0

I am currently new in Python and cryptography. I am trying to make a public key of SECP256K1 elliptic curve manually(without related library use), from a random generated private key as I learned. The method of generating private key is free. What matters is the process making the public key out of it.

This is what I have.

import random
import os
import time
import hashlib

def generate_private_key():
    global P
    while(True):
        key=str(random.random())+str(os.urandom(100))+str(time.time())
        key=hashlib.sha256(key.encode())
        key=int(key.hexdigest(),16)
        if(P>key):
            return key

def generate_public_key(private_key):
    global G
    global P
    bit=list(bin(private_key)[2:])
    point=(0,0)
    for i in bit:
        if i=='0':
            point=point_double(point, P)
        elif i=='1':
            point=point_double(point, P)
            point=point_add(point,G, P)
    return point


#Extended Euclidean Algorithm
def inverse(b,n):
    r1=n
    r2=b
    t1=0
    t2=1
    while(r2>0):
        q=r1//r2
        t=t1-q*t2
        t1=t2
        t2=t
        r=r1-q*r2
        r1=r2
        r2=r
    if t1>0: return t1
    else: return t1+t2
    

def point_double(point, P):
    (x,y)=point
    lam=3*(x**2)*inverse(2*y,P)
    xsum=lam**2-x*2
    ysum=lam*(x-xsum)-y
    return xsum%P, ysum%P

def point_add(p1, p2, P):
    (x1,y1)=p1
    (x2, y2)=p2
    if x1==x2 and y1==y2:
        return point_double(p1)

    lam=(y2-y1)*inverse(x2-x1, P)
    xsum= lam**2-(x1+x2)
    ysum= lam*(x1-xsum)-y1
    return xsum%P, ysum%P





P=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F

G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

private_key=generate_private_key()

#my private key
print(hex(private_key))

#public key
print(generate_public_key(private_key))

I am comparing my code's result with this website's result: https://paulmillr.com/noble/ However, I can't get a same public key out of the same private key.

This is the process what I think:

  1. Create a random private key.
  2. Create a public key using (private key * a fixed point G)

2-1. Use Double-and-Add method to avoid adding up G [private key] times because both numbers are too big to do so.

2-2. All additions are followed by (mod P). P is also a very big number, fixed.

2-3. All divisions are not literally divisions. It is an inverse of (mod P). Solving the inverse of (mod P) is done by using Extended Euclidean Algorithm('inverse' function in code).

Since I wasn't sure where to put the '%P' in code, I tried several places putting '%P', but no luck so far and ended up with the current code. I couldn't actually test the result step by step because the numbers and the amount of process were too big.

hib0823
  • 1
  • 1
  • 1
    Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Mar 13 '23 at 00:45

0 Answers0