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 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
def mk_ecadd_data(p1, p2): if isinstance(p1[0], py_pairing.FQ): p1 = py_pairing.normalize(p1) p1 = (p1[0].n, p1[1].n) if isinstance(p2[0], py_pairing.FQ): p2 = py_pairing.normalize(p2) p2 = (p2[0].n, p2[1].n) return encode_int32(p1[0]) + encode_int32(p1[1]) + \ encode_int32(p2[0]) + encode_int32(p2[1])
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_ecadd(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_pairing FQ = py_pairing.FQ print('ecadd proc', msg.gas) if msg.gas < opcodes.GECADD: return 0, 0, [] x1 = msg.data.extract32(0) y1 = msg.data.extract32(32) x2 = msg.data.extract32(64) y2 = msg.data.extract32(96) p1 = validate_point(x1, y1) p2 = validate_point(x2, y2) if p1 is False or p2 is False: return 0, 0, [] o = py_pairing.normalize(py_pairing.add(p1, p2)) return 1, msg.gas - opcodes.GECADD, [ safe_ord(x) for x in (encode_int32(o[0].n) + encode_int32(o[1].n)) ]
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]) testout["ecadd_%r-%r_%r-%r_%d_%d" % (n1[0], n1[1], n2[0], n2[1], test[2], test[3])] = o1 o2["explanation"] = "Puts the points %r and %r into the ECADD precompile, truncating or expanding the input data to %d bytes. Gives the execution %d bytes" % ( n1, n2, test[3], test[2]) testout_filler["ecadd_%r-%r_%r-%r_%d_%d" % (n1[0], n1[1], n2[0], n2[1], test[2], test[3])] = o2 open('ecadd_tests.json', 'w').write(json.dumps(testout, indent=4)) open('ecadd_tests_filler.json', 'w').write(json.dumps(testout_filler, indent=4))
def mk_ecmul_data(p1, m): if isinstance(p1[0], py_pairing.FQ): p1 = py_pairing.normalize(p1) p1 = (p1[0].n, p1[1].n) return encode_int32(p1[0]) + encode_int32(p1[1]) + encode_int32(m)
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: tests.append((pt, m, g, 0)) tests.append((pt, m, g, 40)) testout = {} testout_filler = {} for test in tests: o1, o2 = mk_test(*test) n = py_pairing.normalize(test[0]) testout["ecmul_%r-%r_%d_%d_%d" % (n[0], n[1], test[1], test[2], test[3])] = o1 o2["explanation"] = "Puts the point %r and the factor %d into the ECMUL precompile, truncating or expanding the input data to %d bytes. Gives the execution %d bytes" % ( n, test[1], test[3], test[2]) testout_filler["ecmul_%r-%r_%d_%d_%d" % (n[0], n[1], test[1], test[2], test[3])] = o2 open('ecmul_tests.json', 'w').write(json.dumps(testout, indent=4)) open( 'ecmul_tests_filler.json', 'w').write( json.dumps( testout_filler, indent=4))