def mk_test(p1, m, execgas, datarestrict=96): encoded = mk_ecmul_data(p1, m)[:datarestrict] + \ b'\x00' * max(datarestrict - 96, 0) pre = tester.mk_state_test_prefill(c) try: o = x1.foo( encoded, startgas=21000 + intrinsic_gas_of_data( x1.translator.encode( 'foo', [encoded])) + execgas) x, y = big_endian_to_int(o[:32]), big_endian_to_int(o[32:]) if py_pairing.normalize(py_pairing.multiply(p1, m)) != ( py_pairing.FQ(x), py_pairing.FQ(y)): raise Exception("Mismatch! %r %r %d, expected %r computed %r" % (p1, m, datarestrict, py_pairing.normalize(py_pairing.multiply(p1, m)), (x, y))) print('Succeeded! %r %d %d %r' % (p1, m, datarestrict, (x, y))) except tester.TransactionFailed: print('OOG %r %d %d %d' % (p1, m, datarestrict, execgas)) o = tester.mk_state_test_postfill(c, pre) o2 = tester.mk_state_test_postfill(c, pre, filler_mode=True) assert new_statetest_utils.verify_state_test(o) return o, o2
def proc_ecmul(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_pairing FQ = py_pairing.FQ print('ecmul proc', msg.gas) if msg.gas < opcodes.GECMUL: return 0, 0, [] x = msg.data.extract32(0) y = msg.data.extract32(32) m = msg.data.extract32(64) p = validate_point(x, y) if p is False: return 0, 0, [] o = py_pairing.normalize(py_pairing.multiply(p, m)) return (1, msg.gas - opcodes.GECMUL, [ safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n)) ])
def proc_ecpairing(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_pairing FQ = py_pairing.FQ print('pairing proc', msg.gas) # Data must be an exact multiple of 192 byte if msg.data.size % 192: return 0, 0, [] gascost = opcodes.GPAIRINGBASE + msg.data.size // 192 * opcodes.GPAIRINGPERPOINT if msg.gas < gascost: return 0, 0, [] zero = (py_pairing.FQ2.one(), py_pairing.FQ2.one(), py_pairing.FQ2.zero()) exponent = py_pairing.FQ12.one() for i in range(0, msg.data.size, 192): x1 = msg.data.extract32(i) y1 = msg.data.extract32(i + 32) x2_i = msg.data.extract32(i + 64) x2_r = msg.data.extract32(i + 96) y2_i = msg.data.extract32(i + 128) y2_r = msg.data.extract32(i + 160) p1 = validate_point(x1, y1) if p1 is False: return 0, 0, [] for v in (x2_i, x2_r, y2_i, y2_r): if v >= py_pairing.field_modulus: return 0, 0, [] fq2_x = py_pairing.FQ2([x2_r, x2_i]) fq2_y = py_pairing.FQ2([y2_r, y2_i]) if (fq2_x, fq2_y) != (py_pairing.FQ2.zero(), py_pairing.FQ2.zero()): p2 = (fq2_x, fq2_y, py_pairing.FQ2.one()) if not py_pairing.is_on_curve(p2, py_pairing.b2): return 0, 0, [] else: p2 = zero if py_pairing.multiply( p2, py_pairing.curve_order)[-1] != py_pairing.FQ2.zero(): return 0, 0, [] exponent *= py_pairing.pairing(p2, p1, final_exponentiate=False) result = py_pairing.final_exponentiate(exponent) == py_pairing.FQ12.one() return 1, msg.gas - gascost, [0] * 31 + [1 if result else 0]
tests = [] for g in gaslimits: tests.append((zero, zero, g, 128)) tests.append((zero, zero, g, 64)) tests.append((zero, zero, g, 80)) tests.append((zero, zero, g, 0)) tests.append((zero, zero, g, 192)) tests.append((zero, py_pairing.G1, g, 128)) tests.append((zero, py_pairing.G1, g, 192)) tests.append((py_pairing.G1, zero, g, 64)) tests.append((py_pairing.G1, zero, g, 128)) tests.append((py_pairing.G1, zero, g, 192)) tests.append((py_pairing.G1, py_pairing.G1, g, 128)) tests.append((py_pairing.G1, py_pairing.G1, g, 192)) tests.append((py_pairing.multiply(py_pairing.G1, 5), py_pairing.multiply(py_pairing.G1, 9), g, 128)) tests.append((py_pairing.multiply(py_pairing.G1, 5), py_pairing.multiply(py_pairing.G1, py_pairing.curve_order - 5), g, 192)) tests.append((zero, wrong1, g, 128)) tests.append((wrong1, zero, g, 80)) tests.append((wrong2, py_pairing.G1, g, 128)) tests.append((wrong3, wrong4, g, 128)) testout = {} testout_filler = {} for test in tests: o1, o2 = mk_test(*test) n1, n2 = py_pairing.normalize(test[0]), py_pairing.normalize(test[1])
x1 = c.contract(kode, language='viper') # Generate a point on the G2 curve, but not in the correct subgroup fake_point = None FQ2_one = py_pairing.FQ2.one() big_order = py_pairing.curve_order * \ (py_pairing.field_modulus * 2 - py_pairing.curve_order) G1_zero = (py_pairing.FQ.one(), py_pairing.FQ.one(), py_pairing.FQ.zero()) G2_zero = (FQ2_one, FQ2_one, py_pairing.FQ2.zero()) for i in range(200): x = py_pairing.FQ2([8, i]) ysquared = x**3 + py_pairing.b2 y = ysquared**((py_pairing.field_modulus**2 + 15) // 32) if y**2 == ysquared: assert py_pairing.multiply((x, y, FQ2_one), big_order) == G2_zero assert py_pairing.multiply( (x, y, FQ2_one), py_pairing.curve_order) != G2_zero fake_point = (x, y, FQ2_one) break def mk_ecpairing_data(pts): o = b'' for p, q in pts: np, nq = py_pairing.normalize(p), py_pairing.normalize(q) o += encode_int32(np[0].n) + encode_int32(np[1].n) + \ encode_int32(nq[0].coeffs[1]) + encode_int32(nq[0].coeffs[0]) + \ encode_int32(nq[1].coeffs[1]) + encode_int32(nq[1].coeffs[0]) return o
mults = [ 0, 1, 2, 9, 2**128, py_pairing.curve_order - 1, py_pairing.curve_order, 2**256 - 1] pts = [ zero, py_pairing.G1, py_pairing.multiply( py_pairing.G1, 98723629835235), wrong1, wrong2] tests = [] for g in gaslimits: for m in mults: for pt in pts: tests.append((pt, m, g, 96)) tests.append((pt, m, g, 128)) if m == 0: tests.append((pt, m, g, 64)) if not m % 2**128: tests.append((pt, m, g, 80)) if m == 0 and pt == zero: