We have a number of possible types of elliptic curve methods. These have a field (the prime number used), the order (the number of elliptic curve points), an \(a\) value, a \(b\) value, and a generator point (\(G\)). For a Weierstrass curve the standard form is \(y^2=x^3+ax+b\). With a twisted Edwards curve (such as Ed25519) we have the form of \(ax^2+y^2=1+dx^2y^2\). A Montgomory curve has the form of \(by^2=x^3+ax^2+x\).
Elliptic Curve Types and nG |
Sample run
A sample run is:
Curve: secp256k1 ==================== G: (0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 , 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8) Bit size: 256 Order: 115792089237316195423570985008687907852837564279074904382605163141518161494337 Field: 115792089237316195423570985008687907853269984665640564039457584007908834671663 a: 0 b: 7 ==================== 10G: (0xa0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7 , 0x893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7) Point add (add 1G on) 11G: (0x774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb , 0xd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b) Point subtraction (take 1G off) 10G: (0xa0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7 , 0x893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7) The first 10 points ... (1,29896722852569046015560700294576055776214335159245303116488692907525646231534) (2,46580984542418694471253469931035885126779956971428003686700937153791839982430) (3,94471189679404635060807731153122836805497974241028285133722790318709222555876) (4,75283998438183369598817001785077409976464767920444208230223825605154713824156) (5,None) (6,19112057249303445409876026535760519114630369653212530612662492210011362204224) (7,None) (8,91736135629086734185706894124002126994554994840140056297753929940646699135966) (9,None) (10,None)
Coding
The outline code is:
from ecpy.curves import Curve import sys o=3 k=3 if (len(sys.argv)>1): o=int(sys.argv[1]) if (len(sys.argv)>2): k=int(sys.argv[2]) cv = Curve.get_curve('Curve25519') if (o==1): cv = Curve.get_curve('Curve25519') if (o==2): cv = Curve.get_curve('Curve448') if (o==3): cv = Curve.get_curve('Ed25519') if (o==4): cv = Curve.get_curve('Ed448') if (o==5): cv = Curve.get_curve('secp160r2') if (o==6): cv = Curve.get_curve('secp256k1') if (o==7): cv = Curve.get_curve('secp521r1') if (o==8): cv = Curve.get_curve('NIST-P192') if (o==9): cv = Curve.get_curve('NIST-P224') if (o==10): cv = Curve.get_curve('NIST-P256') print (f"Curve: {cv.name}") print ("====================") print (f"G: {cv.generator}") print (f"Bit size: {cv.size}") print (f"Order: {cv.order}") print (f"Field: {cv.field}") print (f"a: {cv.a}") if (o==3 or o==4): print (f"b: {cv.d}") else: print (f"b: {cv.b}") print ("====================") G=cv.generator Q = k*G print (f"\n{k}G: {Q}") print ("\nPoint add (add 1G on)") P = G R=P+Q print (f"\n{k+1}G: {R}") print ("\nPoint subtraction (take 1G off)") R=R-G print (f"\n{k}G: {R}") print ("\nThe first 10 points ...") for i in range(1,11): if (o==3 or o==4): try: x=cv.x_recover(i) print (f"({x},{i})") except: print (f"(NO POINT,{i})") else: y=cv.y_recover(i) print (f"({i},{y})")