/* * prime = prime20; * Main(32); * NetSimulator.Reset(); * * prime = prime30; * Main(32); * NetSimulator.Reset(); * * prime = prime40; * Main(32); * NetSimulator.Reset(); * * prime = prime50; * Main(32); * NetSimulator.Reset(); */ public static void Main(int n) // number of parties { Debug.Assert(NumTheoryUtils.MillerRabin(prime, 5) == false); // must be a prime // Create an MPC network, add parties, and init them with random inputs NetSimulator.Init(seed); //seed StaticRandom.Init(seed + 1); //seed + 1 Quorum q = new Quorum(0, 0, n); SetupMps(n); //SetupMultiQuorumCircuitEvaluation(q); Console.WriteLine(n + " parties initialized. Running simulation...\n"); // run the simulator var elapsedTime = Timex.Run(() => NetSimulator.Run()); // CheckMps(n); //ReconstructDictionary(q, network.LastGateForWire, 4); Console.WriteLine("Simulation finished. Checking results...\n"); Console.WriteLine("# parties = " + n); Console.WriteLine("# msgs sent = " + NetSimulator.SentMessageCount.ToString("0.##E+00")); Console.WriteLine("# bits sent = " + (NetSimulator.SentByteCount * 8).ToString("0.##E+00")); Console.WriteLine("Rounds = " + NetSimulator.RoundCount + "\n"); Console.WriteLine("Key size = " + NumTheoryUtils.GetBitLength2(prime) + " bits"); Console.WriteLine("Seed = " + seed + "\n"); Console.WriteLine("Elapsed time = " + elapsedTime.ToString("hh':'mm':'ss'.'fff") + "\n"); }
private bool IsMultStepShareLegal(MultStepBCaseShare recvShareFromPlayer_i, MultStepVerificationPoly recvVerifcationPolynomial) { if (!IsRecvShareLegal(recvShareFromPlayer_i)) { return(false); } var RxPolynomial = recvVerifcationPolynomial.RxPolynomial; Zp Ratpoint0 = Zp.EvalutePolynomialAtPoint(RxPolynomial, new Zp(Prime, 0)); if (!Ratpoint0.Equals(new Zp(Prime, 0))) { return(false); } int w = NumTheoryUtils.GetFieldMinimumPrimitive(Prime); var w_InMyIndex = new Zp(Prime, NumTheoryUtils.ModPow(w, Party.Id, Prime)); Zp RjFromPublicPolynomial = Zp.EvalutePolynomialAtPoint(RxPolynomial, w_InMyIndex); Zp temp = recvShareFromPlayer_i.AShare.ConstMul(recvShareFromPlayer_i.BShare).ConstSub(recvShareFromPlayer_i.AbShare); Zp RjFromRecvPrivateInfo = w_InMyIndex.ConstMul(recvShareFromPlayer_i.RShare).ConstAdd(temp); if (!RjFromPublicPolynomial.Equals(RjFromRecvPrivateInfo)) { return(false); } return(true); }
public static MatrixLong operator *(MatrixLong a, MatrixLong b) { if (a == null) { throw new ArgumentNullException("a"); } if (b == null) { throw new ArgumentNullException("b"); } if (a.Cols != b.Rows) { throw new ArgumentException("Invalid matrix dimensions"); } MatrixLong c = new MatrixLong(a.Rows, b.Cols); for (int i = 0; i < a.Rows; i++) { for (int j = 0; j < b.Cols; ++j) { for (int k = 0; k < a.Cols; ++k) { c._Data[i, j] += NumTheoryUtils.Mul(a._Data[i, k], b._Data[k, j], MOD); if (c._Data[i, j] >= MOD) { c._Data[i, j] -= MOD; } } } } return(c); }
void Solve() { ans = -1; long g = NumTheoryUtils.Gcd(p, q); p /= g; q /= g; long tt = q; while (tt % 2 == 0) { tt /= 2; } if (tt != 1) { return; } ans = 1; while (p < q / 2) { q /= 2; ++ans; } }
protected override Zp GetRecombinedResult(IList <Zp> recvList, int prime) { // Scan recvList - if there are null elements replace them arbitrarily to Zp with zero value for (int i = 0; i < recvList.Count; i++) { if (recvList[i] == null) { recvList[i] = new Zp(prime, 0); } } var xVlaues = new List <Zp>(); int w = NumTheoryUtils.GetFieldMinimumPrimitive(prime); for (int i = 0; i < recvList.Count; i++) { xVlaues.Add(new Zp(prime, NumTheoryUtils.ModPow(w, i, prime))); } // Should call Welch-Berlekamp Decoder to fix error at last stage var fixedShares = WelchBerlekampDecoder.Decode(xVlaues, recvList, PolynomialDeg, PolynomialDeg, prime); if (fixedShares == null) { throw new Exception("There were more then polynomialDegree = " + PolynomialDeg + " Cheaters - cannot extract results."); } return(ShamirSharing.Recombine(fixedShares, PolynomialDeg, prime, true)); }
public override void HandleMessage(int fromId, Msg msg) { Debug.Assert(msg is SubProtocolCompletedMsg); SubProtocolCompletedMsg completedMsg = msg as SubProtocolCompletedMsg; switch (Stage) { case 0: BitwiseRand = (List <Share <BigZp> >)completedMsg.SingleResult; ExecuteSubProtocol(new BitCompositionProtocol(Me, Quorum, BitwiseRand, Prime)); break; case 1: Rand = (Share <BigZp>)completedMsg.SingleResult; ExecuteSubProtocol(new ShareAdditionProtocol(Me, Quorum, Rand, Share)); break; case 2: PaddedShare = (Share <BigZp>)completedMsg.SingleResult; ExecuteSubProtocol(new ReconstructionProtocol(Me, Quorum, PaddedShare)); break; case 3: RevealedPadded = (BigZp)completedMsg.SingleResult; BigZp lowBit = new BigZp(Prime, RevealedPadded.Value.IsEven ? 0 : 1); ExecuteSubProtocol(new SharedBitXor(Me, Quorum, new Share <BigZp>(lowBit, true), BitwiseRand[0])); break; case 4: X = (Share <BigZp>)completedMsg.SingleResult; var bitwiseRevealedPadded = NumTheoryUtils.GetBitDecomposition(RevealedPadded.Value, Prime, BitwiseRand.Count); var bitwiseRevealedPaddedShares = new List <Share <BigZp> >(); foreach (var bit in bitwiseRevealedPadded) { bitwiseRevealedPaddedShares.Add(new Share <BigZp>(bit, true)); } ExecuteSubProtocol(new BitwiseLessThanProtocol(Me, Quorum, bitwiseRevealedPaddedShares, BitwiseRand)); break; case 5: Y = (Share <BigZp>)completedMsg.SingleResult; ExecuteSubProtocol(new SharedBitXor(Me, Quorum, X, Y)); break; case 6: Result = (Share <BigZp>)completedMsg.SingleResult; IsCompleted = true; break; } Stage++; }
private static Zp[] getWelchBerlekampConstraintVector(IList <Zp> XVlaues, IList <Zp> YVlaues, int n, int e, int prime) { var bVector = new Zp[n]; for (int i = 0; i < n; i++) { bVector[i] = new Zp(prime, NumTheoryUtils.ModPow(XVlaues[i].Value, e, prime) * YVlaues[i].Value); } return(bVector); }
public void DivisorArraysTest() { var minD = NumTheoryUtils.GetMinDivisorArray(10000); for (int i = 2; i <= 10000; ++i) { for (int j = 2; j *j <= i; ++j) { if (i % j == 0) { Assert.AreEqual(j, minD[i]); break; } } } var maxD = NumTheoryUtils.GetMaxDivisorArray(10000); for (int i = 2; i <= 10000; ++i) { int t = i, corrent = 0; for (int j = 2; j *j <= t; ++j) { if (t % j == 0) { corrent = j; while (t % j == 0) { t /= j; } } } if (t > 1) { corrent = t; } Assert.AreEqual(corrent, maxD[i], i.ToString()); } for (int i = 2; i <= 10000; ++i) { var divs1 = NumTheoryUtils.Divisors(i, minD); var divs2 = NumTheoryUtils.Divisors(i); Assert.AreEqual(divs2.Length, divs1.Length, i.ToString()); for (int j = 0; j < divs1.Length; ++j) { Assert.AreEqual(divs2[j], divs1[j], i + " " + j); } } }
private static IList <Zp> GenerateF_i_xPolynomial(ZpMatrix f_x_y, Zp secret, int playerNum) { int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime); int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime); var y_values = new int[f_x_y.ColCount]; for (int i = 0; i < f_x_y.ColCount; i++) { y_values[i] = NumTheoryUtils.ModPow(w_i, i, secret.Prime); } return(f_x_y.MulMatrixByScalarsVector(y_values).SumMatrixRows()); }
public override void HandleMessage(int fromId, Msg msg) { Debug.Assert(msg is SubProtocolCompletedMsg); SubProtocolCompletedMsg completedMsg = msg as SubProtocolCompletedMsg; switch (Stage) { case 0: Result = completedMsg.ResultList.Cast <Share <BigZp> >().ToList(); if (Max.IsPowerOfTwo) { // we automatically know the number we generated is in the range IsCompleted = true; } else { var maxBits = NumTheoryUtils.GetBitDecomposition(Max, Prime); var maxBitsShares = new List <Share <BigZp> >(); foreach (var bit in maxBits) { maxBitsShares.Add(new Share <BigZp>(bit, true)); } ExecuteSubProtocol(new BitwiseLessThanProtocol(Me, Quorum, Result, maxBitsShares)); Stage++; } break; case 1: // Reveal (r < p) ExecuteSubProtocol(new ReconstructionProtocol(Me, Quorum, (Share <BigZp>)completedMsg.SingleResult)); Stage++; break; case 2: // If (r < p), then we're done. Otherwise, we should retry since the generated random value is not in the field. if (((BigZp)completedMsg.SingleResult).Value == 1) { IsCompleted = true; } else { // try again :( Result.Clear(); Start(); } break; } }
public RandomBitwiseGenProtocol(Party me, Quorum quorum, BigInteger prime, BigInteger max) : base(me, quorum) { Max = max; Prime = prime; BitsNeeded = NumTheoryUtils.GetBitLength2(Max); if (Max.IsPowerOfTwo) { BitsNeeded--; } Result = new List <Share <BigZp> >(); }
public void ArithmeticsMustWork() { for (int i = -100; i <= 100; ++i) { for (int j = -100; j <= 100; ++j) { for (int mod = 1; mod <= 1000; ++mod) { Assert.AreEqual(((i * j) % mod + mod) % mod, NumTheoryUtils.Mul(i, j, mod)); } } } long mx = 1000000000000000000L; for (int i = -10; i <= 10; ++i) { for (int j = -10; j <= 10; ++j) { for (int mod = 1; mod <= 100; ++mod) { var bi = new BigInteger(mx - i); var bj = new BigInteger(mx - j); var bmod = new BigInteger(mx - mod); Assert.AreEqual((((bi * bj) % bmod + bmod) % bmod).ToString(), NumTheoryUtils.Mul(mx - i, mx - j, mx - mod).ToString(), string.Format("{0}*{1} modulo {2}", bi, bj, bmod)); bi = new BigInteger(-mx + i); bj = new BigInteger(mx - j); bmod = new BigInteger(mx - mod); Assert.AreEqual((((bi * bj) % bmod + bmod) % bmod).ToString(), NumTheoryUtils.Mul(i - mx, mx - j, mx - mod).ToString(), string.Format("{0}*{1} modulo {2}", bi, bj, bmod)); bi = new BigInteger(mx - i); bj = new BigInteger(mx - j); bmod = new BigInteger(mod); Assert.AreEqual((((bi * bj) % bmod + bmod) % bmod).ToString(), NumTheoryUtils.Mul(mx - i, mx - j, mod).ToString(), string.Format("{0}*{1} modulo {2}", bi, bj, bmod)); bi = new BigInteger(-mx + i); bj = new BigInteger(mx - j); bmod = new BigInteger(mod); Assert.AreEqual((((bi * bj) % bmod + bmod) % bmod).ToString(), NumTheoryUtils.Mul(i - mx, mx - j, mod).ToString(), string.Format("{0}*{1} modulo {2}", bi, bj, bmod)); } } } }
private static IList <Zp> GenerateG_i_yPolynomial(ZpMatrix f_x_y, Zp secret, int playerNum) { int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime); int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime); var x_values = new Zp[f_x_y.RowCount]; for (int i = 0; i < f_x_y.RowCount; i++) { x_values[i] = new Zp(secret.Prime, NumTheoryUtils.ModPow(w_i, i, secret.Prime)); } var tempArr = f_x_y.Times(new ZpMatrix(x_values, VectorType.Column)).ZpVector; return(tempArr); }
public void PrimalityTests() { Assert.IsTrue(NumTheoryUtils.IsPrime(22801763489)); Assert.IsTrue(NumTheoryUtils.IsPrime(252097800623)); Assert.IsTrue(NumTheoryUtils.IsPrime(2760727302517)); Assert.IsTrue(NumTheoryUtils.IsPrime(29996224275833)); Assert.IsFalse(NumTheoryUtils.IsPrime(2038074743L * 2038074751L)); Assert.IsFalse(NumTheoryUtils.IsPrime(2038074743L * 2038074743L)); for (int n = 1; n <= 10000; ++n) { Assert.AreEqual(NumTheoryUtils.IsPrimeNaive(n), NumTheoryUtils.IsPrime(n), n.ToString()); } for (int n = 1; n <= 10000; ++n) { Assert.AreEqual(NumTheoryUtils.IsPrimeNaive(n + 1234567), NumTheoryUtils.IsPrime(n + 1234567), (n + 1234567).ToString()); } }
public void GcdTests() { for (int a = -100; a <= 100; ++a) { for (int b = -100; b <= 100; ++b) { int g = NumTheoryUtils.Gcd(a, b); int brute = 0; for (int i = Math.Max(Math.Abs(a), Math.Abs(b)); i > 0; --i) { if (a % i == 0 && b % i == 0) { brute = i; break; } } Assert.AreEqual(brute, g); } } }
//public override void loadFromByteArrayNoHeader(BitStream bs, int prime) //{ // if (bs.readBoolean()) // fi_x = bs.readList(prime); // if (bs.readBoolean()) // gi_y = bs.readList(prime); //} //public override void writeToBitStreamNoHeader(BitStream bs) //{ // bs.writeBoolean(fi_x != null); // if (fi_x != null) // bs.writeList(fi_x); // bs.writeBoolean(gi_y != null); // if (gi_y != null) // bs.writeList(gi_y); //} //public override byte[] writeToByteArray() //{ // var bs = new BitStream(); // bs.writeMessageType(MessageType.ZP_LISTS); // writeToBitStreamNoHeader(bs); // bs.close(); // return bs.ByteArray; //} public virtual IList <Zp> CalculateF_i_xValuesForPlayers(int numOfPlayers, int prime) { int w_i, w = NumTheoryUtils.GetFieldMinimumPrimitive(prime); int value; var f_i_xValues = new List <Zp>(); for (int playerNum = 0; playerNum < numOfPlayers; playerNum++) { w_i = NumTheoryUtils.ModPow(w, playerNum, prime); value = 0; for (int j = 0; j < fi_x.Count; j++) { value += NumTheoryUtils.ModPow(w_i, j, prime) * fi_x[j].Value; } f_i_xValues.Add(new Zp(prime, value)); } return(f_i_xValues); }
public void EulerPhiMustWork() { for (int i = 1; i <= 1000; ++i) { int cnt = 0; for (int j = 1; j <= i; ++j) { if (NumTheoryUtils.Gcd(i, j) == 1) { ++cnt; } } Assert.AreEqual(cnt, NumTheoryUtils.EulerPhi(i)); } var phiArr = NumTheoryUtils.EulerPhiArray(100000); for (int i = 1; i < phiArr.Length; i++) { Assert.AreEqual(NumTheoryUtils.EulerPhi(i), phiArr[i]); } }
/* * Finds a solution to a system of linear equations represtented by an * n-by-n+1 matrix A: namely, denoting by B the left n-by-n submatrix of A * and by C the last column of A, finds a column vector x such that Bx=C. * If more than one solution exists, chooses one arbitrarily by setting some * values to 0. If no solutions exists, returns false. Otherwise, places * a solution into the first argument and returns true. * * Note : matrix A changes (gets converted to row echelon form). */ private static Zp[] linearSolve(ZpMatrix A, ZpMatrix B, int prime) { var invArray = NumTheoryUtils.GetFieldInverse(prime); var C = ZpMatrix.GetConcatenationMatrix(A, B); // augmented matrix int n = C.RowCount; int[] solution = new int[n]; int temp; int firstDeterminedValue = n; // we will be determining values of the solution // from n-1 down to 0. At any given time, // values from firstDeterminedValue to n-1 have been // found. Initializing to n means // no values have been found yet. // To put it another way, the variabe firstDeterminedValue // stores the position of first nonzero entry in the row just examined // (except at initialization) int rank = C.Gauss(); int[][] cContent = C.Data; // can start at rank-1, because below that are all zeroes for (int row = rank - 1; row >= 0; row--) { // remove all the known variables from the equation temp = cContent[row][n]; int col; for (col = n - 1; col >= firstDeterminedValue; col--) { temp = Zp.Modulo(temp - (cContent[row][col] * solution[col]), prime); } // now we need to find the first nonzero coefficient in this row // if it exists before firstDeterminedValue // because the matrix is in row echelon form, the first nonzero // coefficient cannot be before the diagonal for (col = row; col < firstDeterminedValue; col++) { if (cContent[row][col] != 0) { break; } } if (col < firstDeterminedValue) // this means we found a nonzero coefficient { // we can determine the variables in position from col to firstDeterminedValue // if this loop executes even once, then the system is undertermined // we arbitrarily set the undetermined variables to 0, because it make math easier for (int j = col + 1; j < firstDeterminedValue; j++) { solution[j] = 0; } // Now determine the variable at the nonzero coefficient //div(solution[col], temp, A.getContent()[row][col]); solution[col] = temp * invArray[Zp.Modulo(cContent[row][col], prime)]; firstDeterminedValue = col; } else { // this means there are no nonzero coefficients before firstDeterminedValue. // Because we skip all the zero rows at the bottom, the matrix is in // row echelon form, and firstDeterminedValue is equal to the // position of first nonzero entry in row+1 (unless it is equal to n), // this means we are at a row with all zeroes except in column n // The system has no solution. return(null); } } // set the remaining undetermined values, if any, to 0 for (int col = 0; col < firstDeterminedValue; col++) { solution[col] = 0; } var ResultVec = new Zp[n]; for (int i = 0; i < n; i++) { ResultVec[i] = new Zp(prime, solution[i]); } return(ResultVec); }
void Solve() { ans = 0; edges = new int[26, 26]; for (int i = 0; i < n; ++i) { var letters = new List <char>(); for (int j = 0; j < s[i].Length;) { int k = j + 1; while (k < s[i].Length && s[i][k] == s[i][j]) { ++k; } letters.Add(s[i][j]); j = k; } if (letters.Distinct().Count() != letters.Count) { return; } if (letters.Count < 3) { edges[letters[0] - 'a', letters[letters.Count - 1] - 'a']++; } else { for (int j = 1; j < letters.Count - 1; ++j) { for (int l = 0; l < n; ++l) { if (l != i && s[l].IndexOf(letters[j]) >= 0) { return; } } } edges[letters[0] - 'a', letters[letters.Count - 1] - 'a']++; } } int[] to = new int[26]; int[] from = new int[26]; for (int i = 0; i < 26; ++i) { to[i] = -1; from[i] = -1; } for (int i = 0; i < 26; ++i) { for (int j = 0; j < 26; ++j) { if (i != j && edges[i, j] > 0) { if (to[i] != -1) { return; } to[i] = j; from[j] = i; } } if (to[i] != -1 && edges[i, to[i]] > 1) { return; } } int[] f = NumTheoryUtils.FactorialArray(1000, MOD); bool[] was = new bool[26]; int counted = 0; int curAns = 1; int chains = 0; for (int i = 0; i < 26; ++i) { if (from[i] == -1) { if (to[i] != -1 || edges[i, i] > 0) { ++chains; } int u = i; while (u != -1 && !was[u]) { was[u] = true; curAns = NumTheoryUtils.Mul(curAns, f[edges[u, u]], MOD); counted += edges[u, u] + (to[u] == -1 ? 0 : 1); u = to[u]; } if (u != -1) { ans = 0; return; } } } if (counted != n) { ans = 0; return; } curAns = NumTheoryUtils.Mul(curAns, f[chains], MOD); ans = curAns; }