Skip to content

Commit

Permalink
IMakeSharesUseCase & IReconstructionUseCase: Initial import
Browse files Browse the repository at this point in the history
Resolves: No entry
  • Loading branch information
shinji-san committed Aug 25, 2024
1 parent 8e376d1 commit 39a34bb
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 60 deletions.
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,45 @@ An C# implementation of Shamir's Secret Sharing.
Use the function `MakeShares` to generate the shares, based on a random or pre-defined secret.
Afterwards, use the function `Reconstruction` to re-construct the original secret.
The length of the shares is based on the security level. It's possible to pre-define a security level by `ctor` or the `SecurityLevel` property. The pre-defined security level will be overriden, if the secret size is greater than the Mersenne prime, which is calculated by means of the security level. It is not necessary to define a security level for a re-construction.
The length of the shares is based on the security level. It is possible to pre-define a security level by `ctor` or the `SecurityLevel` property. The pre-defined security level will be overriden, if the secret size is greater than the Mersenne prime, which is calculated by means of the security level. It is not necessary to define a security level for a re-construction.
## Using the SecretSharingDotNet library with DI in a .NET project.
This guide will demonstrate how to use the SecretSharingDotNet library with Dependency Injection (DI) in a .NET project.
Firstly, add the following dependencies:
```csharp
using Microsoft.Extensions.DependencyInjection;
using SecretSharingDotNet.Cryptography;
using SecretSharingDotNet.Math;
using System.Numerics;
```
Next, initialize a `ServiceCollection` instance and add dependencies to the DI container:
```csharp
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<IExtendedGcdAlgorithm<BigInteger>, ExtendedEuclideanAlgorithm<BigInteger>>();
serviceCollection.AddSingleton<IMakeSharesUseCase<BigInteger>, ShamirsSecretSharing<BigInteger>>();
serviceCollection.AddSingleton<IReconstructionUseCase<BigInteger>, ShamirsSecretSharing<BigInteger>>();
using var serviceProvider = serviceCollection.BuildServiceProvider();
```
In the code above, the `ServiceCollection` registers an implementation for each of the main components of the SecretSharingDotNet library.

Next, create an instance of the `IMakeSharesUseCase<BigInteger>`:
```csharp
var makeSharesUseCase = serviceProvider.GetRequiredService<IMakeSharesUseCase<BigInteger>>();
```
Using this instance, it is possible to create shares from a secret:
```csharp
var shares = makeSharesUseCase.MakeShares(3, 7, "Hello!");
Console.WriteLine(shares);
```
Similarly, an instance of `IReconstructionUseCase<BigInteger>` can be created to rebuild the original secret:
```csharp
var reconstructionUseCase = serviceProvider.GetRequiredService<IReconstructionUseCase<BigInteger>>();
var reconstruction = reconstructionUseCase.Reconstruction(finitePoints.Where(p => p.X.IsEven).ToArray());
Console.WriteLine(reconstruction);
```

The code above reconstructs the original secret from the shares, and then outputs it.

## Random secret
Create a random secret in conjunction with the generation of shares. The length of the generated shares and of the secret are based on the security level. Here is an example with a pre-defined security level of 127:
Expand Down
31 changes: 15 additions & 16 deletions src/Cryptography/FinitePoint`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,39 +154,39 @@ public FinitePoint(Calculator<TNumber> x, Calculator<TNumber> y)
/// </summary>
/// <param name="left">The left operand</param>
/// <param name="right">The right operand</param>
/// <returns>Returns <see langword="true"/> if its operands are not equal, otherwise <see langword="false"/>.</returns>
/// <returns>Returns <see langword="true"/> if its operands aren't equal, otherwise <see langword="false"/>.</returns>
public static bool operator !=(FinitePoint<TNumber> left, FinitePoint<TNumber> right) => !left.Equals(right);

/// <summary>
/// Greater than operator
/// </summary>
/// <param name="left">The 1st operand</param>
/// <param name="right">The 2nd operand</param>
/// <returns>Returns <see langword="true"/> if its 1st operand is greater than its 2nd operand, otherwise <see langword="false"/>.</returns>
/// <param name="left">The first operand</param>
/// <param name="right">The second operand</param>
/// <returns>Returns <see langword="true"/> if its first operand is greater than its second operand, otherwise <see langword="false"/>.</returns>
public static bool operator >(FinitePoint<TNumber> left, FinitePoint<TNumber> right) => left.CompareTo(right) == 1;

/// <summary>
/// Less than operator
/// </summary>
/// <param name="left">The 1st operand</param>
/// <param name="right">The 2nd operand</param>
/// <returns>Returns <see langword="true"/> if its 1st operand is less than its 2nd operand, otherwise <see langword="false"/>.</returns>
/// <param name="left">The first operand</param>
/// <param name="right">The second operand</param>
/// <returns>Returns <see langword="true"/> if its first operand is less than its second operand, otherwise <see langword="false"/>.</returns>
public static bool operator <(FinitePoint<TNumber> left, FinitePoint<TNumber> right) => left.CompareTo(right) == -1;

/// <summary>
/// Greater than or equal operator
/// </summary>
/// <param name="left">The 1st operand</param>
/// <param name="right">The 2nd operand</param>
/// <returns>Returns <see langword="true"/> if its 1st operand is greater than or equal to its 2nd operand, otherwise <see langword="false"/>.</returns>
/// <param name="right">The second operand</param>
/// <returns>Returns <see langword="true"/> if its first operand is greater than or equal to its second operand, otherwise <see langword="false"/>.</returns>
public static bool operator >=(FinitePoint<TNumber> left, FinitePoint<TNumber> right) => left.CompareTo(right) >= 0;

/// <summary>
/// Less than or equal operator
/// </summary>
/// <param name="left">The 1st operand</param>
/// <param name="right">The 2nd operand</param>
/// <returns>Returns <see langword="true"/> if its 1st operand is less than or equal to its 2nd operand, otherwise <see langword="false"/>.</returns>
/// <param name="left">The first operand</param>
/// <param name="right">The second operand</param>
/// <returns>Returns <see langword="true"/> if its first operand is less than or equal to its second operand, otherwise <see langword="false"/>.</returns>
public static bool operator <=(FinitePoint<TNumber> left, FinitePoint<TNumber> right) => left.CompareTo(right) <= 0;

/// <inheritdoc />
Expand Down Expand Up @@ -251,7 +251,7 @@ private static Calculator<TNumber> Evaluate(IEnumerable<Calculator<TNumber>> pol
/// Converts a byte collection to hexadecimal string.
/// </summary>
/// <param name="bytes"></param>
/// <returns>human readable / printable string</returns>
/// <returns>human-readable / printable string</returns>
/// <remarks>
/// Based on discussion on <see href="https://stackoverflow.com/questions/623104/byte-to-hex-string/5919521#5919521">stackoverflow</see>
/// </remarks>
Expand Down Expand Up @@ -287,8 +287,7 @@ private static string ToHexString(IEnumerable<byte> bytes)
private static byte[] ToByteArray(string hexString)
{
byte[] bytes = new byte[hexString.Length / 2];
var hexValues = Array.AsReadOnly(new[]
{
var hexValues = Array.AsReadOnly([
0x00,
0x01,
0x02,
Expand All @@ -312,7 +311,7 @@ private static byte[] ToByteArray(string hexString)
0x0D,
0x0E,
0x0F
});
]);

for (int i = 0, j = 0; j < hexString.Length; j += 2, i += 1)
{
Expand Down
43 changes: 43 additions & 0 deletions src/Cryptography/IMakeSharesUseCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace SecretSharingDotNet.Cryptography;

/// <summary>
/// Interface for the Shamir's Secret Sharing algorithm implementation for creating shared secrets.
/// </summary>
/// <typeparam name="TNumber">Numeric data type (An integer type)</typeparam>
public interface IMakeSharesUseCase<TNumber>
{
/// <summary>
/// Generates a random shamir pool, returns the random secret and the share points.
/// </summary>
/// <param name="numberOfMinimumShares">Minimum number of shared secrets for reconstruction</param>
/// <param name="numberOfShares">Maximum number of shared secrets</param>
/// <param name="securityLevel">Security level (in number of bits). The minimum is 13.</param>
/// <returns>A <see cref="Shares{TNumber}"/> object</returns>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// The <paramref name="securityLevel"/> parameter is lower than 13 or greater than 43.112.609. OR The <paramref name="numberOfMinimumShares"/> parameter is lower than 2 or greater than <paramref name="numberOfShares"/>.
/// </exception>
Shares<TNumber> MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, int securityLevel);

/// <summary>
/// Generates a random shamir pool, returns the specified <paramref name="secret"/> and the share points.
/// </summary>
/// <param name="numberOfMinimumShares">Minimum number of shared secrets for reconstruction</param>
/// <param name="numberOfShares">Maximum number of shared secrets</param>
/// <param name="secret">secret text as <see cref="Secret{TNumber}"/> or see cref="string"/></param>
/// <param name="securityLevel">Security level (in number of bits). The minimum is 13.</param>
/// <returns>A <see cref="Shares{TNumber}"/> object</returns>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// The <paramref name="securityLevel"/> is lower than 13 or greater than 43.112.609. OR <paramref name="numberOfMinimumShares"/> is lower than 2 or greater than <paramref name="numberOfShares"/>.
/// </exception>
Shares<TNumber> MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, Secret<TNumber> secret, int securityLevel);

/// <summary>
/// Generates a random shamir pool, returns the specified <paramref name="secret"/> and the share points.
/// </summary>
/// <param name="numberOfMinimumShares">Minimum number of shared secrets for reconstruction</param>
/// <param name="numberOfShares">Maximum number of shared secrets</param>
/// <param name="secret">secret text as <see cref="Secret{TNumber}"/> or see cref="string"/></param>
/// <returns>A <see cref="Shares{TNumber}"/> object</returns>
/// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="numberOfMinimumShares"/> is lower than 2 or greater than <paramref name="numberOfShares"/>.</exception>
Shares<TNumber> MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, Secret<TNumber> secret);
}
39 changes: 39 additions & 0 deletions src/Cryptography/IReconstructionUseCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace SecretSharingDotNet.Cryptography;

/// <summary>
/// Interface for the Shamir's Secret Sharing algorithm implementation for reconstructing the secret.
/// </summary>
/// <typeparam name="TNumber"></typeparam>
public interface IReconstructionUseCase<TNumber>
{
/// <summary>
/// Recovers the secret from the given <paramref name="shares"/> (points with x and y on the polynomial)
/// </summary>
/// <param name="shares">Shares represented by <see cref="string"/> and separated by newline.</param>
/// <returns>Re-constructed secret</returns>
Secret<TNumber> Reconstruction(string shares);

/// <summary>
///
/// Recovers the secret from the given <paramref name="shares"/> (points with x and y on the polynomial)
/// </summary>
/// <param name="shares">Shares represented by <see cref="string"/> array.</param>
/// <returns>Re-constructed secret</returns>
Secret<TNumber> Reconstruction(string[] shares);

/// <summary>
/// Recovers the secret from the given <paramref name="shares"/> (points with x and y on the polynomial)
/// </summary>
/// <param name="shares">For details <see cref="Shares{TNumber}"/></param>
/// <returns>Re-constructed secret</returns>
Secret<TNumber> Reconstruction(Shares<TNumber> shares);

/// <summary>
/// Recovers the secret from the given <paramref name="shares"/> (points with x and y on the polynomial)
/// </summary>
/// <param name="shares">Two or more shares represented by a set of <see cref="FinitePoint{TNumber}"/></param>
/// <returns>Re-constructed secret</returns>
/// <exception cref="T:System.ArgumentNullException"><paramref name="shares"/> is <see langword="null"/>.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">The length of <paramref name="shares"/> is lower than 2.</exception>
Secret<TNumber> Reconstruction(FinitePoint<TNumber>[] shares);
}
6 changes: 3 additions & 3 deletions src/Cryptography/Secret`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public static implicit operator Secret<TNumber>(ReadOnlySpan<char> secretText)
/// </summary>
/// <param name="left">The left operand</param>
/// <param name="right">The right operand</param>
/// <returns>Returns <see langword="true"/> if its operands are not equal, otherwise <see langword="false"/>.</returns>
/// <returns>Returns <see langword="true"/> if its operands aren't equal, otherwise <see langword="false"/>.</returns>
public static bool operator !=(Secret<TNumber> left, Secret<TNumber> right) => !left.Equals(right);

/// <summary>
Expand Down Expand Up @@ -276,8 +276,8 @@ public static implicit operator Secret<TNumber>(ReadOnlySpan<char> secretText)
/// <param name="other">An <see cref="Secret{TNumber}"/> instance to compare with this instance.</param>
/// <returns>A value that indicates the relative order of the <see cref="Secret{TNumber}"/> instances being compared.</returns>
public int CompareTo(Secret<TNumber> other) => this.secretNumber
.Subset(0, this.SecretByteSize - MarkByteCount).CompareTo(other.secretNumber
.Subset(0, other.SecretByteSize - MarkByteCount));
.Subset(0, this.SecretByteSize - MarkByteCount)
.CompareTo(other.secretNumber.Subset(0, other.SecretByteSize - MarkByteCount));

/// <summary>
/// Determines whether this instance and an<paramref name="other"/> specified <see cref="Secret{TNumber}"/> instance are equal.
Expand Down
Loading

0 comments on commit 39a34bb

Please sign in to comment.