ethereum / py_ecc

Python implementation of ECC pairing and bn_128 and bls12_381 curve operations
MIT License
191 stars 82 forks source link

Fails test vectors from hash_to_curve v7 #98

Closed paulmillr closed 4 years ago

paulmillr commented 4 years ago

See hash_to_curve spec version 7, specifically msg=abc.

Expected

It should produce (stripping hex to 4 chars):

u[0]    = 0a7d + I * 1630
u[1]    = 0a1c + I * 07aa
P.x     = 1953 + I * 0357
P.y     = 0882 + I * 0184

Actual

u0 and u1 are correct, everything else is not.

hash_to_curve u0=(0a7d...55f2 + 1630...b378×i), u1=(0a1c...f96b + 07aa...b788×i)
Q0 Point<x=0265...f2c4 + 1957...bd53×i, y=0824...2918 + 0d1a...9589×i>
Q1 Point<x=0368...80fe + 156d...19b1×i, y=0cda...087e + 0cc7...c12e×i>
R Point<x=07e2...67a9 + 04cf...29ec×i, y=13db...0fd6 + 12b9...364a×i>
Point<x=0a4a...ab29 + 073f...766e×i, y=0e92...6bd4 + 1695...13eb×i>

Test code

(copy-paste helper methods to hash_to_curve.py if you want to log u, Q, R)

from hashlib import sha256
import py_ecc
from py_ecc.bls.hash_to_curve import hash_to_G2

def fq_to_hex(fq):
    h = hex(fq)[2:].rjust(96, '0')
    return '{}...{}'.format(h[:4], h[-4:])
def fq2_to_hex(fq2):
    a, b = fq2.coeffs
    return '{} + {}×i'.format(*map(fq_to_hex, fq2.coeffs))
def point_3d_to_2d(P):
    z3inv = (P[2] ** 3).inv()
    return (P[0] * P[2] * z3inv, P[1] * z3inv)
def ppp(p): # pretty print point
    x, y = point_3d_to_2d(p)
    return 'Point<x={}, y={}>'.format(fq2_to_hex(x), fq2_to_hex(y))

msg = b'abc'
dst = b'BLS12381G2_XMD:SHA-256_SSWU_RO_TESTGEN'
print(ppp(hash_to_G2(msg, dst, sha256)))

cc @hwwhww @CarlBeek

hwwhww commented 4 years ago

Hi @paulmillr

afaik the msg = abc case is in our CI tests and it passed: https://github.com/ethereum/py_ecc/blob/d21bbb11d4e7514956810e6ce1cd443a8e8ee817/tests/bls/test_hash_to_curve.py#L70-L72

It seem that your point_3d_to_2d function is in Jacobian projective coordinates and the test vectors are in homogeneous projective coordinates.

Please let me know if I get it wrong or there's issue in py_ecc. :)

paulmillr commented 4 years ago

Thanks, that was unclear.