public static SplitSecret Split(SecretShareType shareType, byte[] secret, int threshold, Diffuser diffuser) { var irreduciblePolynomial = IrreduciblePolynomial.CreateOfByteSize(secret.Length); var rawSecret = secret.ToBigIntegerFromBigEndianUnsignedBytes(); var diffusedSecret = diffuser.Scramble(rawSecret, secret.Length); var secretCoefficient = new FiniteFieldPolynomial(irreduciblePolynomial, diffusedSecret); var allCoefficients = new[] { secretCoefficient } .Concat( GetRandomPolynomials( irreduciblePolynomial, threshold - 1) ) .ToArray(); var passPhrase = new SecureString(); try { foreach (var currentChar in secret.ToHexString()) { passPhrase.AppendChar(currentChar); } } catch { passPhrase = null; } if((passPhrase == null) || (passPhrase.Length == 0)) { passPhrase = null; } return new SplitSecret(shareType, threshold, irreduciblePolynomial, allCoefficients, passPhrase); }
private static CombinedSecret Combine(IEnumerable <SecretShare> shares, Diffuser diffuser) { var allShares = shares.ToArray(); if (allShares.Length == 0) { throw new SecretSplitterException("You must provide at least one secret share (piece)."); } var expectedShareType = allShares[0].ShareType; if (!allShares.All(s => s.ShareType == expectedShareType)) { throw new SecretSplitterException("Secret shares (pieces) must be be of the same type."); } var firstInvalidShare = allShares.FirstOrDefault(s => (s.ShareType != SecretShareType.Unknown) && !s.HasValidChecksum); if (firstInvalidShare != null) { throw new InvalidChecksumShareException(firstInvalidShare.ParsedValue); } var secretCoefficient = LagrangeInterpolator.EvaluateAtZero(allShares.Select(s => s.Point)); var scrambledValue = secretCoefficient.PolynomialValue; var unscrambledValue = diffuser.Unscramble(scrambledValue, scrambledValue.ToByteArray().Length); var recoveredSecret = unscrambledValue.ToUnsignedBigEndianBytes(); return(new CombinedSecret(allShares[0].ShareType, recoveredSecret)); }
// Keeping the methods that take a Diffuser as private to simplify API for now private static string[] SplitMessage(string secret, int threshold, int totalShares, Diffuser diffuser) { return Split(SecretShareType.Message, SecretEncoder.EncodeString(secret), threshold, diffuser) .GetShares(totalShares) .Select(share => share.ToString()) .ToArray(); }
private static CombinedSecret Combine(IEnumerable <SecretShare> shares, Diffuser diffuser) { var allShares = shares.ToArray(); if (allShares.Length == 0) { throw new SecretSplitterException("You must provide at least one secret share (piece)."); } int expectedShareLength = allShares[0].ParsedValue.Substring(allShares[0].ParsedValue.LastIndexOf('-') + 1).Length; if (!allShares.All(s => s.ParsedValue.Substring(s.ParsedValue.LastIndexOf('-') + 1).Length == expectedShareLength)) { throw new SecretSplitterException("Secret shares (pieces) must be be of the same size."); } var expectedShareType = allShares[0].ShareType; if (!allShares.All(s => s.ShareType == expectedShareType)) { throw new SecretSplitterException("Secret shares (pieces) must be be of the same type."); } var firstInvalidShare = allShares.FirstOrDefault(s => (s.ShareType != SecretShareType.Unknown) && !s.HasValidChecksum); if (firstInvalidShare != null) { throw new InvalidChecksumShareException(firstInvalidShare.ParsedValue); } var secretCoefficient = LagrangeInterpolator.EvaluateAtZero(allShares.Select(s => s.Point)); var scrambledValue = secretCoefficient.PolynomialValue; var unscrambledValue = diffuser.Unscramble(scrambledValue, expectedShareLength / 2); var recoveredSecret = unscrambledValue.ToUnsignedBigEndianBytes(); int paddingNeeded = expectedShareLength / 2 - recoveredSecret.Length; if (paddingNeeded > 0) { var padBytes = new byte[paddingNeeded]; var newArray = new byte[paddingNeeded + recoveredSecret.Length]; Array.Copy(padBytes, 0, newArray, 0, paddingNeeded); Array.Copy(recoveredSecret, 0, newArray, paddingNeeded, recoveredSecret.Length); recoveredSecret = newArray; } return(new CombinedSecret(allShares[0].ShareType, recoveredSecret)); }
private static CombinedSecret Combine(IEnumerable<SecretShare> shares, Diffuser diffuser) { var allShares = shares.ToArray(); if(allShares.Length == 0) { throw new SecretSplitterException("You must provide at least one secret share (piece)."); } var expectedShareType = allShares[0].ShareType; if(!allShares.All(s => s.ShareType == expectedShareType)) { throw new SecretSplitterException("Secret shares (pieces) must be be of the same type."); } var firstInvalidShare = allShares.FirstOrDefault(s => (s.ShareType != SecretShareType.Unknown) && !s.HasValidChecksum); if(firstInvalidShare != null) { throw new InvalidChecksumShareException(firstInvalidShare.ParsedValue); } var secretCoefficient = LagrangeInterpolator.EvaluateAtZero(allShares.Select(s => s.Point)); var scrambledValue = secretCoefficient.PolynomialValue; var unscrambledValue = diffuser.Unscramble(scrambledValue, scrambledValue.ToByteArray().Length); var recoveredSecret = unscrambledValue.ToUnsignedBigEndianBytes(); return new CombinedSecret(allShares[0].ShareType, recoveredSecret); }
public static CombinedSecret Combine(IEnumerable <string> allShares, Diffuser diffuser) { return(Combine(allShares.Select(share => Regex.Match(share, SecretShare.RegexPattern).Value).Select(SecretShare.Parse), diffuser)); }
public static CombinedSecret Combine(IEnumerable<string> allShares, Diffuser diffuser) { return Combine(allShares.Select(share => Regex.Match(share, SecretShare.RegexPattern).Value).Select(SecretShare.Parse), diffuser); }
public static SplitSecret Split(SecretShareType shareType, byte[] secret, int threshold, Diffuser diffuser) { var irreduciblePolynomial = IrreduciblePolynomial.CreateOfByteSize(secret.Length); var rawSecret = secret.ToBigIntegerFromBigEndianUnsignedBytes(); var diffusedSecret = diffuser.Scramble(rawSecret, secret.Length); var secretCoefficient = new FiniteFieldPolynomial(irreduciblePolynomial, diffusedSecret); var allCoefficients = new[] { secretCoefficient } .Concat( GetRandomPolynomials( irreduciblePolynomial, threshold - 1) ) .ToArray(); var passPhrase = new SecureString(); try { foreach (var currentChar in secret.ToHexString()) { passPhrase.AppendChar(currentChar); } } catch { passPhrase = null; } if ((passPhrase == null) || (passPhrase.Length == 0)) { passPhrase = null; } return(new SplitSecret(shareType, threshold, irreduciblePolynomial, allCoefficients, passPhrase)); }
// Keeping the methods that take a Diffuser as private to simplify API for now private static string[] SplitMessage(string secret, int threshold, int totalShares, Diffuser diffuser) { return (Split(SecretShareType.Message, SecretEncoder.EncodeString(secret), threshold, diffuser) .GetShares(totalShares) .Select(share => share.ToString()) .ToArray()); }