Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python3 debugging code #14

Open
NewbieOubie2017 opened this issue Nov 24, 2017 · 7 comments
Open

python3 debugging code #14

NewbieOubie2017 opened this issue Nov 24, 2017 · 7 comments

Comments

@NewbieOubie2017
Copy link

I edited the code to get it to run with python3 but it still is not completely debugged...
this is what I get when it runs:
******* Public Key Generation *********
the private key (in base 10 format):
75263518707598184987916378021939673586055614731957507592904438851787542395619

the uncompressed public key (starts with '04' & is not the public address):
04 0.0 0.0

******* Signature Generation *********
r = 0.0
s = 0.0

******* Signature Verification ********>>
Traceback (most recent call last):
File "CreateEllipticCurvesPart5TheMagicSigningAndVerifyingdebugged.py", line 63, in
xu2, yu2 = EccMultiply(xPublicKey,yPublicKey,(r
w)%N)
File "CreateEllipticCurvesPart5TheMagicSigningAndVerifyingdebugged.py", line 39, in EccMultiply
if Scalar == 0 or Scalar >= N: raise Exception("Invalid Scalar/Private Key")
Exception: Invalid Scalar/Private Key

Basically I just put in parentheses in the print commands. Here is the new code.

Python 2.7.6 - Super simple Elliptic Curve Presentation. No imported libraries, wrappers, nothing. # For educational purposes only

Below are the public specs for Bitcoin's curve - the secp256k1

Pcurve = 2256 - 232 - 29 - 28 - 27 - 26 - 2**4 -1 # The proven prime
N=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # Number of points in the field
Acurve = 0; Bcurve = 7 # This defines the curve. y^2 = x^3 + Acurve * x + Bcurve
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
GPoint = (Gx,Gy) # This is our generator point. Tillions of dif ones possible

#Individual Transaction/Personal Information
privKey = 75263518707598184987916378021939673586055614731957507592904438851787542395619 #replace with any private key
RandNum = 28695618543805844332113829720373285210420739438570883203839696518176414791234 #replace with a truly random number
HashOfThingToSign = 86032112319101611046176971828093669637772856272773459297323797145286374828050 # the hash of your message/transaction

def modinv(a,n=Pcurve): #Extended Euclidean Algorithm/'division' in elliptic curves
lm, hm = 1,0
low, high = a%n,n
while low > 1:
ratio = high/low
nm, new = hm-lmratio, high-lowratio
lm, low, hm, high = nm, new, lm, low
return lm % n

def ECadd(xp,yp,xq,yq): # Not true addition, invented for EC. It adds Point-P with Point-Q.
m = ((yq-yp) * modinv(xq-xp,Pcurve)) % Pcurve
xr = (mm-xp-xq) % Pcurve
yr = (m
(xp-xr)-yp) % Pcurve
return (xr,yr)

def ECdouble(xp,yp): # EC point doubling, invented for EC. It doubles Point-P.
LamNumer = 3xpxp+Acurve
LamDenom = 2yp
Lam = (LamNumer * modinv(LamDenom,Pcurve)) % Pcurve
xr = (Lam
Lam-2xp) % Pcurve
yr = (Lam
(xp-xr)-yp) % Pcurve
return (xr,yr)

def EccMultiply(xs,ys,Scalar): # Double & add. EC Multiplication, Not true multiplication
if Scalar == 0 or Scalar >= N: raise Exception("Invalid Scalar/Private Key")
ScalarBin = str(bin(Scalar))[2:]
Qx,Qy=xs,ys
for i in range (1, len(ScalarBin)): # This is invented EC multiplication.
Qx,Qy=ECdouble(Qx,Qy); # print "DUB", Qx; print
if ScalarBin[i] == "1":
Qx,Qy=ECadd(Qx,Qy,xs,ys); # print "ADD", Qx; print
return (Qx,Qy)

print()
print( "******* Public Key Generation *********")
xPublicKey, yPublicKey = EccMultiply(Gx,Gy,privKey)
print( "the private key (in base 10 format):"); print(privKey); print()
print("the uncompressed public key (starts with '04' & is not the public address):"); print("04", xPublicKey, yPublicKey)

print(); print("******* Signature Generation *******")
xRandSignPoint, yRandSignPoint = EccMultiply(Gx,Gy,RandNum)
r = xRandSignPoint % N
print("r =", r)
s = ((HashOfThingToSign + r
privKey)
(modinv(RandNum,N))) % N; print("s =", s)

print(); print("******* Signature Verification ********>>")
w = modinv(s,N)
xu1, yu1 = EccMultiply(Gx,Gy,(HashOfThingToSign * w)%N)
xu2, yu2 = EccMultiply(xPublicKey,yPublicKey,(r
w)%N)
x,y = ECadd(xu1,yu1,xu2,yu2)
print(r==x); print()

@molet01
Copy link

molet01 commented Dec 27, 2018

ratio = high/low must be an integer division, change it into ratio = high // low

@ricky-andre
Copy link

ricky-andre commented Apr 4, 2019

This version worked for me:

Pcurve = 2256 - 232 - 29 - 28 - 27 - 26 - 2**4 -1 # The proven prime
Acurve = 0; Bcurve = 7 # These two defines the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
GPoint = (Gx,Gy) # Generator Point
N=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # Number of points in the field
privKey = 75263518707598184987916378021939673586055614731957507592904438851787542395619

RandNum = 28695618543805844332113829720373285210420739438570883203839696518176414791234 #replace with a truly random number
HashOfThingToSign = 86032112319101611046176971828093669637772856272773459297323797145286374828050 # the hash of your message/transaction

def modinv(a,b=Pcurve): #Extended Euclidean Algorithm/'division' in elliptic curves
lm, hm = 1,0
low, high = a%b,b
while low > 1:
ratio = high//low
nm, new = hm-lmratio, high-lowratio
lm, low, hm, high = nm, new, lm, low
return lm % b

def ECAdd(a,b): # Point addition, invented for EC.
LambdaAdd = ((b[1] - a[1]) * modinv(b[0] - a[0],Pcurve)) % Pcurve
x = (LambdaAdd * LambdaAdd - a[0] - b[0]) % Pcurve
y = (LambdaAdd * (a[0] - x) - a[1]) % Pcurve
return (x,y)

def ECDouble(a): # Point Doubling, also invented for EC.
LamdaDouble = ((3 * a[0] * a[0] + Acurve) * modinv((2 * a[1]), Pcurve)) % Pcurve
x = (LamdaDouble * LamdaDouble - 2 * a[0]) % Pcurve
y = (LamdaDouble * (a[0] - x) - a[1]) % Pcurve
return (x,y)

def ECMultiply(GenPoint,privKeyHex): #Double & add. Not true multiplication
if privKeyHex == 0 or privKeyHex >= N: raise Exception("Invalid Private Key")
privKeyBin = str(bin(privKeyHex))[2:]
Q=GenPoint
for i in range (1, len(privKeyBin)):
Q=ECDouble(Q);
if privKeyBin[i] == "1":
Q=ECAdd(Q,GenPoint);
return (Q)

PublicKey = ECMultiply(GPoint,privKey)
print("Private Key:")
print (privKey)
print("\nPublic Key public key (uncompressed):")
print ("04", PublicKey)
print("\nPublic Key (compressed):")
if (PublicKey[1] % 2 == 1): # If the Y coordinate of the Public Key is odd.
print("03"+str(hex(PublicKey[0])[2:]).zfill(64))
else: # If the Y coordinate is even.
print("02"+str(hex(PublicKey[0])[2:]).zfill(64))

print("\n******* Signature Generation *****")
xRandSignPoint, yRandSignPoint = ECMultiply(GPoint,RandNum)
r = xRandSignPoint % N
print("r =", r)
s = ((HashOfThingToSign + r
privKey)
(modinv(RandNum,N))) % N
print("s =", s)

print("\n******* Signature Verification ********>>")
w = modinv(s,N)
x, y = ECAdd(ECMultiply(GPoint,(HashOfThingToSign * w) % N), ECMultiply(PublicKey,(r*w) % N))
print(r==x);

@ricky-andre
Copy link

ricky-andre commented Apr 4, 2019

You can also find the code here:
https://github.com/roheat/PublicKeyGeneration/

... even though you have to fix the following:

  • as explained above ratio = high//low (double back slash)
  • when printing the compressed version, the hex string needs to be cutted with [2:] (and NOT [2:-1])

and of course the print statements need to be modified.

@NewbieOubie2017
Copy link
Author

Okay I made those changes and hopefully submitted it correctly.

@gtmadureira
Copy link

gtmadureira commented Apr 13, 2021

@NewbieOubie2017
Copy link
Author

NewbieOubie2017 commented Apr 13, 2021 via email

@gtmadureira
Copy link

If I use the same source code, but for curve 25519, where the cofactor is "h = 8". How would I implement this "cofactor" in the source code?
Just for testing and learning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants