14

The generator point G in the secp256k1 curve used in Bitcoin is a known constant:

Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

How was this point determined or chosen? I understand it needs to be a point with large order (which is the case for G) but other than that, was it chosen randomly or is it somehow derived deterministically?

2

2 Answers 2

28

We don't know. The secp256k1 curve (and the corresponding generator) was defined and standardized by people at Certicom. I know people have inquired about its origins, but it appears those involved are simply not around anymore.

There is however an unsual property that may give a hint about how it was constructed. If the point is multiplied by the multiplicative inverse of 2 (so effectively undoing a doubling operation), one gets the point with X coordinate 0x3b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63, an unfathomably small number (only 166 bits in size). Perhaps the generator was constructed by hashing some simple input, feeding it through a 160-bit hash function, prefixing it with 0x3b, constructing the point with the result as X coordinate, and then doubling it.

That said, it is believed that the choice of generator is irrelevant for security properties of schemes that only use one generator (like ECDSA, BIP340 Schnorr signatures, ECDH, ...).

0
12

As Pieter already described in his answer it is not known why the multiplicative inverse of 2 of the generator point of secp256k1 is such a short (166 bit) number.

But interestingly all prime order koblitz curves of the SEC 2 family (secp160k1, secp192k1, secp224k1, secp256k1) share this unusual property.

Moreover all these short x-coordinates of these source points share a significant amount of their bits (152 bits for all these x-values are the same):

secp160k1:         0x4_8ce563f89a0ed9414f5aa28ad0d96d6795f9c6_2
secp192k1:  0x554123b7_8ce563f89a0ed9414f5aa28ad0d96d6795f9c6_6
secp224k1:       0x3b7_8ce563f89a0ed9414f5aa28ad0d96d6795f9c6_3
secp256k1:       0x3b7_8ce563f89a0ed9414f5aa28ad0d96d6795f9c6_3

(I inserted the _ to visualize the identical part in the numbers.)

So maybe back in the 90s someone at Certicom hashed something into a 160 bit hash and then decided to replace the first and the last 4 bits per curve (and added a prefix value for 3 of them)?

Who knows? It's an interesting mystery. :)

I can highly recommend this short talk from Nadia Heninger about this topic: https://www.youtube.com/watch?v=NGLR2N4EK58

Edit:

To verify this yourself in Sage (example for secp192k1, simply change curve parameters for the other secp...k1 curves):

# define the curve from parameters
sage: prime_p = ZZ('0xfffffffffffffffffffffffffffffffffffffffeffffee37')
sage: a = 0
sage: b = 3

sage: secp192k1 = EllipticCurve( GF(prime_p), [a, b] )
sage: order_n = secp192k1.order()  # get order of the curve

# generator point G
sage: G = secp192k1.point(('0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d' , '0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d'))

# multiply with multiplicative inverse of 2:
sage: Point_half_G_mod_n = G *  ZZ( 1 / GF(order_n)(2) )

# print coordinates in hex:
sage: 'x: %x, y: %x'  %( Point_half_G_mod_n.xy() )
'x: 554123b78ce563f89a0ed9414f5aa28ad0d96d6795f9c66, y: 90755fc93ea4b13027fc6c8f337d92c6d00090fad0e8b2c6'
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.