public static void TestShamir(int n, BigInteger prime, int seed) { var PolyDegree = (int)Math.Ceiling(n / 3.0); var i1 = new BigZp(prime, StaticRandom.Next(1000000000)); var i2 = new BigZp(prime, StaticRandom.Next(1000000000)); var i3 = new BigZp(prime, StaticRandom.Next(1000000000)); var i4 = new BigZp(prime, StaticRandom.Next(1000000000)); var a = i1 + i2 + i3 + i4; var shares1 = BigShamirSharing.Share(i1, n, PolyDegree - 1); var shares2 = BigShamirSharing.Share(i2, n, PolyDegree - 1); var shares3 = BigShamirSharing.Share(i3, n, PolyDegree - 1); var shares4 = BigShamirSharing.Share(i4, n, PolyDegree - 1); var rs = new List <BigZp>(n); for (int i = 0; i < n; i++) { rs.Add(new BigZp(prime)); rs[i] += shares1[i]; rs[i] += shares2[i]; rs[i] += shares3[i]; rs[i] += shares4[i]; } var t = BigShamirSharing.Recombine(rs, PolyDegree - 1, prime); }
private void Recombine() { BigZp[,] orderedShares = new BigZp[FinalSharesPerParty, StartShareCount]; int senderPos = 0; foreach (var sender in Quorums[FROM].Members) { var sharesFromSender = sharesRecv[sender]; for (int i = 0; i < StartSharesPerParty; i++) { var resharesForShare = sharesFromSender[i]; for (int j = 0; j < resharesForShare.Count; j++) { var msg = resharesForShare[j]; orderedShares[j, senderPos *StartSharesPerParty + i] = msg.Share; } } senderPos++; } Result = new BigZp[FinalSharesPerParty]; for (int i = 0; i < FinalSharesPerParty; i++) { Result[i] = new BigZp(Prime); for (int j = 0; j < StartShareCount; j++) { Result[i] += orderedShares[i, j] * VandermondeInv[j]; } } IsCompleted = true; }
/// <summary> /// Evaluates the shares of secret with polynomial of degree 'polynomDeg' and 'numPlayers' players. /// </summary> private static IList <BigZp> Share(BigZp secret, int numPlayers, int polyDeg, bool usePrimitiveShare, out IList <BigZp> coeffs) { #if NO_COMPUTATION // send some dummy shares var shares = new BigZp[numPlayers]; for (int i = 0; i < numPlayers; i++) { shares[i] = new BigZp(secret.Prime); } return(shares); #else Debug.Assert(numPlayers > polyDeg, "Polynomial degree cannot be greater than or equal to the number of players!"); // Create a random polynomial - f(x) // Note: Polynomial of degree d has d+1 coefficients var randomMatrix = BigZpMatrix.GetRandomMatrix(1, polyDeg + 1, secret.Prime); // The free variable in the Random Polynomial (i.e. f(x)) is the secret randomMatrix.SetMatrixCell(0, 0, secret); // Polynomial coefficients coeffs = randomMatrix.GetMatrixRow(0); // Create vanderMonde matrix var vanderMonde = BigZpMatrix.GetVandermondeMatrix(polyDeg + 1, numPlayers, secret.Prime); // Compute f(i) for the i-th player var sharesArr = randomMatrix.Times(vanderMonde).ZpVector; Debug.Assert(sharesArr.Length == numPlayers); return(sharesArr); #endif }
public static void ReconstructDictionary(Quorum q, OutputGateAddress[] ordering, int qSize) { List <BigZp> result = new List <BigZp>(); foreach (OutputGateAddress outAddr in ordering) { if (outAddr == null) { continue; } BigZp[] shares = new BigZp[qSize]; int j = 0; foreach (var id in q.Members) { Protocol <IDictionary <OutputGateAddress, Share <BigZp> > > p = (NetSimulator.GetParty(id) as TestParty <IDictionary <OutputGateAddress, Share <BigZp> > >).UnderTest; if (p.Result.ContainsKey(outAddr)) { shares[j++] = p.Result[outAddr].Value; } } result.Add(BigShamirSharing.Recombine(new List <BigZp>(shares), (int)Math.Ceiling(qSize / 3.0) - 1, prime)); } Console.WriteLine("Result: " + string.Join(" ", result)); }
internal BigZp InternalCalculate(IList <BigZp> inputs) { var values = new List <BigZp>(); foreach (BigWire wire in InputWires) { if (wire.IsInput) { if (inputs.Count <= wire.InputIndex) { throw new Exception("Input " + wire.InputIndex + " is expected - not found in the list given"); } values.Add(inputs[wire.InputIndex]); } else { Debug.Assert(wire.SourceGate != null && wire.SourceGate.IsOutputReady); values.Add(wire.ConstValue != null ? wire.ConstValue : wire.SourceGate.OutputValue); } } OutputValue = new BigZp(values[0]); values.RemoveAt(0); foreach (BigZp value in values) { OutputValue.Calculate(value, Operation == Operation.Div && value.Value == 0 ? Operation.Mul : Operation); } return(OutputValue); }
public MpsParty(int numParties, BigZp input) { SortedSet<int> parties = new SortedSet<int>(); for (int i = 0; i < numParties; i++) parties.Add(i); Protocol = new MultiPartyShufflingProtocol(this, parties, ProtocolIdGenerator.GenericIdentifier(0), input, input.Prime); //Protocol = new MultiPartySortingProtocol(this, parties, ProtocolIdGenerator.GenericIdentifier(0), input, input.Prime); }
public MpsParty(int numParties, BigZp input) { SortedSet <int> parties = new SortedSet <int>(); for (int i = 0; i < numParties; i++) { parties.Add(i); } Protocol = new MultiPartyShufflingProtocol(this, parties, ProtocolIdGenerator.GenericIdentifier(0), input, input.Prime); //Protocol = new MultiPartySortingProtocol(this, parties, ProtocolIdGenerator.GenericIdentifier(0), input, input.Prime); }
public static MG GenerateCommitment(int numShares, BigZp[] coeffs, BigInteger prime, ref MG[] witnesses, PolyCommit polyCommit) { var iz = new BigZp[numShares]; for (int i = 0; i < numShares; i++) { iz[i] = new BigZp(prime, new BigInteger(i + 1)); } byte[] proof = null; MG commitment = polyCommit.Commit(coeffs, iz, ref witnesses, ref proof, false); return commitment; }
public static MG GenerateCommitment(int numShares, BigZp[] coeffs, BigInteger prime, ref MG[] witnesses, PolyCommit polyCommit) { var iz = new BigZp[numShares]; for (int i = 0; i < numShares; i++) { iz[i] = new BigZp(prime, new BigInteger(i + 1)); } byte[] proof = null; MG commitment = polyCommit.Commit(coeffs, iz, ref witnesses, ref proof, false); return(commitment); }
private void Reshare(BigZp secret) { Debug.Assert(Prime == secret.Prime); IList <BigZp> coeffs = null; var shares = BigShamirSharing.Share(secret, FinalShareCount, NewPolyDeg, out coeffs); MG[] witnesses = null; MG commitment = null; if (PolyCommit != null) { commitment = BigShamirSharing.GenerateCommitment(FinalShareCount, coeffs.ToArray(), Prime, ref witnesses, (Quorums[TO] as ByzantineQuorum).PolyCommit); // fake random generation round for (int i = 0; i < Quorums[TO].Size; i++) { NetSimulator.FakeMulticast(Quorums[TO].Size, secret.Size); } // fake commitment and challenge response NetSimulator.FakeMulticast(Quorums[TO].Size, secret.Size); NetSimulator.FakeMulticast(Quorums[TO].Size, secret.Size); } else { witnesses = new MG[FinalShareCount]; } QuorumBroadcast(new CommitMsg(commitment), TO); // create the share messages if (PolyCommit != null) { Debug.Assert(PolyCommit.VerifyEval(commitment, new BigZp(Prime, 2), shares[1], witnesses[1])); } Debug.Assert(BigShamirSharing.Recombine(shares, NewPolyDeg, Prime) == secret); int numSent = 0; //int delay = (PolyCommit != null) ? 1 : 0; foreach (var toMember in Quorums[TO].Members) { for (int i = 0; i < FinalSharesPerParty; i++) { Send(toMember, new ShareWitnessMsg <BigZp>(shares[numSent], witnesses[numSent])); numSent++; } } }
public static void Reconstruct(Quorum q) { BigZp[] shares = new BigZp[q.Size]; int i = 0; foreach (var id in q.Members) { shares[i++] = (NetSimulator.GetParty(id) as TestParty <Share <BigZp> >).UnderTest.Result.Value; } var val = BigShamirSharing.Recombine(new List <BigZp>(shares), (int)Math.Ceiling(q.Size / 3.0) - 1, prime); Console.WriteLine("Output: " + val); }
public static void SetupLeastSignificantBit(Quorum quorum) { int n = quorum.Size; var input = new BigZp(prime, 2); var polyDeg = (int)Math.Ceiling(n / 3.0) - 1; var shares = BigShamirSharing.Share(input, n, polyDeg); for (int i = 0; i < n; i++) { TestParty <Share <BigZp> > party = new TestParty <Share <BigZp> >(); party.UnderTest = new LeastSignificantBitProtocol(party, quorum, new Share <BigZp>(shares[i])); NetSimulator.RegisterParty(party); } }
public static void SetupReconstructionProtocol(Quorum quorum) { int n = quorum.Size; var input = new BigZp(prime, 20); var polyDeg = (int)Math.Ceiling(n / 3.0) - 1; var shares = BigShamirSharing.Share(input, n, polyDeg); for (int i = 0; i < n; i++) { TestParty <BigZp> party = new TestParty <BigZp>(); ReconstructionProtocol rp = new ReconstructionProtocol(party, quorum, new Share <BigZp>(shares[i])); party.UnderTest = rp; NetSimulator.RegisterParty(party); } }
private static BigZp[] TruncateVector(BigZp[] vector, int toSize) { if (vector.Length < toSize) { return(null); } var truncVec = new BigZp[toSize]; for (int i = 0; i < toSize; i++) { truncVec[i] = new BigZp(vector[i]); } return(truncVec); }
public static void ReconstructTuple(Quorum q) { BigZp[] shares1 = new BigZp[q.Size]; BigZp[] shares2 = new BigZp[q.Size]; int i = 0; foreach (var id in q.Members) { var result = (NetSimulator.GetParty(id) as TestParty <Tuple <Share <BigZp>, Share <BigZp> > >).UnderTest.Result; shares1[i] = result.Item1.Value; shares2[i] = result.Item2.Value; i++; } var val1 = BigShamirSharing.Recombine(new List <BigZp>(shares1), (int)Math.Ceiling(q.Size / 3.0) - 1, prime); var val2 = BigShamirSharing.Recombine(new List <BigZp>(shares2), (int)Math.Ceiling(q.Size / 3.0) - 1, prime); Console.WriteLine(val1 + " " + val2); }
public static void ReconstructBitwise(Quorum q, int bitCount) { List <BigZp> result = new List <BigZp>(); for (int i = bitCount - 1; i >= 0; i--) { BigZp[] shares = new BigZp[q.Size]; int j = 0; foreach (var id in q.Members) { shares[j++] = (NetSimulator.GetParty(id) as TestParty <List <Share <BigZp> > >).UnderTest.Result[i].Value; } result.Add(BigShamirSharing.Recombine(new List <BigZp>(shares), (int)Math.Ceiling(q.Size / 3.0) - 1, prime)); } foreach (var bit in result) { Console.Write(bit); } Console.WriteLine(); }
// Mahdi's recombine method based on Lagrange interpolation for finite fields. private static BigZp SimpleRecombine(IList <BigZp> sharedSecrets, int polyDeg, BigInteger prime) { if (sharedSecrets.Count < polyDeg) { throw new System.ArgumentException("Polynomial degree cannot be bigger or equal to the number of shares"); } // find Lagrange basis polynomials free coefficients var L = new BigZp[polyDeg + 1]; for (int i = 0; i < polyDeg + 1; i++) { L[i] = new BigZp(prime, 1); } int ix = 0; for (var i = new BigZp(prime, 1); i < polyDeg + 2; i++, ix++) { for (var j = new BigZp(prime, 1); j < polyDeg + 2; j++) { if (j != i) { var additiveInverse = j.AdditiveInverse; L[ix] = L[ix] * (additiveInverse / (i + additiveInverse)); // note: division done in finite-field } } } // find the secret by multiplying each share to the corresponding Lagrange's free coefficient var secret = new BigZp(prime, 0); for (int i = 0; i < polyDeg + 1; i++) { secret = secret + (L[i] * sharedSecrets[i]); } return(secret); }
public static void ReconstructDictionary(Quorum q, OutputGateAddress[] ordering, int qSize) { List<BigZp> result = new List<BigZp>(); foreach (OutputGateAddress outAddr in ordering) { if (outAddr == null) continue; BigZp[] shares = new BigZp[qSize]; int j = 0; foreach (var id in q.Members) { Protocol<IDictionary<OutputGateAddress, Share<BigZp>>> p = (NetSimulator.GetParty(id) as TestParty<IDictionary<OutputGateAddress, Share<BigZp>>>).UnderTest; if (p.Result.ContainsKey(outAddr)) shares[j++] = p.Result[outAddr].Value; } result.Add(BigShamirSharing.Recombine(new List<BigZp>(shares), (int)Math.Ceiling(qSize / 3.0) - 1, prime)); } Console.WriteLine("Result: " + string.Join(" ", result)); }
public static void ReconstructBitwise(Quorum q, int bitCount) { List<BigZp> result = new List<BigZp>(); for (int i = bitCount - 1; i >= 0; i--) { BigZp[] shares = new BigZp[q.Size]; int j = 0; foreach (var id in q.Members) { shares[j++] = (NetSimulator.GetParty(id) as TestParty<List<Share<BigZp>>>).UnderTest.Result[i].Value; } result.Add(BigShamirSharing.Recombine(new List<BigZp>(shares), (int)Math.Ceiling(q.Size / 3.0) - 1, prime)); } foreach (var bit in result) { Console.Write(bit); } Console.WriteLine(); }
/// <summary> /// Discrete logarithm encryption. /// </summary> /// <param name="x">Value to be encrypted.</param> /// <param name="p">Prime modulus. Should be large enough (> 1024 bits) to ensure security.</param> public static BigInteger DLEncrypt(BigZp x, BigInteger p) { return BigInteger.ModPow(2, x.Value, p); }
public BigZp GenerateRandom() { int polyDegree = NumParties / 3; BigInteger myRandom; if (Prime > int.MaxValue) myRandom = StaticRandom.Next(Prime); else myRandom = StaticRandom.Next((int) Prime); IList<BigZp> shares = BigShamirSharing.Share(new BigZp(Prime, myRandom), PartyIds.Count, PartyIds.Count / 3); IList<BigShareMsg> sendMsgs = new List<BigShareMsg>(); foreach (BigZp share in shares) { sendMsgs.Add(new BigShareMsg(share)); } IList<BigShareMsg> recvMsgs = SendReceive(PartyIds, sendMsgs); List<BigZp> receivedShares = new List<BigZp>(); foreach (BigShareMsg shareMsg in recvMsgs) { receivedShares.Add(shareMsg.Value); } /* eVSS sharing = new eVSS(Party, PartyIds, Prime, NumParties / 3); sharing.Setup(RandGen.Next(int.MinValue, int.MaxValue)); List<BigZp> receivedShares = sharing.ShareVerify(new BigZp(Prime, myRandom), true); */ BigZp combinedShare = new BigZp(Prime); for (var i = 0; i < receivedShares.Count; i++) { combinedShare += receivedShares[i]; } //BigZp random = sharing.Reconst(combinedShare); var finalShareMsgs = BroadcastReceive(new BigShareMsg(combinedShare)); finalShareMsgs.Sort(new SenderComparer()); var finalShares = new List<BigZp>(); foreach (var finalShareMsg in finalShareMsgs) { finalShares.Add(finalShareMsg.Value); } BigZp random = BigShamirSharing.Recombine(finalShares, PartyIds.Count / 3, Prime, false); return random; }
public override void Run() { Result = GenerateRandom(); }
public BigWire(BigZp constValue) : this() { this.ConstValue = constValue; }
public static void SetupReconstructionProtocol(Quorum quorum) { int n = quorum.Size; var input = new BigZp(prime, 20); var polyDeg = (int)Math.Ceiling(n / 3.0) - 1; var shares = BigShamirSharing.Share(input, n, polyDeg); for (int i = 0; i < n; i++) { TestParty<BigZp> party = new TestParty<BigZp>(); ReconstructionProtocol rp = new ReconstructionProtocol(party, quorum, new Share<BigZp>(shares[i])); party.UnderTest = rp; NetSimulator.RegisterParty(party); } }
private static BigZp[] TruncateVector(BigZp[] vector, int toSize) { if (vector.Length < toSize) return null; var truncVec = new BigZp[toSize]; for (int i = 0; i < toSize; i++) truncVec[i] = new BigZp(vector[i]); return truncVec; }
// Mahdi's recombine method based on Lagrange interpolation for finite fields. private static BigZp SimpleRecombine(IList<BigZp> sharedSecrets, int polyDeg, BigInteger prime) { if (sharedSecrets.Count < polyDeg) throw new System.ArgumentException("Polynomial degree cannot be bigger or equal to the number of shares"); // find Lagrange basis polynomials free coefficients var L = new BigZp[polyDeg + 1]; for (int i = 0; i < polyDeg + 1; i++) L[i] = new BigZp(prime, 1); int ix = 0; for (var i = new BigZp(prime, 1); i < polyDeg + 2; i++, ix++) { for (var j = new BigZp(prime, 1); j < polyDeg + 2; j++) { if (j != i) { var additiveInverse = j.AdditiveInverse; L[ix] = L[ix] * (additiveInverse / (i + additiveInverse)); // note: division done in finite-field } } } // find the secret by multiplying each share to the corresponding Lagrange's free coefficient var secret = new BigZp(prime, 0); for (int i = 0; i < polyDeg + 1; i++) secret = secret + (L[i] * sharedSecrets[i]); return secret; }
/// <summary> /// Calculates the shares of a secret with polynomial of degree t and numPlayers players. /// The method also returns the array of coefficients of the polynomial. /// </summary> public static IList<BigZp> Share(BigZp secret, int numPlayers, int polyDeg, out IList<BigZp> coeffs) { return Share(secret, numPlayers, polyDeg, false, out coeffs); }
internal BigZp InternalCalculate(IList<BigZp> inputs) { var values = new List<BigZp>(); foreach (BigWire wire in InputWires) { if (wire.IsInput) { if (inputs.Count <= wire.InputIndex) throw new Exception("Input " + wire.InputIndex + " is expected - not found in the list given"); values.Add(inputs[wire.InputIndex]); } else { Debug.Assert(wire.SourceGate != null && wire.SourceGate.IsOutputReady); values.Add(wire.ConstValue != null ? wire.ConstValue : wire.SourceGate.OutputValue); } } OutputValue = new BigZp(values[0]); values.RemoveAt(0); foreach (BigZp value in values) { OutputValue.Calculate(value, Operation == Operation.Div && value.Value == 0 ? Operation.Mul : Operation); } return OutputValue; }
public static void ReconstructTuple(Quorum q) { BigZp[] shares1 = new BigZp[q.Size]; BigZp[] shares2 = new BigZp[q.Size]; int i = 0; foreach (var id in q.Members) { var result = (NetSimulator.GetParty(id) as TestParty<Tuple<Share<BigZp>, Share<BigZp>>>).UnderTest.Result; shares1[i] = result.Item1.Value; shares2[i] = result.Item2.Value; i++; } var val1 = BigShamirSharing.Recombine(new List<BigZp>(shares1), (int)Math.Ceiling(q.Size / 3.0) - 1, prime); var val2 = BigShamirSharing.Recombine(new List<BigZp>(shares2), (int)Math.Ceiling(q.Size / 3.0) - 1, prime); Console.WriteLine(val1 + " " + val2); }
public BigShareMsg(BigZp value) { Value = value; }
public static void SetupLeastSignificantBit(Quorum quorum) { int n = quorum.Size; var input = new BigZp(prime, 2); var polyDeg = (int)Math.Ceiling(n / 3.0) - 1; var shares = BigShamirSharing.Share(input, n, polyDeg); for (int i = 0; i < n; i++) { TestParty<Share<BigZp>> party = new TestParty<Share<BigZp>>(); party.UnderTest = new LeastSignificantBitProtocol(party, quorum, new Share<BigZp>(shares[i])); NetSimulator.RegisterParty(party); } }
public BigZp GenerateRandom() { int polyDegree = NumParties / 3; BigInteger myRandom; if (Prime > int.MaxValue) { myRandom = StaticRandom.Next(Prime); } else { myRandom = StaticRandom.Next((int)Prime); } IList <BigZp> shares = BigShamirSharing.Share(new BigZp(Prime, myRandom), PartyIds.Count, PartyIds.Count / 3); IList <BigShareMsg> sendMsgs = new List <BigShareMsg>(); foreach (BigZp share in shares) { sendMsgs.Add(new BigShareMsg(share)); } IList <BigShareMsg> recvMsgs = SendReceive(PartyIds, sendMsgs); List <BigZp> receivedShares = new List <BigZp>(); foreach (BigShareMsg shareMsg in recvMsgs) { receivedShares.Add(shareMsg.Value); } /* * eVSS sharing = new eVSS(Party, PartyIds, Prime, NumParties / 3); * sharing.Setup(RandGen.Next(int.MinValue, int.MaxValue)); * * List<BigZp> receivedShares = sharing.ShareVerify(new BigZp(Prime, myRandom), true); */ BigZp combinedShare = new BigZp(Prime); for (var i = 0; i < receivedShares.Count; i++) { combinedShare += receivedShares[i]; } //BigZp random = sharing.Reconst(combinedShare); var finalShareMsgs = BroadcastReceive(new BigShareMsg(combinedShare)); finalShareMsgs.Sort(new SenderComparer()); var finalShares = new List <BigZp>(); foreach (var finalShareMsg in finalShareMsgs) { finalShares.Add(finalShareMsg.Value); } BigZp random = BigShamirSharing.Recombine(finalShares, PartyIds.Count / 3, Prime, false); return(random); }
public static void TestShamir(int n, BigInteger prime, int seed) { var PolyDegree = (int)Math.Ceiling(n / 3.0); var i1 = new BigZp(prime, StaticRandom.Next(1000000000)); var i2 = new BigZp(prime, StaticRandom.Next(1000000000)); var i3 = new BigZp(prime, StaticRandom.Next(1000000000)); var i4 = new BigZp(prime, StaticRandom.Next(1000000000)); var a = i1 + i2 + i3 + i4; var shares1 = BigShamirSharing.Share(i1, n, PolyDegree - 1); var shares2 = BigShamirSharing.Share(i2, n, PolyDegree - 1); var shares3 = BigShamirSharing.Share(i3, n, PolyDegree - 1); var shares4 = BigShamirSharing.Share(i4, n, PolyDegree - 1); var rs = new List<BigZp>(n); for (int i = 0; i < n; i++) { rs.Add(new BigZp(prime)); rs[i] += shares1[i]; rs[i] += shares2[i]; rs[i] += shares3[i]; rs[i] += shares4[i]; } var t = BigShamirSharing.Recombine(rs, PolyDegree - 1, prime); }
/// <summary> /// Calculates the shares of a secret with polynomial of degree t and numPlayers players. /// The method also returns the array of coefficients of the polynomial. /// </summary> public static IList <BigZp> Share(BigZp secret, int numPlayers, int polyDeg, out IList <BigZp> coeffs) { return(Share(secret, numPlayers, polyDeg, false, out coeffs)); }
public BigWire(int inputIndex, bool isOutput, BigZp constValue) { this.InputIndex = inputIndex; this.IsOutput = isOutput; ConstValue = constValue; }
public static void Reconstruct(Quorum q) { BigZp[] shares = new BigZp[q.Size]; int i = 0; foreach (var id in q.Members) { shares[i++] = (NetSimulator.GetParty(id) as TestParty<Share<BigZp>>).UnderTest.Result.Value; } var val = BigShamirSharing.Recombine(new List<BigZp>(shares), (int)Math.Ceiling(q.Size / 3.0) - 1, prime); Console.WriteLine("Output: " + val); }
/// <summary> /// Evaluates the shares of secret with polynomial of degree 'polynomDeg' and 'numPlayers' players. /// </summary> private static IList<BigZp> Share(BigZp secret, int numPlayers, int polyDeg, bool usePrimitiveShare, out IList<BigZp> coeffs) { #if NO_COMPUTATION // send some dummy shares var shares = new BigZp[numPlayers]; for (int i = 0; i < numPlayers; i++) shares[i] = new BigZp(secret.Prime); return shares; #else Debug.Assert(numPlayers > polyDeg, "Polynomial degree cannot be greater than or equal to the number of players!"); // Create a random polynomial - f(x) // Note: Polynomial of degree d has d+1 coefficients var randomMatrix = BigZpMatrix.GetRandomMatrix(1, polyDeg + 1, secret.Prime); // The free variable in the Random Polynomial (i.e. f(x)) is the secret randomMatrix.SetMatrixCell(0, 0, secret); // Polynomial coefficients coeffs = randomMatrix.GetMatrixRow(0); // Create vanderMonde matrix var vanderMonde = BigZpMatrix.GetVandermondeMatrix(polyDeg + 1, numPlayers, secret.Prime); // Compute f(i) for the i-th player var sharesArr = randomMatrix.Times(vanderMonde).ZpVector; Debug.Assert(sharesArr.Length == numPlayers); return sharesArr; #endif }