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 Jun 27, 2024
1 parent d3df3ca commit 0192538
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 59 deletions.
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
39 changes: 21 additions & 18 deletions src/Cryptography/ShamirsSecretSharing`3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ namespace SecretSharingDotNet.Cryptography;
/// Shamir's secret sharing algorithm
/// </summary>
/// <typeparam name="TNumber">Numeric data type</typeparam>
/// <typeparam name="TExtendedGcdAlgorithm"></typeparam>
/// <typeparam name="TExtendedGcdResult"></typeparam>
public class ShamirsSecretSharing<TNumber, TExtendedGcdAlgorithm, TExtendedGcdResult> : ShamirsSecretSharing
/// <typeparam name="TExtendedGcdAlgorithm">Extended greatest common divisor algorithm</typeparam>
/// <typeparam name="TExtendedGcdResult">Extended greatest common divisor result</typeparam>
public class ShamirsSecretSharing<TNumber, TExtendedGcdAlgorithm, TExtendedGcdResult> : ShamirsSecretSharing,
IMakeSharesUseCase<TNumber>, IReconstructionUseCase<TNumber>
where TExtendedGcdAlgorithm : class, IExtendedGcdAlgorithm<TNumber, TExtendedGcdResult>
where TExtendedGcdResult : struct, IExtendedGcdResult<TNumber>
{
Expand All @@ -70,21 +71,21 @@ public class ShamirsSecretSharing<TNumber, TExtendedGcdAlgorithm, TExtendedGcdRe
public ShamirsSecretSharing(TExtendedGcdAlgorithm extendedGcd)
{
this.extendedGcd = extendedGcd ?? throw new ArgumentNullException(nameof(extendedGcd));
this.SecurityLevel = 13;
this.SecurityLevel = SecurityLevels[0];
}

/// <summary>
/// Gets or sets the security level
/// </summary>
/// <remarks>Value is lower than 13 or greater than 43112609.</remarks>
/// <exception cref="T:System.ArgumentOutOfRangeException" accessor="set">Value is lower than 13 or greater than 43112609.</exception>
/// <remarks>The value is lower than 13 or greater than 43.112.609.</remarks>
/// <exception cref="T:System.ArgumentOutOfRangeException" accessor="set">The value is lower than 13 or greater than 43.112.609.</exception>
public int SecurityLevel
{
get => this.fixedSecurityLevel;

set
{
if (value < 13)
if (value < SecurityLevels[0])
{
throw new ArgumentOutOfRangeException(nameof(value), value, ErrorMessages.MinimumSecurityLevelExceeded);
}
Expand Down Expand Up @@ -112,9 +113,11 @@ public int SecurityLevel
/// </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). Minimum is 13.</param>
/// <param name="securityLevel">Security level (in number of bits). The minimum is 13.</param>
/// <returns></returns>
/// <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="securityLevel"/> parameter is lower than 13 or greater than 43112609. OR The <paramref name="numberOfMinimumShares"/> parameter is lower than 2 or greater than <paramref name="numberOfShares"/>.</exception>
/// <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>
public Shares<TNumber> MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, int securityLevel)
{
try
Expand Down Expand Up @@ -156,10 +159,12 @@ public Shares<TNumber> MakeShares(TNumber numberOfMinimumShares, TNumber numberO
/// <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). Minimum is 13.</param>
/// <param name="securityLevel">Security level (in number of bits). The minimum is 13.</param>
/// <returns></returns>
/// <remarks>This method can modify the <see cref="SecurityLevel"/> based on the <paramref name="secret"/> length.</remarks>
/// <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="securityLevel"/> is lower than 13 or greater than 43112609. OR <paramref name="numberOfMinimumShares"/> is lower than 2 or greater than <paramref name="numberOfShares"/>.</exception>
/// <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>
public Shares<TNumber> MakeShares(TNumber numberOfMinimumShares, TNumber numberOfShares, Secret<TNumber> secret, int securityLevel)
{
try
Expand Down Expand Up @@ -220,13 +225,11 @@ private Calculator<TNumber>[] CreatePolynomial(int numberOfMinimumShares)
var polynomial = new Calculator<TNumber>[numberOfMinimumShares];
polynomial[0] = Calculator<TNumber>.Zero;
byte[] randomNumber = new byte[this.mersennePrime.ByteCount];
using (var rng = RandomNumberGenerator.Create())
using var rng = RandomNumberGenerator.Create();
for (int i = 1; i < numberOfMinimumShares; i++)
{
for (int i = 1; i < numberOfMinimumShares; i++)
{
rng.GetBytes(randomNumber);
polynomial[i] = (Calculator.Create(randomNumber, typeof(TNumber)) as Calculator<TNumber>)?.Abs() % this.mersennePrime;
}
rng.GetBytes(randomNumber);
polynomial[i] = (Calculator.Create(randomNumber, typeof(TNumber)) as Calculator<TNumber>)?.Abs() % this.mersennePrime;
}

return polynomial;
Expand Down Expand Up @@ -293,7 +296,7 @@ private static Calculator<TNumber> Product(IReadOnlyList<Calculator<TNumber>> va
/// k points will define a polynomial of up to kth order
/// </summary>
/// <param name="finitePoints">The shares represented by a set of <see cref="FinitePoint{TNumber}"/>.</param>
/// <param name="prime">A prime number must be defined to avoid computation with real numbers. In fact it is finite field arithmetic.
/// <param name="prime">A prime number must be defined to avoid computation with real numbers. In fact, it is finite field arithmetic.
/// The prime number must be the same as used for the construction of shares.</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>The re-constructed secret.</returns>
Expand Down
2 changes: 1 addition & 1 deletion src/Cryptography/SharedSeparator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ internal static class SharedSeparator
/// <summary>
/// Separator array for <see cref="string.Split(char[])"/> method usage to avoid allocation of a new array.
/// </summary>
internal static readonly char[] CoordinateSeparatorArray = { CoordinateSeparator };
internal static readonly char[] CoordinateSeparatorArray = [CoordinateSeparator];
}
Loading

0 comments on commit 0192538

Please sign in to comment.