public void Square_seems_fine() { Fp2 result = Fp2.One.Squared(); Assert.AreEqual((Fp)1, result.A); Assert.AreEqual((Fp)0, result.B); }
public void Double_seems_fine() { Fp2 result = Fp2.NonResidue.Double(); Assert.AreEqual((Fp)18, result.A); Assert.AreEqual((Fp)2, result.B); }
public void FrobeniusMap_seems_fine() { Fp2 result = Fp2.NonResidue.FrobeniusMap(2); Assert.AreEqual((Fp)9, result.A); Assert.AreEqual((Fp)1, result.B); }
public void Inverse_seems_fine() { Fp2 result = Fp2.One.Inverse(); Assert.AreEqual((Fp)1, result.A); Assert.AreEqual((Fp)0, result.B); }
public void Negate_seems_fine() { Fp2 result = Fp2.NonResidue.Negate(); Assert.AreEqual((Fp)(Parameters.P - 9), result.A); Assert.AreEqual((Fp)(Parameters.P - 1), result.B); }
public void Mul_karatsuba_check() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp2 b = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.AreEqual(a.Mul(b), a.MulKaratsuba(b)); }
public void Sub_seems_fine() { Fp2 result = Fp2.NonResidue.Sub(Fp2.NonResidue); Assert.AreEqual((Fp)0, result.A); Assert.AreEqual((Fp)0, result.B); }
public void Add_seems_fine() { Fp2 result = Fp2.One.Add(Fp2.NonResidue); Assert.AreEqual((Fp)10, result.A); Assert.AreEqual((Fp)1, result.B); }
public void Inverse_mul_self() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.AreEqual(Fp2.One, a.Mul(a.Inverse())); Assert.AreEqual(Fp2.One, a.Inverse().Mul(a)); }
public void Zero_initializes() { Fp2 _ = Fp2.Zero; Assert.True(_.A.Equals(Fp.Zero)); Assert.True(_.B.Equals(Fp.Zero)); }
public void One_initializes() { Fp2 _ = Fp2.One; Assert.True(_.A.Equals(Fp.One)); Assert.True(_.B.Equals(Fp.Zero)); }
public void Mul_schoolbook_check() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp2 b = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.AreEqual(a.Mul(b), a.MulSchoolbook(b)); }
public void MulByNonResidue_seems_fine() { Fp2 result = Fp2.One.MulByNonResidue(); Assert.AreEqual((Fp)9, result.A); Assert.AreEqual((Fp)1, result.B); }
public void Double_cross_check() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); a.IsValid(); Assert.AreEqual(a.Double(), a.Add(a)); }
public void Square_cross_check() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); a.IsValid(); Assert.AreEqual(a.Squared(), a.Mul(a)); }
public void All_constructors_are_fine() { Fp2 a = new Fp2(1, 0); Fp2 b = new Fp2(new byte[] { 1 }, new byte[] { 0 }); Assert.AreEqual(a, Fp2.One); Assert.AreEqual(b, Fp2.One); }
public void Inverse_mul_self() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a = new Fp6(a2, a2, a2); Assert.True(a.IsValid()); Assert.AreEqual(Fp6.One, a.Mul(a.Inverse())); }
public void Negate_negate() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a = new Fp6(a2, a2, a2); Assert.True(a.IsValid()); Assert.AreEqual(a, a.Negate().Negate()); }
public void Add_negate() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.True(a.IsValid()); Assert.AreEqual(Fp2.Zero, a.Add(a.Negate())); Assert.AreEqual(Fp2.Zero, a.Negate().Add(a)); }
public void Square_cross_check() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a = new Fp6(a2, a2, a2); Assert.True(a.IsValid()); Assert.AreEqual(a.Squared(), a.Mul(a)); }
public void Double_cross_check() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a = new Fp6(a2, a2, a2); Assert.True(a.IsValid()); Assert.AreEqual(a.Double(), a.Add(a)); }
public void Inverse_inverse() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a = new Fp6(a2, a2, a2); Assert.True(a.IsValid()); Assert.AreEqual(a, a.Inverse().Inverse()); }
public void Square_cross_check() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a6 = new Fp6(a2, a2, a2); Fp12 a12 = new Fp12(a6, a6); Assert.True(a12.IsValid()); Assert.AreEqual(a12.Squared(), a12.Mul(a12)); }
public void Inverse_mul_self_is_commutative_regression() { Fp2 a2 = new Fp2(Parameters.P / 2, Parameters.P / 4); Fp6 a = new Fp6(a2, a2, a2); Assert.True(a.IsValid()); Fp6 inv = a.Inverse(); Assert.AreEqual(a.Mul(inv), inv.Mul(a)); }
public void TestFp2() { Fp2 x = new Fp2(1, 0); Fp2 f = new Fp2(1, 2); Fp2 fpx = new Fp2(2, 2); Assert.Equal(fpx, x + f); Assert.Equal(Fp2.OneValue, f / f); Assert.Equal((Fp2.OneValue + x) / f, (Fp2.OneValue / f) + (x / f)); Assert.Equal((Fp2.OneValue + x) * f, (Fp2.OneValue * f) + (x * f)); }
public void Squared_complex_check() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.AreEqual(a.Squared(), a.SquaredComplex()); }
public void NonResidue_intiializes() { Fp2 _ = Fp2.NonResidue; }
public void Inverse_inverse() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.AreEqual(a, a.Inverse().Inverse()); }
public void Negate_negate() { Fp2 a = new Fp2(Parameters.P / 2, Parameters.P / 4); Assert.AreEqual(a, a.Negate().Negate()); }
private static EVMExecutionResult Precompile_ECPairing(MeadowEVM evm) { // Verify we're past the byzantium fork if (evm.Version < EthereumRelease.Byzantium) { return(new EVMExecutionResult(evm, null, true)); } const int PAIRING_SIZE_PER_POINT = 192; // Verify our messatge data is divisible by our size per point. if (evm.Message.Data.Length % PAIRING_SIZE_PER_POINT != 0) { throw new EVMException($"ECPairing precompile failed because the call data was not divisible by the size per point ({PAIRING_SIZE_PER_POINT})."); } // Charge the gas for the precompile operation before processing. BigInteger gasCharge = GasDefinitions.GAS_PRECOMPILE_ECPAIRING_BASE + ((evm.Message.Data.Length / PAIRING_SIZE_PER_POINT) * GasDefinitions.GAS_PRECOMPILE_ECPAIRING_PER_POINT); evm.GasState.Deduct(gasCharge); // Obtain a memory representation of our data. Span <byte> messageData = new Span <byte>(evm.Message.Data); // Define some constant variables for arithmetic. FpVector3 <Fp2> zero = new FpVector3 <Fp2>(Fp2.OneValue, Fp2.OneValue, Fp2.ZeroValue); Fp12 exponent = Fp12.OneValue; // Loop for each point in our data for (int i = 0; i < evm.Message.Data.Length; i += PAIRING_SIZE_PER_POINT) { // Obtain our component data BigInteger x1 = BigIntegerConverter.GetBigInteger(messageData.Slice(i + 0, EVMDefinitions.WORD_SIZE)); BigInteger y1 = BigIntegerConverter.GetBigInteger(messageData.Slice(i + 32, EVMDefinitions.WORD_SIZE)); BigInteger x2_i = BigIntegerConverter.GetBigInteger(messageData.Slice(i + 64, EVMDefinitions.WORD_SIZE)); BigInteger x2_r = BigIntegerConverter.GetBigInteger(messageData.Slice(i + 96, EVMDefinitions.WORD_SIZE)); BigInteger y2_i = BigIntegerConverter.GetBigInteger(messageData.Slice(i + 128, EVMDefinitions.WORD_SIZE)); BigInteger y2_r = BigIntegerConverter.GetBigInteger(messageData.Slice(i + 160, EVMDefinitions.WORD_SIZE)); // Parse and verify our point. FpVector3 <Fp> point1 = ParsePoint(x1, y1); if (point1 == null) { throw new EVMException("ECPairing precompile failed because point 1 was deemed invalid when parsing."); } // If our coordinates exceed our modulo divisor, they are invalid. if (x2_i >= Bn128Curve.P || x2_r >= Bn128Curve.P || y2_i >= Bn128Curve.P || y2_r >= Bn128Curve.P) { throw new EVMException("ECPairing precompile failed because point 2 was deemed invalid when parsing."); } Fp2 x2 = new Fp2(x2_r, x2_i); Fp2 y2 = new Fp2(y2_r, y2_i); FpVector3 <Fp2> point2 = null; if (x2 == Fp2.ZeroValue && y2 == Fp2.ZeroValue) { // Our point is the zero point. point2 = zero; } else { // Initialize our point from components. point2 = new FpVector3 <Fp2>(x2, y2, Fp2.OneValue); // Verify our desired point is on the curve if (!point2.IsOnCurveCheck(Bn128Curve.B2)) { throw new EVMException("ECPairing precompile failed because point 2 was not on the curve."); } } // Verify multiplying by the curve order is non-zero. if (point2.Multiply(Bn128Curve.N).Z != Fp2.ZeroValue) { throw new EVMException("ECPairing precompile failed because point 2 was deemed invalid. Points multiplied by the curve order should equal infinity (zero)."); } // Pair our points and multiply the exponent by them. exponent *= Bn128Pairing.Pair(point2, point1, false); } // Return our result bool returnStatus = Bn128Pairing.FinalExponentiate(exponent) == Fp12.OneValue; byte[] returnData = BigIntegerConverter.GetBytes(returnStatus ? 1 : 0, EVMDefinitions.WORD_SIZE); return(new EVMExecutionResult(evm, returnData, true)); }