0

I am using the pycryptodome package to implement a cryptographic voting protocol. I am using the Nist256 curve and would like to create a second generator, independent of the default generator i.e. not related to it by scalar multiplication.

The common way to do this is by the try-and-increment method (if there is another method which works with pycryptodome then please tell) which involves basically:

  1. Create some unique hash with context specific information and some padding. Treat this as the x coordinate of the generator.
  2. Find the equivalent y coordinate of the point using the curve equation
  3. If this point is on the curve, then bingo you've found a new generator. If this point is not on the curve, then increment the padding and go back to step 1.

The problem I have is that I cannot instantiate a pycryptodome EccPoint without knowledge of both the x and y coordinates. I cannot work out what the y coordinate is according to the curve equation because I cannot reproduce the curve equation with the parameters in the private EccCurve._curve attribute.

The _curve attribute contains p, b, order, the default generator and some other information. I cannot see how to reconstruct the curve equation from this information, is there a way to do this?

Perhaps there is a better way to go about doing this that I'm missing? Or maybe it just isn't possible to create a second independent generator using pycryptodome?

Many thanks in advance for any input.

TP0G
  • 1

1 Answers1

0

There are probably numerous packages that can do this, perhaps even pycryptodome. One relatively simple one this example uses is the ECpy package. Here is an example that is inspired by my understanding of your requirements. It uses a method of an elliptic curve object called y_recover(x) that returns an int y if (x, y) is a point on the curve, otherwise it returns None.

import hashlib

from ecpy.curves import Curve

curve = Curve.get_curve('secp256r1')
base_info = b'some fixed or domain-specific byte sequence'
padding = 0

num_new_points = 5
for i in range(num_new_points):
    while True:
        x_bytes = hashlib.sha256(base_info + padding.to_bytes(4, 'big')).digest()
        x = int.from_bytes(x_bytes, 'big') % curve.field
        y = curve.y_recover(x)
        padding += 1
        if y:
            print(f'({x}, {y}) is on the curve')
            break
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125