diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 67fdfb7..70f14f5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -46,11 +46,6 @@ jobs: with: dotnet-version: 3.1.415 - - name: Setup .NET 5 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 5.0.403 - - name: Setup .NET 6 uses: actions/setup-dotnet@v1 with: @@ -58,7 +53,7 @@ jobs: - name: .NET Core SxS run: | - rsync -a ${DOTNET_ROOT/6.0.100/5.0.403/3.1.415}/* $DOTNET_ROOT/ + rsync -a ${DOTNET_ROOT/6.0.100/3.1.415}/* $DOTNET_ROOT/ # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/dotnetall.yml b/.github/workflows/dotnetall.yml index c513e34..45ba527 100644 --- a/.github/workflows/dotnetall.yml +++ b/.github/workflows/dotnetall.yml @@ -23,11 +23,6 @@ jobs: with: dotnet-version: 3.1.415 - - name: Setup .NET 5 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 5.0.403 - - name: Setup .NET 6 uses: actions/setup-dotnet@v1 with: @@ -35,7 +30,7 @@ jobs: - name: .NET Core SxS run: | - rsync -a ${DOTNET_ROOT/6.0.100/5.0.403/3.1.415}/* $DOTNET_ROOT/ + rsync -a ${DOTNET_ROOT/6.0.100/3.1.415}/* $DOTNET_ROOT/ - name: Restore run: dotnet restore SecretSharingDotNet.sln @@ -46,5 +41,10 @@ jobs: - name: Test run: dotnet test --configuration Release SecretSharingDotNet.sln + - name: Prepare README.md for NuGet package + run: | + grep -n "## Install SecretSharingDotNet package" README.md | cut -d: -f 1| xargs -i tail -n +{} README.md > TMP.md && sed -i '1s/^/# Setup\r\n/' TMP.md && mv -f TMP.md README.md + grep -n "# CLI building instructions" README.md | cut -d: -f 1| xargs -i head -n {} README.md | head -n -1 > TMP.md && mv -f TMP.md README.md + - name: Create Package run: dotnet pack --configuration Release SecretSharingDotNet.sln diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 989c777..0572a01 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -17,7 +17,7 @@ jobs: DOTNET_CLI_TELEMETRY_OPTOUT: true strategy: matrix: - dotnet: [ '3.1.415', '5.0.403', '6.0.100'] + dotnet: [ '3.1.415', '6.0.100'] name: Dotnet ${{ matrix.dotnet }} steps: @@ -32,12 +32,6 @@ jobs: - name: Test with donet SDK v3.1 if: matrix.dotnet == '3.1.415' run: dotnet test -v d --configuration Release SecretSharingDotNetCore3.1.sln - - name: Build with dotnet SDK v5.0 - if: matrix.dotnet == '5.0.403' - run: dotnet build --configuration Release SecretSharingDotNet5.sln - - name: Test with dotnet SDK v5.0 - if: matrix.dotnet == '5.0.403' - run: dotnet test --configuration Release SecretSharingDotNet5.sln - name: Build with dotnet SDK v6.0 if: matrix.dotnet == '6.0.100' run: dotnet build --configuration Release SecretSharingDotNet6.sln diff --git a/.github/workflows/dotnetfx.yml b/.github/workflows/dotnetfx.yml index 4c34836..0bef54e 100644 --- a/.github/workflows/dotnetfx.yml +++ b/.github/workflows/dotnetfx.yml @@ -12,7 +12,7 @@ on: jobs: build: - runs-on: windows-latest + runs-on: windows-2019 steps: - name: checkout diff --git a/.github/workflows/publishing.yml b/.github/workflows/publishing.yml index a27ae16..6a7fac9 100644 --- a/.github/workflows/publishing.yml +++ b/.github/workflows/publishing.yml @@ -21,11 +21,6 @@ jobs: with: dotnet-version: 3.1.415 - - name: Setup .NET 5 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 5.0.403 - - name: Setup .NET 6 uses: actions/setup-dotnet@v1 with: @@ -33,7 +28,7 @@ jobs: - name: .NET Core SxS run: | - rsync -a ${DOTNET_ROOT/6.0.100/5.0.403/3.1.415}/* $DOTNET_ROOT/ + rsync -a ${DOTNET_ROOT/6.0.100/3.1.415}/* $DOTNET_ROOT/ - name: Decrypt large secret run: ./.github/secrets/decrypt_publisher_snk.sh @@ -53,6 +48,11 @@ jobs: - name: Remove obsolete NuGet packages run: rm -f src/bin/Release/SecretSharingDotNet*.nupk + - name: Prepare README.md for NuGet package + run: | + grep -n "## Install SecretSharingDotNet package" README.md | cut -d: -f 1| xargs -i tail -n +{} README.md > TMP.md && sed -i '1s/^/# Setup\r\n/' TMP.md && mv -f TMP.md README.md + grep -n "# CLI building instructions" README.md | cut -d: -f 1| xargs -i head -n {} README.md | head -n -1 > TMP.md && mv -f TMP.md README.md + - name: Create package run: dotnet pack --configuration Release SecretSharingDotNet.sln diff --git a/CHANGELOG.md b/CHANGELOG.md index f3b32b0..c7f0d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.0] - 2022-07-05 +### Added +- Added more examples in the section *Usage* of the `README.md` file to explain the use of shares and the use of the new type casting from byte array to secret and vice versa. +- Added method `MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, int securityLevel)` +- Added method `MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, Secret secret, int securityLevel)` +- Added localization for exception messages in English and German languages + +### Changed +- Changed existing examples in the section *Usage* of the `README.md` file to explain the use and the type casting of recovered secrets. +- Minify NuGet package README.md +- Changed ctor `ShamirsSecretSharing(IExtendedGcdAlgorithm extendedGcd)`. This ctor sets the SecurityLevel to 13. + +### Deprecated +- Ctor `ShamirsSecretSharing(IExtendedGcdAlgorithm extendedGcd, int securityLevel)` is deprecated. +- Method `MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares)` is deprecated. +- Shares to tuple type casting is obsolete and will be remove in the next release. +- Shares.Item1 property is obsolete and will be remove in the next release. +- Shares.Item2 property is obsolete and will be remove in the next release. + +### Removed +- Removed .NET 5 support, because it retires on May 10, 2022. See [Microsoft .NET and .NET Core - Support Dates](https://docs.microsoft.com/en-us/lifecycle/products/microsoft-net-and-net-core). + ## [0.7.0] - 2022-02-09 ### Added - Added implicit casts for byte arrays in *Secret* class. @@ -104,7 +126,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added LICENSE.md - Added README.md -[Unreleased]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.4.2...HEAD +[Unreleased]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.8.0...HEAD +[0.8.0]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.7.0...v0.8.0 +[0.7.0]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.6.0...v0.7.0 +[0.6.0]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.5.0...v0.6.0 +[0.5.0]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.4.2...v0.5.0 [0.4.2]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.4.1...v0.4.2 [0.4.1]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.4.0...v0.4.1 [0.4.0]: https://github.com/shinji-san/SecretSharingDotNet/compare/v0.3.0...v0.4.0 diff --git a/README.md b/README.md index 84f7a6d..bd1dd03 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ An C# implementation of Shamir's Secret Sharing. - Build status - SecretSharingDotNet.sln - Core + Build status + SecretSharingDotNet.sln + Core Core 3.1 (LTS) @@ -39,22 +39,15 @@ An C# implementation of Shamir's Secret Sharing. FX 4.8 - - .NET 5 - .NET 6 - Build status + Build status SecretSharingDotNetCore3.1.sln - Core + Core Core 3.1 (LTS) - - SecretSharingDotNet5.sln - .NET 5 - SecretSharingDotNet6.sln .NET 6 @@ -81,14 +74,11 @@ An C# implementation of Shamir's Secret Sharing. - SecretSharingDotNet NuGet - NuGet Version 0.7.0 - Tag + SecretSharingDotNet NuGet + NuGet Version 0.8.0 + Tag Core 3.1 (LTS) - - .NET 5 - .NET 6 @@ -120,10 +110,10 @@ An C# implementation of Shamir's Secret Sharing. 1. Open a console and switch to the directory, containing your project file. -2. Use the following command to install version 0.7.0 of the SecretSharingDotNet package: +2. Use the following command to install version 0.8.0 of the SecretSharingDotNet package: ```dotnetcli - dotnet add package SecretSharingDotNet -v 0.7.0 -f + dotnet add package SecretSharingDotNet -v 0.8.0 -f ``` 3. After the completition of the command, look at the project file to make sure that the package is successfuly installed. @@ -132,7 +122,7 @@ An C# implementation of Shamir's Secret Sharing. ```xml - + ``` ## Remove SecretSharingDotNet package @@ -243,22 +233,43 @@ namespace Example1 var gcd = new ExtendedEuclideanAlgorithm(); //// Create Shamir's Secret Sharing instance with BigInteger - //// and security level 127 (Mersenne prime exponent) - var split = new ShamirsSecretSharing(gcd, 127); + var split = new ShamirsSecretSharing(gcd); //// Minimum number of shared secrets for reconstruction: 3 //// Maximum number of shared secrets: 7 - var shares = split.MakeShares(3, 7); + //// Security level: 127 (Mersenne prime exponent) + var shares = split.MakeShares(3, 7, 127); //// The property 'shares.OriginalSecret' represents the random secret var secret = shares.OriginalSecret; + //// Secret as big integer number + Console.WriteLine((BigInteger)secret); + + //// Secret as base64 string + Console.WriteLine(secret.ToBase64()); + //// The 'shares' instance contains the shared secrets var combine = new ShamirsSecretSharing(gcd); var subSet1 = shares.Where(p => p.X.IsEven).ToList(); var recoveredSecret1 = combine.Reconstruction(subSet1.ToArray()); var subSet2 = shares.Where(p => !p.X.IsEven).ToList(); var recoveredSecret2 = combine.Reconstruction(subSet2.ToArray()); + + //// String representation of all shares + Console.WriteLine(shares); + + //// 1st recovered secret as big integer number + Console.WriteLine((BigInteger)recoveredSecret1); + + //// 2nd recovered secret as big integer number + Console.WriteLine((BigInteger)recoveredSecret2); + + //// 1st recovered secret as base64 string + Console.WriteLine(recoveredSecret1.ToBase64()); + + //// 2nd recovered secret as base64 string + Console.WriteLine(recoveredSecret2.ToBase64()); } } } @@ -289,7 +300,8 @@ namespace Example2 string password = "Hello World!!"; //// Minimum number of shared secrets for reconstruction: 3 //// Maximum number of shared secrets: 7 - //// Attention: The password length changes the security level set by the ctor + //// Attention: The password length can change the security level set by the ctor + //// or SecurityLevel property. var shares = split.MakeShares(3, 7, password); //// The property 'shares.OriginalSecret' represents the original password @@ -301,6 +313,15 @@ namespace Example2 var recoveredSecret1 = combine.Reconstruction(subSet1.ToArray()); var subSet2 = shares.Where(p => !p.X.IsEven).ToList(); var recoveredSecret2 = combine.Reconstruction(subSet2.ToArray()); + + //// String representation of all shares + Console.WriteLine(shares); + + //// 1st recovered secret as string (not base64!) + Console.WriteLine(recoveredSecret1); + + //// 2nd recovered secret as string (not base64!) + Console.WriteLine(recoveredSecret2); } } } @@ -327,14 +348,16 @@ namespace Example3 var gcd = new ExtendedEuclideanAlgorithm(); //// Create Shamir's Secret Sharing instance with BigInteger - //// and security level 521 (Mersenne prime exponent) - var split = new ShamirsSecretSharing(gcd, 521); + //// and + var split = new ShamirsSecretSharing(gcd); BigInteger number = 20000; //// Minimum number of shared secrets for reconstruction: 3 //// Maximum number of shared secrets: 7 - //// Attention: The number size changes the security level set by the ctor - var shares = split.MakeShares (3, 7, number); + //// Security level: 521 (Mersenne prime exponent) + //// Attention: The size of the number can change the security level set by the ctor + //// or SecurityLevel property. + var shares = split.MakeShares (3, 7, number, 521); //// The property 'shares.OriginalSecret' represents the number (original secret) var secret = shares.OriginalSecret; @@ -345,47 +368,151 @@ namespace Example3 var recoveredSecret1 = combine.Reconstruction(subSet1.ToArray()); var subSet2 = shares.Where(p => !p.X.IsEven).ToList(); var recoveredSecret2 = combine.Reconstruction(subSet2.ToArray()); + + //// String representation of all shares + Console.WriteLine(shares); + + //// 1st recovered secret as big integer number + Console.WriteLine((BigInteger)recoveredSecret1); + + //// 2nd recovered secret as big integer number + Console.WriteLine((BigInteger)recoveredSecret2); + } + } +} +``` +## Pre-defined secret: byte array +Use a byte array as secret, which can be divided into shares. The length of the generated shares is based on the security level. +Here is an example with auto-detected security level: +```csharp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +using SecretSharingDotNet.Cryptography; +using SecretSharingDotNet.Math; + +namespace Example4 +{ + public class Program + { + public static void Main(string[] args) + { + var gcd = new ExtendedEuclideanAlgorithm(); + + //// Create Shamir's Secret Sharing instance with BigInteger + var split = new ShamirsSecretSharing(gcd); + + byte[] bytes = { 0x1D, 0x2E, 0x3F }; + //// Minimum number of shared secrets for reconstruction: 4 + //// Maximum number of shared secrets: 10 + //// Attention: The password length changes the security level set by the ctor + var shares = split.MakeShares(4, 10, bytes); + + //// The 'shares' instance contains the shared secrets + var combine = new ShamirsSecretSharing(gcd); + var subSet = shares.Where(p => p.X.IsEven).ToList(); + var recoveredSecret = combine.Reconstruction(subSet.ToArray()).ToByteArray(); + + //// String representation of all shares + Console.WriteLine(shares); + + //// The secret bytes. + Console.WriteLine($"{recoveredSecret[0]:X2}, {recoveredSecret[1]:X2}, {recoveredSecret[2]:X2}"); } } } ``` + +## Shares +The following example shows three ways to use shares to reconstruct a secret: +```csharp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +using SecretSharingDotNet.Cryptography; +using SecretSharingDotNet.Math; + +namespace Example5 +{ + public class Program + { + public static void Main(string[] args) + { + var gcd = new ExtendedEuclideanAlgorithm(); + + //// One way to use shares + string shares1 = "02-665C74ED38FDFF095B2FC9319A272A75" + Environment.NewLine + + "05-CDECB88126DBC04D753E0C2D83D7B55D" + Environment.NewLine + + "07-54A83E34AB0310A7F5D80F2A68FD4F33"; + + //// A 2nd way to use shares + string[] shares2 = {"02-665C74ED38FDFF095B2FC9319A272A75", + "07-54A83E34AB0310A7F5D80F2A68FD4F33", + "05-CDECB88126DBC04D753E0C2D83D7B55D"}; + + //// Another way to use shares + var fp1 = new FinitePoint("05-CDECB88126DBC04D753E0C2D83D7B55D"); + var fp2 = new FinitePoint("07-54A83E34AB0310A7F5D80F2A68FD4F33"); + var fp3 = new FinitePoint("02-665C74ED38FDFF095B2FC9319A272A75"); + + var combine = new ShamirsSecretSharing(gcd); + + var recoveredSecret1 = combine.Reconstruction(shares1); + //// Output should be 52199147989510990914370102003412153 + Console.WriteLine((BigInteger)recoveredSecret1); + + var recoveredSecret2 = combine.Reconstruction(shares2); + //// Output should be 52199147989510990914370102003412153 + Console.WriteLine((BigInteger)recoveredSecret2); + + //// Output should be 52199147989510990914370102003412153 + var recoveredSecret3 = combine.Reconstruction(fp1, fp2, fp3); + Console.WriteLine((BigInteger)recoveredSecret3); + } + } +} +``` + # CLI building instructions For the following instructions, please make sure that you are connected to the internet. If necessary, NuGet will try to restore the [xUnit](https://xunit.net/) packages. -## Using dotnet to build for .NET6, .NET 5, .NET Core and .NET FX 4.x +## Using dotnet to build for .NET6, .NET Core and .NET FX 4.x Use one of the following solutions with `dotnet` to build [SecretSharingDotNet](#secretsharingdotnet): * `SecretSharingDotNet.sln` (all, [see table](#build--test-status-of-default-branch)) -* `SecretSharingDotNet5.sln` (.NET 5 only) * `SecretSharingDotNet6.sln` (.NET 6 only) * `SecretSharingDotNetCore3.1.sln` (.NET Core 3.1 only) The syntax is: ```dotnetcli -dotnet {build|test} -c {Debug|Release} SecretSharingDotNet{6|5|Core3.1}.sln +dotnet {build|test} -c {Debug|Release} SecretSharingDotNet{6|Core3.1}.sln ``` -The instructions below are examples, which operate on the `SecretSharingDotNet5.sln`. +The instructions below are examples, which operate on the `SecretSharingDotNet6.sln`. ### Build Debug configuration ```dotnetcli -dotnet build -c Debug SecretSharingDotNet5.sln +dotnet build -c Debug SecretSharingDotNet6.sln ``` ### Build Release configuration ```dotnetcli -dotnet build -c Release SecretSharingDotNet5.sln +dotnet build -c Release SecretSharingDotNet6.sln ``` ### Test Debug configuration ```dotnetcli -dotnet test -c Debug SecretSharingDotNet5.sln +dotnet test -c Debug SecretSharingDotNet6.sln ``` ### Test Release configuration ```dotnetcli -dotnet test -c Release SecretSharingDotNet5.sln +dotnet test -c Release SecretSharingDotNet6.sln ``` ## Using MSBuild to build for .NET FX 4.6.2 diff --git a/SecretSharingDotNet5.sln b/SecretSharingDotNet5.sln deleted file mode 100644 index 7fa3c3b..0000000 --- a/SecretSharingDotNet5.sln +++ /dev/null @@ -1,48 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 -MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecretSharingDotNet", "src\SecretSharingDotNet5.csproj", "{EF113114-267C-4CA0-B22A-62A326FF73B2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecretSharingDotNetTest", "tests\SecretSharingDotNet5Test.csproj", "{1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Debug|x64.ActiveCfg = Debug|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Debug|x64.Build.0 = Debug|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Debug|x86.ActiveCfg = Debug|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Debug|x86.Build.0 = Debug|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Release|Any CPU.Build.0 = Release|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Release|x64.ActiveCfg = Release|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Release|x64.Build.0 = Release|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Release|x86.ActiveCfg = Release|Any CPU - {EF113114-267C-4CA0-B22A-62A326FF73B2}.Release|x86.Build.0 = Release|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Debug|x64.ActiveCfg = Debug|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Debug|x64.Build.0 = Debug|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Debug|x86.ActiveCfg = Debug|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Debug|x86.Build.0 = Debug|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Release|Any CPU.Build.0 = Release|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Release|x64.ActiveCfg = Release|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Release|x64.Build.0 = Release|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Release|x86.ActiveCfg = Release|Any CPU - {1754AFBB-73DF-4AEB-9CBC-5C46B3708D8F}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/src/Cryptography/Secret.cs b/src/Cryptography/Secret.cs index abe7447..4d01829 100644 --- a/src/Cryptography/Secret.cs +++ b/src/Cryptography/Secret.cs @@ -155,7 +155,7 @@ public Secret(byte[] secretSource) if (secretSource.Length == 0) { - throw new ArgumentException("Value cannot be an empty collection.", nameof(secretSource)); + throw new ArgumentException(ErrorMessages.EmptyCollection, nameof(secretSource)); } var buffer = new byte[1]; diff --git a/src/Cryptography/ShamirsSecretSharing.cs b/src/Cryptography/ShamirsSecretSharing.cs index 99db97b..eeb530c 100644 --- a/src/Cryptography/ShamirsSecretSharing.cs +++ b/src/Cryptography/ShamirsSecretSharing.cs @@ -56,9 +56,9 @@ public class ShamirsSecretSharing }); /// - /// Saves the security level + /// Saves the fixed security level /// - private int securityLevel; + private int fixedSecurityLevel; /// /// Saves the calculated mersenne prime @@ -74,9 +74,11 @@ public class ShamirsSecretSharing /// Initializes a new instance of the class. /// /// Extended greatest common divisor algorithm + /// The parameter is . public ShamirsSecretSharing(IExtendedGcdAlgorithm extendedGcd) { this.extendedGcd = extendedGcd ?? throw new ArgumentNullException(nameof(extendedGcd)); + this.SecurityLevel = 13; } /// @@ -85,6 +87,7 @@ public ShamirsSecretSharing(IExtendedGcdAlgorithm extendedGcd) /// Extended greatest common divisor algorithm /// Security level (in number of bits). Minimum is 5 for legacy mode and 13 for normal mode. /// The security level is lower than 5 or greater than 43112609. + [Obsolete("Will be removed in future versions. Please use one of the overloads of the method MakeShares.", false)] public ShamirsSecretSharing(IExtendedGcdAlgorithm extendedGcd, int securityLevel) { this.extendedGcd = extendedGcd ?? throw new ArgumentNullException(nameof(extendedGcd)); @@ -101,16 +104,17 @@ public ShamirsSecretSharing(IExtendedGcdAlgorithm extendedGcd, int secu /// /// Gets or sets the security level /// + /// Value is lower than 5 or greater than 43112609. /// Value is lower than 5 or greater than 43112609. public int SecurityLevel { - get => this.securityLevel; + get => this.fixedSecurityLevel; set { if (value < 5) { - throw new ArgumentOutOfRangeException(nameof(value), value, "Minimum exceeded!"); + throw new ArgumentOutOfRangeException(nameof(value), value, ErrorMessages.MinimumSecurityLevelExceeded); } if (!Secret.LegacyMode.Value && value < 13) @@ -127,12 +131,12 @@ public int SecurityLevel } catch (ArgumentOutOfRangeException) { - throw new ArgumentOutOfRangeException(nameof(value), value, "Maximum exceeded!"); + throw new ArgumentOutOfRangeException(nameof(value), value, ErrorMessages.MaximumSecurityLevelExceeded); } } this.mersennePrime = Calculator.Two.Pow(value) - Calculator.One; - this.securityLevel = value; + this.fixedSecurityLevel = value; } } @@ -141,21 +145,46 @@ public int SecurityLevel /// /// Minimum number of shared secrets for reconstruction /// Maximum number of shared secrets + /// Security level (in number of bits). Minimum is 5 for legacy mode and 13 for normal mode. /// - /// is lower than 2 or greater than . + /// The parameter is lower than 5 or greater than 43112609. OR The parameter is lower than 2 or greater than . + public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, int securityLevel) + { + Calculator min = numberOfMinimumShares; + Calculator max = numberOfShares; + try + { + this.SecurityLevel = securityLevel; + } + catch (ArgumentOutOfRangeException e) + { + throw new ArgumentOutOfRangeException(nameof(securityLevel), securityLevel, e.Message); + } + + return this.MakeShares(numberOfMinimumShares, numberOfShares); + } + + /// + /// Generates a random shamir pool, returns the random secret and the share points. + /// + /// Minimum number of shared secrets for reconstruction + /// Maximum number of shared secrets + /// + /// The parameter is lower than 2 or greater than . /// Security Level is not initialized! + [Obsolete("Will be removed in future versions. Please use the method MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, int securityLevel).", false)] public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares) { Calculator min = numberOfMinimumShares; Calculator max = numberOfShares; if (min < Calculator.Two) { - throw new ArgumentOutOfRangeException(nameof(numberOfMinimumShares)); + throw new ArgumentOutOfRangeException(nameof(numberOfMinimumShares), numberOfMinimumShares, ErrorMessages.MinNumberOfSharesLowerThanTwo); } if (min > max) { - throw new ArgumentOutOfRangeException(nameof(numberOfShares), "The pool secret would be irrecoverable."); + throw new ArgumentOutOfRangeException(nameof(numberOfShares), numberOfShares, ErrorMessages.MaxSharesLowerThanMinShares); } if (this.mersennePrime == null) @@ -170,6 +199,31 @@ public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberO return new Shares(secret, points); } + /// + /// Generates a random shamir pool, returns the specified and the share points. + /// + /// Minimum number of shared secrets for reconstruction + /// Maximum number of shared secrets + /// secret text as or see cref="string"/> + /// Security level (in number of bits). Minimum is 5 for legacy mode and 13 for normal mode. + /// + /// This method can modify the based on the length. + /// The parameter is . + /// The is lower than 5 or greater than 43112609. OR is lower than 2 or greater than . + public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, Secret secret, int securityLevel) + { + try + { + this.SecurityLevel = securityLevel; + } + catch (ArgumentOutOfRangeException e) + { + throw new ArgumentOutOfRangeException(nameof(securityLevel), securityLevel, e.Message); + } + + return this.MakeShares(numberOfMinimumShares, numberOfShares, secret); + } + /// /// Generates a random shamir pool, returns the specified and the share points. /// @@ -178,7 +232,7 @@ public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberO /// secret text as or see cref="string"/> /// /// This method modifies the based on the length - /// is + /// is . /// is lower than 2 or greater than . public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, Secret secret) { @@ -191,12 +245,12 @@ public Shares MakeShares(TNumber numberOfMinimumShares, TNumber numberO Calculator max = numberOfShares; if (min < Calculator.Two) { - throw new ArgumentOutOfRangeException(nameof(numberOfMinimumShares)); + throw new ArgumentOutOfRangeException(nameof(numberOfMinimumShares), numberOfMinimumShares, ErrorMessages.MinNumberOfSharesLowerThanTwo); } if (min > max) { - throw new ArgumentOutOfRangeException(nameof(numberOfShares), "The pool secret would be irrecoverable."); + throw new ArgumentOutOfRangeException(nameof(numberOfShares), numberOfShares, ErrorMessages.MaxSharesLowerThanMinShares); } int newSecurityLevel = secret.SecretByteSize * 8; @@ -292,7 +346,7 @@ private Secret LagrangeInterpolate(List> finitePoi { if (finitePoints.Distinct().Count() != finitePoints.Count) { - throw new ArgumentException("Finite points (aka shares) are not distinct!", nameof(finitePoints)); + throw new ArgumentException(ErrorMessages.FinitePointsNotDistinct, nameof(finitePoints)); } int k = finitePoints.Count; @@ -369,7 +423,7 @@ public Secret Reconstruction(string[] shares) if (shares.Length < 2) { - throw new ArgumentOutOfRangeException(nameof(shares)); + throw new ArgumentOutOfRangeException(nameof(shares), ErrorMessages.MinNumberOfSharesLowerThanTwo); } Shares castShares = shares; @@ -402,7 +456,7 @@ public Secret Reconstruction(params FinitePoint[] shares) if (shares.Length < 2) { - throw new ArgumentOutOfRangeException(nameof(shares)); + throw new ArgumentOutOfRangeException(nameof(shares), ErrorMessages.MinNumberOfSharesLowerThanTwo); } var maximumY = shares.Select(point => point.Y).Max(); diff --git a/src/Cryptography/Shares.cs b/src/Cryptography/Shares.cs index 91275e6..119646d 100644 --- a/src/Cryptography/Shares.cs +++ b/src/Cryptography/Shares.cs @@ -90,7 +90,7 @@ internal Shares(Secret secret, IList> shares) /// Gets the original secret /// /// Legacy property - [Obsolete("Legacy property. Will be removed in futures versions.", false)] + [Obsolete("Legacy property. Will be removed in futures versions. Pleas use OriginalSecret property.", true)] public Secret Item1 => this.OriginalSecret; /// @@ -105,7 +105,7 @@ internal Shares(Secret secret, IList> shares) /// Gets the shares. /// /// Legacy property - [Obsolete("Legacy property. Will be removed in futures versions.", false)] + [Obsolete("Legacy property. Will be removed in futures versions.", true)] public ICollection> Item2 => this.shareList; /// @@ -118,6 +118,7 @@ internal Shares(Secret secret, IList> shares) /// /// A object. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")] + [Obsolete("Legacy property. Will be removed in futures versions.", true)] public static implicit operator Tuple, ICollection>>(Shares shares) => new Tuple, ICollection>>(shares?.OriginalSecret, shares); /// @@ -225,7 +226,7 @@ public void Clear() { if (this.IsReadOnly) { - throw new NotSupportedException($"The {nameof(Shares)} collection is read-only."); + throw new NotSupportedException(string.Format(ErrorMessages.ReadOnlyCollection, nameof(Shares))); } this.shareList.Clear(); @@ -242,7 +243,7 @@ public void Add(FinitePoint item) { if (this.IsReadOnly) { - throw new NotSupportedException($"The {nameof(Shares)} collection is read-only."); + throw new NotSupportedException(string.Format(ErrorMessages.ReadOnlyCollection, nameof(Shares))); } if (!this.Contains(item)) @@ -263,7 +264,7 @@ public bool Remove(FinitePoint item) { if (this.IsReadOnly) { - throw new NotSupportedException($"The {nameof(Shares)} collection is read-only."); + throw new NotSupportedException(string.Format(ErrorMessages.ReadOnlyCollection, nameof(Shares))); } return this.shareList.Remove(item); @@ -284,7 +285,7 @@ void ICollection.CopyTo(Array array, int arrayIndex) this.CopyTo(x, arrayIndex); break; default: - throw new InvalidCastException($"Parameter {nameof(array)}: Cannot convert an array from type {array.GetType().GetElementType()} to an array of type {typeof(FinitePoint)}."); + throw new InvalidCastException(string.Format(ErrorMessages.InvalidArrayTypeCast, nameof(array), array.GetType().GetElementType(), typeof(FinitePoint))); } } @@ -301,12 +302,12 @@ public void CopyTo(FinitePoint[] array, int arrayIndex) _ = array ?? throw new ArgumentNullException(nameof(array)); if (arrayIndex < 0) { - throw new ArgumentOutOfRangeException(nameof(arrayIndex), "The starting array index cannot be negative."); + throw new ArgumentOutOfRangeException(nameof(arrayIndex), ErrorMessages.StartArrayIndexNegative); } if (Count > array.Length - arrayIndex + 1) { - throw new ArgumentException("The destination array has fewer elements than the collection.", nameof(array)); + throw new ArgumentException(ErrorMessages.DestinationArrayHasFewerElements, nameof(array)); } for (int i = 0; i < this.shareList.Count; i++) diff --git a/src/Helper/Extensions.cs b/src/Helper/Extensions.cs index 1ea7c73..ca3cb21 100644 --- a/src/Helper/Extensions.cs +++ b/src/Helper/Extensions.cs @@ -67,17 +67,17 @@ public static TArray[] Subset(this TArray[] array, int index, int count) if (array.Length == 0) { - throw new ArgumentException("Value cannot be an empty collection.", nameof(array)); + throw new ArgumentException(ErrorMessages.EmptyCollection, nameof(array)); } if (index < 0) { - throw new ArgumentOutOfRangeException(nameof(index), index, "Value cannot be lower than 0."); + throw new ArgumentOutOfRangeException(nameof(index), index, string.Format(ErrorMessages.ValueLowerThanX, 0)); } if (count < 1) { - throw new ArgumentOutOfRangeException(nameof(count), count, "Value cannot be lower than 1."); + throw new ArgumentOutOfRangeException(nameof(count), count, string.Format(ErrorMessages.ValueLowerThanX, 1)); } var subset = new TArray[count]; diff --git a/src/Math/Calculator.cs b/src/Math/Calculator.cs index a57bd87..407e89b 100644 --- a/src/Math/Calculator.cs +++ b/src/Math/Calculator.cs @@ -358,7 +358,7 @@ public static implicit operator Calculator(TNumber number) } catch (KeyNotFoundException) { - throw new NotSupportedException($"Generic Data Type '{typeof(TNumber).Name}' not supported!"); + throw new NotSupportedException(string.Format(ErrorMessages.DataTypeNotSupported, typeof(TNumber).Name)); } } diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index 01fb070..50bc500 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -15,8 +15,8 @@ [assembly: Guid("1c21b99c-2de4-4ca5-b4ce-bc95cf89369e")] -[assembly: AssemblyVersion("0.7.0")] -[assembly: AssemblyFileVersion("0.7.0")] +[assembly: AssemblyVersion("0.8.0")] +[assembly: AssemblyFileVersion("0.8.0")] [assembly: NeutralResourcesLanguage("en")] [assembly: System.CLSCompliant(true)] diff --git a/src/Resources/ErrorMessages.Designer.cs b/src/Resources/ErrorMessages.Designer.cs new file mode 100644 index 0000000..d335bdc --- /dev/null +++ b/src/Resources/ErrorMessages.Designer.cs @@ -0,0 +1,123 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SecretSharingDotNet { + using System; + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class ErrorMessages { + + private static System.Resources.ResourceManager resourceMan; + + private static System.Globalization.CultureInfo resourceCulture; + + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal ErrorMessages() { + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { + get { + if (object.Equals(null, resourceMan)) + { + var assemblyType = typeof(ErrorMessages); + var assembly = assemblyType.Assembly; + System.Resources.ResourceManager temp = new System.Resources.ResourceManager(assemblyType.Namespace + ".Resources.ErrorMessages", assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static string MinimumSecurityLevelExceeded { + get { + return ResourceManager.GetString("MinimumSecurityLevelExceeded", resourceCulture); + } + } + + internal static string MaximumSecurityLevelExceeded { + get { + return ResourceManager.GetString("MaximumSecurityLevelExceeded", resourceCulture); + } + } + + internal static string MinNumberOfSharesLowerThanTwo { + get { + return ResourceManager.GetString("MinNumberOfSharesLowerThanTwo", resourceCulture); + } + } + + internal static string FinitePointsNotDistinct { + get { + return ResourceManager.GetString("FinitePointsNotDistinct", resourceCulture); + } + } + + internal static string MaxSharesLowerThanMinShares { + get { + return ResourceManager.GetString("MaxSharesLowerThanMinShares", resourceCulture); + } + } + + internal static string ReadOnlyCollection { + get { + return ResourceManager.GetString("ReadOnlyCollection", resourceCulture); + } + } + + internal static string StartArrayIndexNegative { + get { + return ResourceManager.GetString("StartArrayIndexNegative", resourceCulture); + } + } + + internal static string DestinationArrayHasFewerElements { + get { + return ResourceManager.GetString("DestinationArrayHasFewerElements", resourceCulture); + } + } + + internal static string InvalidArrayTypeCast { + get { + return ResourceManager.GetString("InvalidArrayTypeCast", resourceCulture); + } + } + + internal static string EmptyCollection { + get { + return ResourceManager.GetString("EmptyCollection", resourceCulture); + } + } + + internal static string ValueLowerThanX { + get { + return ResourceManager.GetString("ValueLowerThanX", resourceCulture); + } + } + + internal static string DataTypeNotSupported { + get { + return ResourceManager.GetString("DataTypeNotSupported", resourceCulture); + } + } + } +} diff --git a/src/Resources/ErrorMessages.de-de.resx b/src/Resources/ErrorMessages.de-de.resx new file mode 100644 index 0000000..f402a93 --- /dev/null +++ b/src/Resources/ErrorMessages.de-de.resx @@ -0,0 +1,50 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Der minimale Sicherheitslevel wurde unterschritten! + + + Der maximale Sicherheitslevel wurde überschritten! + + + Die minimale Anzahl an Teilgeheimnissen ist kleiner als 2! Bitte setze die minimale Anzahl an Teilgeheimnissen auf 2 oder höher. + + + Die finiten Punkte (auch als Teilgeheimnis bekannt) sind nicht eindeutig! + + + Das Pool-Geheimnis wäre mit diesen Parametern unwiederbringlich, da die maximale Anzahl an Teilgeheimnissen kleiner ist als die minimale Anzahl an Teilgeheimnissen. + + + Die {0}-Sammlung ist schreibgeschützt. + + + Der Start-Array-Index darf nicht negativ sein. + + + Das Zielarray hat weniger Elemente als die Sammlung. + + + Parameter {0}: Ein Array vom Typ {1} kann nicht in ein Array vom Typ {2} konvertiert werden. + + + Der Wert darf keine leere Sammlung sein. + + + Der Wert darf nicht kleiner als {0} sein. + + + Der Datentyp '{0}' wird nicht unterstützt! + + \ No newline at end of file diff --git a/src/Resources/ErrorMessages.resx b/src/Resources/ErrorMessages.resx new file mode 100644 index 0000000..074292c --- /dev/null +++ b/src/Resources/ErrorMessages.resx @@ -0,0 +1,57 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Minimum security level not achieved! + + + Maximum security level exceeded! + + + The minimum number of shares is lower than 2! Please set the minimum number of shares to 2 or higher. + + + Finite points (aka shares) are not distinct! + + + The pool secret would be irrecoverable, if you use these parameters, because the maximum number of shares is lower than the minimum number of shares. + + + The {0} collection is read-only. + + + The starting array index cannot be negative. + + + The destination array has fewer elements than the collection. + + + Parameter {0}: Cannot convert an array of type {1} to an array of type {2}. + + + Value cannot be an empty collection. + + + Value cannot be lower than {0}. + + + Data Type '{0}' not supported! + + \ No newline at end of file diff --git a/src/SecretSharingDotNet.csproj b/src/SecretSharingDotNet.csproj index dbf0552..38f183f 100644 --- a/src/SecretSharingDotNet.csproj +++ b/src/SecretSharingDotNet.csproj @@ -2,26 +2,42 @@ SecretSharingDotNet + SecretSharingDotNet Library - netcoreapp3.1;netstandard2.0;netstandard2.1;net462;net47;net471;net472;net48;net5.0;net6.0 + netcoreapp3.1;netstandard2.0;netstandard2.1;net462;net47;net471;net472;net48;net6.0 SecretSharingDotNet.snk True false SecretSharingDotNet MIT - Fixed reopened bug #60 "Reconstruction fails at random". Added implicit casts for byte arrays in Secret class. Added legacy mode. Changed calculation of maximum security level in Reconstruction method. Remove support for .NET FX 4.5.2, 4.6 and 4.6.2. + Removed .NET 5 support. Added localization for exception messages in English and German. Add new overloads for the MakeShares method. Mark some ctors, properties and methods as deprecated. An C# implementation of Shamir's Secret Sharing README.md secret sharing;shamir secret sharing;cryptography https://github.com/shinji-san/SecretSharingDotNet https://github.com/shinji-san/SecretSharingDotNet git - 0.7.0 + 0.8.0 Sebastian Walther Private Person true + + + ResXFileCodeGenerator + ErrorMessages.Designer.cs + + + + + + True + True + ErrorMessages.resx + + + diff --git a/src/SecretSharingDotNet5.csproj b/src/SecretSharingDotNet5.csproj deleted file mode 100644 index 089bb64..0000000 --- a/src/SecretSharingDotNet5.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - SecretSharingDotNetCore - Library - net5.0 - SecretSharingDotNet.snk - True - false - true - - - diff --git a/src/SecretSharingDotNet6.csproj b/src/SecretSharingDotNet6.csproj index 090aac0..71dccaa 100644 --- a/src/SecretSharingDotNet6.csproj +++ b/src/SecretSharingDotNet6.csproj @@ -2,6 +2,7 @@ SecretSharingDotNetCore + SecretSharingDotNet Library net6.0 SecretSharingDotNet.snk @@ -10,4 +11,19 @@ true + + + ResXFileCodeGenerator + ErrorMessages.Designer.cs + + + + + + True + True + ErrorMessages.resx + + + diff --git a/src/SecretSharingDotNetCore3.1.csproj b/src/SecretSharingDotNetCore3.1.csproj index c1f7a3c..727dc7c 100644 --- a/src/SecretSharingDotNetCore3.1.csproj +++ b/src/SecretSharingDotNetCore3.1.csproj @@ -2,6 +2,7 @@ SecretSharingDotNetCore + SecretSharingDotNet Library netcoreapp3.1 SecretSharingDotNet.snk @@ -10,4 +11,19 @@ true + + + ResXFileCodeGenerator + ErrorMessages.Designer.cs + + + + + + True + True + ErrorMessages.resx + + + diff --git a/src/SecretSharingDotNetFx4.6.2.csproj b/src/SecretSharingDotNetFx4.6.2.csproj index f585bd9..db99aee 100644 --- a/src/SecretSharingDotNetFx4.6.2.csproj +++ b/src/SecretSharingDotNetFx4.6.2.csproj @@ -56,10 +56,22 @@ + + True + True + ErrorMessages.resx + - + + + + + + ErrorMessages.Designer.cs + + \ No newline at end of file diff --git a/tests/FinitePointTest.cs b/tests/FinitePointTest.cs index f0ea472..b18ed8a 100644 --- a/tests/FinitePointTest.cs +++ b/tests/FinitePointTest.cs @@ -46,8 +46,8 @@ public class FinitePointTest [Fact] public void FinitePointToString() { - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), 500); - FinitePoint fp = split.MakeShares(3, 7).First(); + var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + FinitePoint fp = split.MakeShares(3, 7, 500).First(); string s1 = fp.ToString(); string s2 = new FinitePoint(s1).ToString(); Assert.Equal(s1, s2); diff --git a/tests/SecretSharingDotNet5Test.csproj b/tests/SecretSharingDotNet5Test.csproj deleted file mode 100644 index f5dc337..0000000 --- a/tests/SecretSharingDotNet5Test.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net5.0 - ..\src\SecretSharingDotNet.snk - True - false - false - SecretSharingDotNetTest - - - - - - - - - - - - - diff --git a/tests/SecretSharingDotNetTest.csproj b/tests/SecretSharingDotNetTest.csproj index 18a9208..7a3e30b 100644 --- a/tests/SecretSharingDotNetTest.csproj +++ b/tests/SecretSharingDotNetTest.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1;net5.0;net6.0;net462;net47;net471;net472;net48 + netcoreapp3.1;net6.0;net462;net47;net471;net472;net48 ..\src\SecretSharingDotNet.snk True false diff --git a/tests/ShamirsSecretSharingTest.cs b/tests/ShamirsSecretSharingTest.cs index 56698f1..ab69528 100644 --- a/tests/ShamirsSecretSharingTest.cs +++ b/tests/ShamirsSecretSharingTest.cs @@ -66,27 +66,6 @@ Calculator DivMod(Calculator denominator, Calculator - /// Tests the legacy usage of shares - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - [Fact] - public void LegacyShareUsage() - { - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); - var combine = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); - var shares = split.MakeShares(3, 7, TestData.DefaultTestPassword); - var secret = shares.Item1; - var subSet1 = shares.Item2.Where(p => p.X.IsEven).ToList(); - var recoveredSecret1 = combine.Reconstruction(subSet1.ToArray()); - var subSet2 = shares.Item2.Where(p => !p.X.IsEven).ToList(); - var recoveredSecret2 = combine.Reconstruction(subSet2.ToArray()); - Assert.Equal(TestData.DefaultTestPassword, recoveredSecret1); - Assert.Equal(secret, recoveredSecret1); - Assert.Equal(secret, recoveredSecret2); - Assert.Equal(521, split.SecurityLevel); - } - /// /// Tests the security level auto-detection of . /// @@ -145,10 +124,9 @@ public void TestSecurityLevelAutoDetection(object secret, int expectedSecurityLe [MemberData(nameof(TestData.TestPasswordData), MemberType = typeof(TestData))] public void TestWithPassword(int splitSecurityLevel, int expectedSecurityLevel, string password) { - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), - splitSecurityLevel); + var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); var combine = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); - var shares = split.MakeShares(3, 7, password); + var shares = split.MakeShares(3, 7, password, splitSecurityLevel); Assert.True(shares.OriginalSecretExists); Assert.NotNull(shares.OriginalSecret); var secret = shares.OriginalSecret; @@ -173,10 +151,9 @@ public void TestWithPassword(int splitSecurityLevel, int expectedSecurityLevel, [MemberData(nameof(TestData.TestNumberData), MemberType = typeof(TestData))] public void TestWithNumber(int splitSecurityLevel, int expectedSecurityLevel, BigInteger number) { - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), - splitSecurityLevel); + var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); var combine = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); - var shares = split.MakeShares(3, 7, number); + var shares = split.MakeShares(3, 7, number, splitSecurityLevel); Assert.True(shares.OriginalSecretExists); Assert.NotNull(shares.OriginalSecret); var secret = shares.OriginalSecret; @@ -194,19 +171,15 @@ public void TestWithNumber(int splitSecurityLevel, int expectedSecurityLevel, Bi /// Tests with random value as secret. /// /// Initial security level for secret split phase - /// Initial security level for secret combine phase (aka reconstruction phase) /// Expected security level after secret reconstruction [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] [Theory] [MemberData(nameof(TestData.TestRandomSecretData), MemberType = typeof(TestData))] - public void TestWithRandomSecret(int splitSecurityLevel, int combineSecurityLevel, int expectedSecurityLevel) + public void TestWithRandomSecret(int splitSecurityLevel, int expectedSecurityLevel) { - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), - splitSecurityLevel); - var combine = - new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), - combineSecurityLevel); - var shares = split.MakeShares(3, 7); + var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + var combine = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + var shares = split.MakeShares(3, 7, splitSecurityLevel); Assert.True(shares.OriginalSecretExists); Assert.NotNull(shares.OriginalSecret); var secret = shares.OriginalSecret; @@ -227,8 +200,8 @@ public void TestWithRandomSecret(int splitSecurityLevel, int combineSecurityLeve [Fact] public void TestMinimumSharedSecretsMake() { - var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), 5); - Assert.Throws(() => sss.MakeShares(1, 7)); + var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + Assert.Throws(() => sss.MakeShares(1, 7, 5)); } /// @@ -238,8 +211,8 @@ public void TestMinimumSharedSecretsMake() [Fact] public void TestMinimumSharedSecretsReconstruction() { - var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), 13); - var shares = sss.MakeShares(2, 7); + var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + var shares = sss.MakeShares(2, 7, 13); var subSet = shares.Where(p => p.X == Calculator.One).ToList(); Assert.Throws(() => sss.Reconstruction(subSet.ToArray())); } @@ -251,25 +224,13 @@ public void TestMinimumSharedSecretsReconstruction() [Fact] public void TestShareThreshold() { - var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), 51); - var shares = sss.MakeShares(3, 7); + var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + var shares = sss.MakeShares(3, 7, 51); var subSet = shares.Take(2).ToList(); var secret = sss.Reconstruction(subSet.ToArray()); Assert.NotEqual(shares.OriginalSecret, secret); } - /// - /// Tests whether or not the is thrown if the security level - /// is not initialized. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - [Fact] - public void TestUninitializedSecurityLevel() - { - var sss = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); - Assert.Throws(() => sss.MakeShares(2, 7)); - } - /// /// Tests whether or not bug #40 occurs [Maximum exceeded! (Parameter 'value') Actual value was 10912." #40]. /// @@ -279,9 +240,9 @@ public void MaximumExceeded() { const string longSecret = "-----BEGIN EC PRIVATE KEY-----MIIBUQIBAQQgxq7AWG9L6uleuTB9q5FGqnHjXF+kD4y9154SLYYKMDqggeMwgeACAQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wvMEQEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwRBBHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAaFEA0IABE0XO6I8lZYzXqRQnHP/knSwLex7q77g4J2AN0cVyrADicGlUr6QjVIlIu9NXCHxD2i++ToWjO1zLVdxgNJbUUc=-----END EC PRIVATE KEY-----"; - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), 1024); - var combine = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm(), 5); - var shares = split.MakeShares(3, 7, longSecret); + var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + var combine = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); + var shares = split.MakeShares(3, 7, longSecret, 1024); var subSet1 = shares.Where(p => p.X.IsEven).ToList(); var recoveredSecret1 = combine.Reconstruction(subSet1.ToArray()); var subSet2 = shares.Where(p => !p.X.IsEven).ToList(); diff --git a/tests/SharesTest.cs b/tests/SharesTest.cs index 0bc5cb3..0e828f2 100644 --- a/tests/SharesTest.cs +++ b/tests/SharesTest.cs @@ -45,23 +45,6 @@ namespace SecretSharingDotNet.Test /// public class SharesTest { - /// - /// Tests the implicit cast from to . - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - [Fact] - public void TestSharesToTupleCast() - { - var split = new ShamirsSecretSharing(new ExtendedEuclideanAlgorithm()); - var shares = split.MakeShares(3, 6, TestData.DefaultTestPassword); - Tuple, ICollection>> tuple = shares; - Assert.NotNull(tuple); - Assert.NotNull(tuple.Item1); - Assert.NotNull(tuple.Item2); - Assert.Equal(6, tuple.Item2.Count); - Assert.Equal(TestData.DefaultTestPassword, tuple.Item1); - } - /// /// Tests the cast from array to and vice versa. /// diff --git a/tests/TestData.cs b/tests/TestData.cs index a6c6ac7..f923359 100644 --- a/tests/TestData.cs +++ b/tests/TestData.cs @@ -100,16 +100,16 @@ public static class TestData public static IEnumerable TestRandomSecretData => new List { - new object[] {5, 32, 13}, - new object[] {7, 32, 13}, - new object[] {13, 32, 13}, - new object[] {17, 521, 17}, - new object[] {127, 521, 127}, - new object[] {130, 5, 521}, - new object[] {500, 5, 521}, - new object[] {521, 5, 521}, - new object[] {1024, 5, 1279}, - new object[] {1279, 5, 1279} + new object[] {5, 13}, + new object[] {7, 13}, + new object[] {13, 13}, + new object[] {17, 17}, + new object[] {127, 127}, + new object[] {130, 521}, + new object[] {500, 521}, + new object[] {521, 521}, + new object[] {1024, 1279}, + new object[] {1279, 1279} }; ///