javascriptcryptographycryptojsweb3jssjcl

Generate public key in browser if I only have the existing private key


I'm generating new Ethereum addresses using the scep256k1 curve. Due to storage and hardware limitations, I'm only able to store the private key. I'm looking for ways to generate the public key for asymmetric encryption (NOT the Ethereum public address) in the browser.

It is my understanding that the public key can be derived from the scep256k1 private key, but I'm not sure how to do this in the browser, or whether this is even possible with existing libraries, but I've a hunch that it is. I'm currently trying to see if it is possible with Web3js, SJCL, or CryptoJS but am open to other options.

To provide a bit of an understanding of the flow here. Step 3 is what I'm currently trying to do:

  1. Generate scep256k1 key pair using openSSL
  2. Upload the private key to hardware device and give this to a user
  3. User in web interface: use private key from hardware to get access to their public key, and reconstruct the Ethereum address.

Any pointers in the right direction are appreciated!


Solution

  • Yep this is trivial.

    You simply need to use the private key byte array (which is effectively a 256-bit scalar), and multiply it by the secp256k1 curves generator point g which is itself a point on the curve which generates the curves cyclic group.

    ETH addresses are independently derived from the underlying secp256k1 public key, which is itself physically, a point on the curve.

    The method call you're looking for is curve scalar multiplication.

    The generator is:

    Gx = 
    0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
    
    Gy = 
    0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
    

    Simply add this point to itself n times, where n is the private key order. i.e. g*k where k is the private key, and voila, you've derived the public key.