public void One_initializes() { Fp12 _ = Fp12.One; Assert.AreEqual(Fp6.One, _.A, "A"); Assert.AreEqual(Fp6.Zero, _.B, "B"); }
public void Zero_initializes() { Fp12 _ = Fp12.Zero; Assert.AreEqual(Fp6.Zero, _.A, "A"); Assert.AreEqual(Fp6.Zero, _.B, "B"); }
public void Cyclotomic_square_seems_fine() { // ReSharper disable once EqualExpressionComparison Fp12 cyclotomicSquare = Fp12.One.CyclotomicSquare(); Assert.AreEqual(Fp6.One, cyclotomicSquare.A, "A"); Assert.AreEqual(Fp6.Zero, cyclotomicSquare.B, "B"); }
public void Unitary_inverse_seems_fine() { // ReSharper disable once EqualExpressionComparison Fp6 oneOneOne = new Fp6(Fp2.One, Fp2.One, Fp2.One); Fp12 unitaryInverted = new Fp12(oneOneOne, oneOneOne).UnitaryInverse(); Assert.AreEqual(oneOneOne, unitaryInverted.A, "A"); Assert.AreEqual(oneOneOne.Negate(), unitaryInverted.B, "B"); }
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 TestFp12() { Fp12 x = new Fp12(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); Fp12 f = new Fp12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); Fp12 fpx = new Fp12(2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); Assert.Equal(fpx, x + f); Assert.Equal(Fp12.OneValue, f / f); Assert.Equal((Fp12.OneValue + x) / f, (Fp12.OneValue / f) + (x / f)); Assert.Equal((Fp12.OneValue + x) * f, (Fp12.OneValue * f) + (x * f)); }
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)); }