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 byte[] Combine(IEnumerable <FiniteFieldPoint> points) { var allShares = points.ToArray(); if (allShares.Length == 0) { throw new ArgumentException("You must provide at least one secret share (piece).", nameof(points)); } var secretCoefficient = LagrangeInterpolator.EvaluateAtZero(allShares); var scrambledValue = secretCoefficient.PolynomialValue; var unscrambledValue = DefaultDiffuser.Unscramble(scrambledValue, scrambledValue.ToByteArray().Length); return(unscrambledValue.ToUnsignedBigEndianBytes()); }
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)); }