public void TestSimpleArithmetic() { for (var i = -100; i <= 100; ++i) { var x = GT.FromInt(i); Assert.AreEqual(GT.FromInt(-i), -x); for (var j = -100; j <= 100; ++j) { var y = GT.FromInt(j); Assert.AreEqual(GT.FromInt(i + j), x + y); Assert.AreEqual(GT.FromInt(i * j), x * y); Assert.AreEqual(GT.FromInt(i - j), x - y); if (j == 0) { Assert.Throws <InvalidOperationException>(() => { var unused = x * y / y; }); } else { Assert.AreEqual(GT.FromInt(i * j / j), x * y / y); } if (j > 0 && i >= -8 && i <= 8 && j <= 8) { Assert.AreEqual(GT.FromInt((int)Math.Pow(i, j)), GT.Pow(x, Fr.FromInt(j))); } } } }
public void TestPowersCalculation() { var powers = Enumerable.Range(0, 30) .Select(i => Fr.FromInt(1 << i)) .ToArray(); CollectionAssert.AreEqual(powers, MclBls12381.Powers(Fr.FromInt(2), 30)); }
public IEnumerable <PrivateKeyShare> GetPrivateShares() { var shares = new Fr[_parties]; for (var i = 0; i < _parties; ++i) { shares[i] = MclBls12381.EvaluatePolynomial(_coeffs, Fr.FromInt(i + 1)); } return(shares.Select(share => new PrivateKeyShare(share))); }
public void EvalFrPolyConstantTest() { var poly = new Fr[] { Fr.GetRandom() }; var v0 = MclBls12381.EvaluatePolynomial(poly, Fr.Zero); var v1 = MclBls12381.EvaluatePolynomial(poly, Fr.One); var v2 = MclBls12381.EvaluatePolynomial(poly, Fr.FromInt(319948)); Assert.AreEqual(poly[0], v0); Assert.AreEqual(poly[0], v1); Assert.AreEqual(poly[0], v2); }
public Signature AssembleSignature(IEnumerable <KeyValuePair <int, Signature> > shares) { var keyValuePairs = shares as KeyValuePair <int, Signature>[] ?? shares.ToArray(); var xs = keyValuePairs.Take(Threshold + 1).Select(pair => Fr.FromInt(pair.Key + 1)).ToArray(); var ys = keyValuePairs.Take(Threshold + 1).Select(pair => pair.Value.RawSignature).ToArray(); if (xs.Length <= Threshold || ys.Length <= Threshold) { throw new ArgumentException("not enough shares for signature"); } return(new Signature(MclBls12381.LagrangeInterpolate(xs, ys))); }
public void TestSimpleArithmetic() { for (var i = -100; i <= 100; ++i) { var x = G2.Generator * Fr.FromInt(i); Assert.AreEqual(G2.Generator * Fr.FromInt(-i), -x); for (var j = -100; j <= 100; ++j) { var y = G2.Generator * Fr.FromInt(j); Assert.AreEqual(G2.Generator * Fr.FromInt(i + j), x + y); Assert.AreEqual(G2.Generator * Fr.FromInt(i - j), x - y); Assert.AreEqual(G2.Generator * Fr.FromInt(i * j), x * Fr.FromInt(j)); } } }
public G1 Evaluate(int x, int y) { var result = G1.Zero; var powX = MclBls12381.Powers(Fr.FromInt(x), Degree + 1); var powY = MclBls12381.Powers(Fr.FromInt(y), Degree + 1); for (var i = 0; i <= Degree; ++i) { for (var j = 0; j <= Degree; ++j) { result += _coefficients[Index(i, j)] * powX[i] * powY[j]; } } return(result); }
public void TestGenerator() { Assert.IsTrue(G2.Generator.IsValid()); Assert.IsFalse(G2.Generator.IsZero()); Assert.AreEqual(G2.Generator, G2.Generator); Assert.AreNotEqual(G2.Zero, G2.Generator); // TODO: WTF? Assert.IsTrue(G2.Zero != G2.Generator); Assert.AreNotEqual(G2.Generator, G2.Generator * Fr.FromInt(2)); Assert.AreEqual(G2.Generator - G2.Generator, G2.Zero); Assert.AreEqual(G2.Generator.Double(), G2.Generator + G2.Generator); Assert.AreEqual(G2.Generator.Double(), G2.Generator * Fr.FromInt(2)); Assert.AreEqual( "G2(f1437606f337b000f00d69507434dbbd3b2abfa8a291d88551d92309fe3c222e0790fc847e849eb984bb807cba59170a0a63480e9457a375705ea2aba224a711e717ecddb224feeb738630945581bda24389f8fecf7865724361aec550e44919)", G2.Generator.ToString() ); Assert.AreNotEqual(G1.Generator, G2.Generator); }
public void TestGenerator() { Assert.IsTrue(G1.Generator.IsValid()); Assert.IsFalse(G1.Generator.IsZero()); Assert.AreEqual(G1.Generator, G1.Generator); Assert.AreNotEqual(G1.Zero, G1.Generator); Assert.AreNotEqual(G1.Generator, G1.Generator * Fr.FromInt(2)); Assert.IsTrue(G1.Zero != G1.Generator); Assert.AreEqual(G1.Generator - G1.Generator, G1.Zero); Assert.AreEqual(G1.Generator.Double(), G1.Generator + G1.Generator); Assert.AreEqual(G1.Generator.Double(), G1.Generator * Fr.FromInt(2)); Assert.AreEqual( "G1(e9328f8eb8185341f22adaf2bf41f66258d97b2b5b2dbd2c27a77c81d9b5d76dd119bf7b1cd5d57b1273f9c4a654540e)", G1.Generator.ToString() ); Assert.AreNotEqual(G1.Generator, G2.Generator); }
public IEnumerable <Fr> Evaluate(int x) { var row = Enumerable.Range(0, _degree + 1).Select(_ => Fr.Zero).ToArray(); var frX = Fr.FromInt(x); for (var i = 0; i <= _degree; ++i) { var xPowJ = Fr.One; for (var j = 0; j <= _degree; ++j) { row[i] += _coefficients[Index(i, j)] * xPowJ; xPowJ *= frX; } } return(row); }
public void TestPolyInterpolationG2() { const int degree = 100; var coeffs = Enumerable.Range(0, degree) .Select(i => G2.Generator * Fr.GetRandom()) .ToArray(); var xs = Enumerable.Range(1, degree) .Select(i => Fr.GetRandom()) .ToArray(); var ys = xs .Select(x => MclBls12381.EvaluatePolynomial(coeffs, x)) .ToArray(); var intercept = MclBls12381.EvaluatePolynomial(coeffs, Fr.FromInt(0)); Assert.AreEqual(intercept, MclBls12381.LagrangeInterpolate(xs, ys)); Assert.Throws <ArgumentException>(() => MclBls12381.LagrangeInterpolate(xs, ys.Take(degree - 1).ToArray())); }
public void Test_Mcl_Serializations() { Assert.AreEqual( "0x0000000000000000000000000000000000000000000000000000000000000000", Fr.FromInt(0).ToHex() ); Assert.AreEqual( "0x0100000000000000000000000000000000000000000000000000000000000000", Fr.FromInt(1).ToHex() ); var fr = Fr.GetRandom(); Assert.AreEqual(fr, Fr.FromBytes(fr.ToBytes())); Assert.AreEqual( "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", G1.Zero.ToHex() ); Assert.AreEqual( "0xe9328f8eb8185341f22adaf2bf41f66258d97b2b5b2dbd2c27a77c81d9b5d76dd119bf7b1cd5d57b1273f9c4a654540e", G1.Generator.ToHex() ); Assert.AreEqual( "0x2ac325b200d53184871fb8f8f5e5e43b302349ae6172de2899e88d2961f0bd2593b427667f5f85b4b59296ae8dcfc918", (G1.Generator * Fr.FromInt(2)).ToHex() ); var g1 = G1.Generator * Fr.GetRandom(); Assert.AreEqual(g1, G1.FromBytes(g1.ToBytes())); Assert.AreEqual( "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", G2.Zero.ToHex() ); Assert.AreEqual( "0xf1437606f337b000f00d69507434dbbd3b2abfa8a291d88551d92309fe3c222e0790fc847e849eb984bb807cba59170a0a63480e9457a375705ea2aba224a711e717ecddb224feeb738630945581bda24389f8fecf7865724361aec550e44919", G2.Generator.ToHex() ); Assert.AreEqual( "0xd63f18cd560a715faef9b96c31e08eead86809ffd81642f6cdb55ed88ea2eca32cb2a28d818b7887cb35f1a7d4ab8a04eacc640851cb34b8a615729cd6d8cc4317125959b2012444b435508679e0a2f07d691d91aef2a18400a6696c6a3ae18d", (G2.Generator * Fr.FromInt(2)).ToHex() ); }
public void EvalInterpolateTestFr() { const int n = 10; var poly = Enumerable.Range(0, n).Select(_ => Fr.GetRandom()).ToArray(); var values = Enumerable.Range(100, n + 1) .Select(i => MclBls12381.EvaluatePolynomial(poly, Fr.FromInt(i))) .ToArray(); for (var i = 0; i < n + 1; ++i) { Assert.AreEqual(DummyEval(poly, Fr.FromInt(100 + i)), values[i]); } var intercept = MclBls12381.LagrangeInterpolate( Enumerable.Range(100, n + 1).Select(Fr.FromInt).ToArray(), values ); Assert.AreEqual(poly[0], intercept); }
public void TestSimpleArithmetic() { for (var i = -100; i <= 100; ++i) { var x = Fr.FromInt(i); Assert.AreEqual(Fr.FromInt(-i), -x); Assert.AreEqual(Fr.FromInt(i * i), x.Square()); for (var j = -100; j <= 100; ++j) { var y = Fr.FromInt(j); Assert.AreEqual(Fr.FromInt(i + j), x + y); Assert.AreEqual(Fr.FromInt(i * j), x * y); Assert.AreEqual(Fr.FromInt(i - j), x - y); Assert.AreEqual( j != 0 ? Fr.FromInt(i * j / j) : Fr.FromInt(0), x * y / y ); } } }
public ThresholdKeyring?TryGetKeys() { if (!Finished()) { return(null); } var pubKeyPoly = Enumerable.Range(0, Faulty + 1) .Select(_ => G1.Zero) .ToArray(); var secretKey = Fr.Zero; foreach (var dealer in _finished.Take(Faulty + 1)) { var s = _keyGenStates[dealer]; if (s.ValueCount() <= 2 * Faulty) { throw new Exception("Impossible"); // just in case } var rowZero = s.Commitment !.Evaluate(0).ToArray(); foreach (var(x, i) in rowZero.WithIndex()) { pubKeyPoly[i] += x; } secretKey += s.InterpolateValues(); } var pubKeys = Enumerable.Range(0, Players + 1) .Select(i => MclBls12381.EvaluatePolynomial(pubKeyPoly, Fr.FromInt(i))) .ToArray(); return(new ThresholdKeyring { TpkePrivateKey = new PrivateKey(secretKey, _myIdx), TpkePublicKey = new PublicKey(pubKeys[0], Faulty), ThresholdSignaturePrivateKey = new PrivateKeyShare(secretKey), ThresholdSignaturePublicKeySet = new PublicKeySet(pubKeys.Skip(1).Select(x => new Crypto.ThresholdSignature.PublicKey(x)), Faulty) }); }
public void TestZero() { Assert.IsTrue(Fr.Zero.IsValid()); Assert.IsTrue(Fr.Zero.IsZero()); Assert.IsFalse(Fr.Zero.IsOne()); Assert.AreEqual(Fr.Zero, Fr.Zero); Assert.AreEqual(Fr.Zero, Fr.FromInt(0)); Assert.AreNotEqual(Fr.Zero, Fr.One); Assert.IsTrue(Fr.Zero != Fr.One); Assert.AreEqual(Fr.Zero + Fr.Zero, Fr.Zero); var rnd = Fr.GetRandom(); Assert.AreEqual(Fr.Zero + rnd, rnd); Assert.AreEqual(rnd + Fr.Zero, rnd); Assert.AreEqual(Fr.Zero * rnd, Fr.Zero); Assert.AreEqual(rnd * Fr.Zero, Fr.Zero); Assert.AreEqual(Fr.Zero, Fr.Zero.Inverse()); // NB Assert.AreEqual( "Fr(0000000000000000000000000000000000000000000000000000000000000000)", Fr.Zero.ToString() ); Assert.AreNotEqual(Fr.Zero, G1.Zero); Assert.AreNotEqual(Fr.Zero, G2.Zero); }
public RawShare FullDecrypt(EncryptedShare share, List <PartiallyDecryptedShare> us) { return(FullDecryptBenchmark.Benchmark(() => { if (us.Count < _t) { throw new Exception("Insufficient number of shares!"); } var ids = new HashSet <int>(); foreach (var part in us) { if (ids.Contains(part.DecryptorId)) { throw new Exception($"Id {part.DecryptorId} was provided more than once!"); } if (part.ShareId != share.Id) { throw new Exception($"Share id mismatch for decryptor {part.DecryptorId}"); } ids.Add(part.DecryptorId); } var ys = new List <G1>(); var xs = new List <Fr>(); foreach (var part in us) { xs.Add(Fr.FromInt(part.DecryptorId + 1)); ys.Add(part.Ui); } var u = MclBls12381.LagrangeInterpolate(xs.ToArray(), ys.ToArray()); return new RawShare(Utils.XorWithHash(u, share.V), share.Id); })); }
private static Fr Eval(BiVarSymmetricPolynomial p, int x, int y) { var t = p.Evaluate(x).ToArray(); return(MclBls12381.EvaluatePolynomial(t, Fr.FromInt(y))); }
public PrivateKey GetPrivKey(int i) { return(new PrivateKey(MclBls12381.EvaluatePolynomial(_coeffs, Fr.FromInt(i + 1)), i)); }
public PublicKey GetPubKey() { return(new PublicKey(G1.Generator * MclBls12381.EvaluatePolynomial(_coeffs, Fr.FromInt(0)), _degree)); }
public ValueMessage HandleCommit(int sender, CommitMessage message) { if (message.EncryptedRows.Length != Players) { throw new ArgumentException(); } if (_keyGenStates[sender].Commitment != null) { throw new ArgumentException($"Double commit from sender {sender}"); } _keyGenStates[sender].Commitment = message.Commitment; var myRowCommitted = message.Commitment.Evaluate(_myIdx + 1); var myRow = DecryptRow(message.EncryptedRows[_myIdx], _keyPair.PrivateKey).ToArray(); if (!myRow.Select(x => G1.Generator * x).SequenceEqual(myRowCommitted)) { throw new ArgumentException("Commitment does not match"); } return(new ValueMessage { Proposer = sender, EncryptedValues = Enumerable.Range(0, Players).Select(i => Crypto.Secp256K1Encrypt( _publicKeys[i].EncodeCompressed(), MclBls12381.EvaluatePolynomial(myRow, Fr.FromInt(i + 1)).ToBytes() )).ToArray() }); }