0

I'am trying to get a feel for Elliptic Curve Cryptography. I wrote a small Python program below to generate key material but I don't get the same result for y_squared and Q.y^2. I'am using the parameters from 256-Bit Random ECP Group (RFC 5903 page 4) and the implementation steps Key Pair Generation Using Extra Random Bits (NIST.SP.800-56Ar3 page 30).

# RFC 5903 256-Bit Random ECP Group page 4
# NIST.SP.800-56Ar3 Key Pair Generation Using Extra Random Bits page 30
import sympy
import os

s = 128
p = pow(2, 256) - pow(2, 224) + pow(2, 192) + pow(2, 96) - 1
group_prime = int.from_bytes(bytes.fromhex('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF'), byteorder='big')
assert p == group_prime

x, b = sympy.symbols('x, b')
ecurve = x**3 - 3*x + b 

group_b = int.from_bytes(bytes.fromhex('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B'), byteorder='big')
group_order = int.from_bytes(bytes.fromhex('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551'), byteorder='big')
gx = int.from_bytes(bytes.fromhex('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296'), byteorder='big')
gy = int.from_bytes(bytes.fromhex('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5'), byteorder='big')

L = group_order.bit_length() + 64
c = int.from_bytes(os.urandom(max(s, L) // 8))

assert c > 0 and c < (pow(2, max(s, L)) - 1)

d = (c % (group_order - 1)) + 1
Q = (d*gx, d*gy)
y_squared = pow(Q[1], 2, group_prime)
print(f"y_squared: {y_squared}")
print(f"Q.y^2: {ecurve.subs([(x, Q[0]),(b, group_b)]) % group_prime}")
pppery
  • 3,731
  • 22
  • 33
  • 46
Mehkir
  • 11
  • 5
  • In addition to what I wrote in my answer below - how do you figure that you should get the same result for `y_squared` and `Q.y^2`? It's hard to imagine how these could be the same, as `y_squared` would be a scalar, and `Q.y^2` would be a point on the EC curve. – mti2935 Jun 23 '23 at 12:56
  • `Q.y^2` may be a bad naming. It indicates in my case the y-coordinate as a result from the equation I perform in that line. – Mehkir Jun 23 '23 at 15:28

1 Answers1

1

I believe the problem may be related (at least in part) to this line from your script:

Q = (d*gx, d*gy)

It seems that the intention here is to implement step 7 of the process that you referenced from NIST.SP.800-56Ar3 page 30, which is:

Q = dG

Note here that G is a point on an elliptic curve, and d is a scalar. So, this is elliptic curve multiplication. EC multiplication is not as simple as simply multiplying d by gx and gy respectively.

See this blog post by Andrea Corbellini for a good write-up of how EC math (including EC multiplication) works. The author also has some useful python scripts on Github that implement the methods described in the blog post.

mti2935
  • 11,465
  • 3
  • 29
  • 33
  • Thank you for clarifying that EC multiplication is different from scalar multiplication with vectors and matrices. Now it works! – Mehkir Jun 23 '23 at 15:24