Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Regarding, RFC 7748, Section 5.2, X448, second vector, the given input
- # u-coordinate is not part of a valid point on the Montgomery form of Curve448.
- # I suggest replacing the point with a valid one: (2^447 + 100)*G
- # Execute at: https://sagecell.sagemath.org/
- # Curve448 parameters, as per RFC 7748, Section 4.2
- # Galois Field
- F = GF(2^448 - 2^224 - 1)
- # Montgomery form parameters
- A = 156326
- B = 1
- # --- AUXILIARY FUNCTIONS ---
- def is_valid_point(u):
- # Check if the point satisfies the curve equation v^2 = u^3 + Au^2 + u in the field F
- u3_plus_Au2_plus_u = u^3 + A*u^2 + u
- # Check if this is a quadratic residue in F, meaning there exists a v^2
- return u3_plus_Au2_plus_u.is_square()
- rawslicer = lambda x, k : [x[k*i:k*(i+1)] for i in range(len(x)//k)]
- stringslicer = lambda x, k : ''.join(rawslicer(x, k))
- little2big = lambda x : stringslicer(x, 2)
- def little(x):
- if len(x) % 2: x = '0' + x
- return ''.join(rawslicer(x, 2)[::-1])
- def fixscalar(d):
- d >>= 2
- d <<= 2
- d |= 1 << 447
- return d
- # Generator's u-coordinate
- G = F(5)
- # First test vector, from Section 5.2, X448
- FIRST = F(382239910814107330116229961234899377031416365240571325148346555922438025162094455820962429142971339584360034337310079791515452463053830)
- FIRSTSCALAR = F(fixscalar(599189175373896402783756016145213256157230856085026129926891459468622403380588640249457727683869421921443004045221642549886377526240828))
- FIRSTOUTPUT = 'ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f'
- FIRSTOUTPUT = int.from_bytes(bytes.fromhex(FIRSTOUTPUT), byteorder='little')
- # Second test vector
- SECOND = F(622761797758325444462922068431234180649590390024811299761625153767228042600197997696167956134770744996690267634159427999832340166786063)
- SECONDSCALAR = F(fixscalar(633254335906970592779259481534862372382525155252028961056404001332122152890562527156973881968934311400345568203929409663925541994577184))
- # Prove my point
- assert is_valid_point(G)
- assert is_valid_point(FIRST)
- assert not is_valid_point(SECOND)
- # Curve implementation
- ec = EllipticCurve(F, [0,A,0,B,0])
- assert (FIRSTSCALAR * ec.lift_x(FIRST))[0] == FIRSTOUTPUT
- # Proposed point
- PROPOSED = fixscalar(100) * ec.lift_x(G)
- PROPOSED = PROPOSED[0] # Get only u
- assert is_valid_point(PROPOSED)
- # Proposed output, keeping the same d
- out = SECONDSCALAR * ec.lift_x(PROPOSED)
- out = out[0] # Only u
- # Encodings
- stru = str(PROPOSED)
- hexu = little(hex(PROPOSED)[2:])
- hexout = little(hex(out)[2:])
- # Just in case
- assert (SECONDSCALAR * ec.lift_x(PROPOSED))[0] == out
- assert int.from_bytes(bytes.fromhex(hexu), byteorder='little') == PROPOSED
- assert int.from_bytes(bytes.fromhex(hexout), byteorder='little') == out
- print(' Input u-coordinate:')
- print(' '+'\n '.join(rawslicer(hexu, len(hexu)//2)))
- print(' Input u-coordinate as a number (base 10):')
- print(' '+'\n '.join(rawslicer(stru, len(stru)//3)))
- print(' Output u-coordinate:')
- print(' '+'\n '.join(rawslicer(hexout, len(hexout)//2)))
Advertisement
Add Comment
Please, Sign In to add comment