Skip to content

Instantly share code, notes, and snippets.

@nlitsme
Last active January 19, 2025 10:14
Show Gist options
  • Select an option

  • Save nlitsme/c9031c7b9bf6bb009e5a to your computer and use it in GitHub Desktop.

Select an option

Save nlitsme/c9031c7b9bf6bb009e5a to your computer and use it in GitHub Desktop.

Revisions

  1. nlitsme revised this gist Oct 10, 2022. 1 changed file with 10 additions and 0 deletions.
    10 changes: 10 additions & 0 deletions curve_example.py
    Original file line number Diff line number Diff line change
    @@ -127,3 +127,13 @@ def isoncurve(pt,p):
    2 * halvepub: (71ee918bc19bb566e3a5f12c0cd0de620bec1025da6e98951355ebbde8727be3,37b3650efad4190b7328b1156304f2e9e23dbb7f2da50999dde50ea73b4c2688)
    """

    # this shows how to multiply by -1
    print(" G = (%x,%x)" % g)
    gminus = ptmul(g,n-1, p)
    print(" -G = (%x,%x)" % gminus)
    gminusminus = ptmul(gminus,n-1, p)
    print(" -(-G) = (%x,%x)" % gminusminus)
    gminusplus = addpt(g,gminus, p)

    # this will output the point at infinity, currently represented as 'None'
    print(" G+(-G) = %s" % gminusplus)
  2. nlitsme revised this gist Oct 10, 2022. 1 changed file with 25 additions and 2 deletions.
    27 changes: 25 additions & 2 deletions curve_example.py
    Original file line number Diff line number Diff line change
    @@ -4,8 +4,14 @@
    secp256k1 is the name of the elliptic curve used by bitcoin
    see http://bitcoin.stackexchange.com/questions/25382
    """

    ## the prime modules used in the elliptic curve coordinate calculations
    p = 2**256 - 2**32 - 977

    ## the group order, used with the elliptic curve scalar multiplication calculations
    n = 2**256 - 0x14551231950B75FC4402DA1732FC9BEBF


    def inverse(x, p):
    """
    Calculate the modular inverse of x ( mod p )
    @@ -51,8 +57,13 @@ def addpt(p1,p2, p):
    (x1,y1)= p1
    (x2,y2)= p2
    if x1==x2:
    return dblpt(p1, p)

    if y1==y2:
    return dblpt(p1, p)
    elif (y1+y2) % p == 0:
    return None
    else:
    raise Exception("invalid points added")

    # calculate (y1-y2)/(x1-x2) modulus p
    slope=(y1-y2)*inverse(x1-x2, p)
    xsum= pow(slope,2,p)-(x1+x2)
    @@ -97,10 +108,22 @@ def isoncurve(pt,p):
    privkey= 0xf8ef380d6c05116dbed78bfdd6e6625e57426af9a082b81c2fa27b06984c11f3
    print(" -> pubkey= (%x,%x)" % ptmul(g, privkey, p))

    # note that here I have to use the grouporder 'n'
    halvekey = (privkey * inverse(2, n)) % n
    print(" halvekey = %x" % halvekey)

    halvepub = ptmul(g, halvekey, p)
    print(" pub / 2 = (%x,%x)" % halvepub)
    print("2 * halvepub: (%x,%x)" % addpt(halvepub, halvepub, p))

    """
    for reference, the numbers printed should be:
    2*G= (c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a)
    G+2*G= (f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672)
    2*G+2*G= (e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13,51ed993ea0d455b75642e2098ea51448d967ae33bfbdfe40cfe97bdc47739922)
    -> pubkey= (71ee918bc19bb566e3a5f12c0cd0de620bec1025da6e98951355ebbde8727be3,37b3650efad4190b7328b1156304f2e9e23dbb7f2da50999dde50ea73b4c2688)
    halvekey = fc779c06b60288b6df6bc5feeb73312e88f8a3f027e5ac2bf7ba6cc9b441299a
    pub / 2 = (d6c8d2ecbce68e0bf127c889be491c2a4f26a84c15b1fe8688f42728baea6c18,49a300586b09945c63e89df3c1739fb30567cec3da037d0402222c3b7f05c6e2)
    2 * halvepub: (71ee918bc19bb566e3a5f12c0cd0de620bec1025da6e98951355ebbde8727be3,37b3650efad4190b7328b1156304f2e9e23dbb7f2da50999dde50ea73b4c2688)
    """

  3. nlitsme revised this gist Sep 5, 2021. 1 changed file with 6 additions and 9 deletions.
    15 changes: 6 additions & 9 deletions curve_example.py
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,8 @@
    from __future__ import print_function, division
    """
    Example of how calculations on the secp256k1 curve work.
    secp256k1 is the name of the elliptic curve used by bitcoin
    see http://bitcoin.stackexchange.com/questions/25382
    """
    p = 2**256 - 2**32 - 977

    @@ -21,7 +19,7 @@ def inverse(x, p):
    inv1 = 1
    inv2 = 0
    while p != 1 and p!=0:
    inv1, inv2 = inv2, inv1 - inv2 * (x / p)
    inv1, inv2 = inv2, inv1 - inv2 * (x // p)
    x, p = p, x % p

    return inv2
    @@ -92,16 +90,15 @@ def isoncurve(pt,p):
    Gy=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
    g= (Gx,Gy)
    g2=dblpt(g, p)
    print " 2*G= (%x,%x)" % g2
    print " G+2*G= (%x,%x)" % addpt(g, g2, p)
    print "2*G+2*G= (%x,%x)" % addpt(g2, g2, p)
    print(" 2*G= (%x,%x)" % g2)
    print(" G+2*G= (%x,%x)" % addpt(g, g2, p))
    print("2*G+2*G= (%x,%x)" % addpt(g2, g2, p))

    privkey= 0xf8ef380d6c05116dbed78bfdd6e6625e57426af9a082b81c2fa27b06984c11f3
    print " -> pubkey= (%x,%x)" % ptmul(g, privkey, p)
    print(" -> pubkey= (%x,%x)" % ptmul(g, privkey, p))

    """
    for reference, the numbers printed should be:
    2*G= (c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a)
    G+2*G= (f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672)
    2*G+2*G= (e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13,51ed993ea0d455b75642e2098ea51448d967ae33bfbdfe40cfe97bdc47739922)
  4. nlitsme renamed this gist Oct 30, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. nlitsme revised this gist May 23, 2014. 1 changed file with 10 additions and 2 deletions.
    12 changes: 10 additions & 2 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -92,10 +92,18 @@ def isoncurve(pt,p):
    Gy=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
    g= (Gx,Gy)
    g2=dblpt(g, p)
    print "2*G= (%x,%x)" % g2
    print "G+2*G= (%x,%x)" % addpt(g, g2, p)
    print " 2*G= (%x,%x)" % g2
    print " G+2*G= (%x,%x)" % addpt(g, g2, p)
    print "2*G+2*G= (%x,%x)" % addpt(g2, g2, p)

    privkey= 0xf8ef380d6c05116dbed78bfdd6e6625e57426af9a082b81c2fa27b06984c11f3
    print " -> pubkey= (%x,%x)" % ptmul(g, privkey, p)

    """
    for reference, the numbers printed should be:
    2*G= (c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,1ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a)
    G+2*G= (f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672)
    2*G+2*G= (e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13,51ed993ea0d455b75642e2098ea51448d967ae33bfbdfe40cfe97bdc47739922)
    -> pubkey= (71ee918bc19bb566e3a5f12c0cd0de620bec1025da6e98951355ebbde8727be3,37b3650efad4190b7328b1156304f2e9e23dbb7f2da50999dde50ea73b4c2688)
    """
  6. nlitsme revised this gist May 23, 2014. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,9 @@
    Example of how calculations on the secp256k1 curve work.
    secp256k1 is the name of the elliptic curve used by bitcoin
    see http://bitcoin.stackexchange.com/questions/25382
    """
    p = 2**256 - 2**32 - 977

  7. nlitsme revised this gist May 23, 2014. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -33,7 +33,10 @@ def dblpt(pt, p):
    (x,y)= pt
    if y==0:
    return None

    # Calculate 3*x^2/(2*y) modulus p
    slope= 3*pow(x,2,p)*inverse(2*y,p)

    xsum= pow(slope,2,p)-2*x
    ysum= slope*(x-xsum)-y
    return (xsum%p, ysum%p)
    @@ -48,6 +51,8 @@ def addpt(p1,p2, p):
    (x2,y2)= p2
    if x1==x2:
    return dblpt(p1, p)

    # calculate (y1-y2)/(x1-x2) modulus p
    slope=(y1-y2)*inverse(x1-x2, p)
    xsum= pow(slope,2,p)-(x1+x2)
    ysum= slope*(x1-xsum)-y1
  8. nlitsme revised this gist May 23, 2014. 1 changed file with 28 additions and 0 deletions.
    28 changes: 28 additions & 0 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,20 @@
    """
    Example of how calculations on the secp256k1 curve work.
    secp256k1 is the name of the elliptic curve used by bitcoin
    """
    p = 2**256 - 2**32 - 977

    def inverse(x, p):
    """
    Calculate the modular inverse of x ( mod p )
    the modular inverse is a number such that:
    (inverse(x, p) * x) % p == 1
    you could think of this as: 1/x
    """
    inv1 = 1
    inv2 = 0
    while p != 1 and p!=0:
    @@ -12,6 +25,9 @@ def inverse(x, p):


    def dblpt(pt, p):
    """
    Calculate pt+pt = 2*pt
    """
    if pt is None:
    return None
    (x,y)= pt
    @@ -23,6 +39,9 @@ def dblpt(pt, p):
    return (xsum%p, ysum%p)

    def addpt(p1,p2, p):
    """
    Calculate p1+p2
    """
    if p1 is None or p2 is None:
    return None
    (x1,y1)= p1
    @@ -35,6 +54,11 @@ def addpt(p1,p2, p):
    return (xsum%p, ysum%p)

    def ptmul(pt,a, p):
    """
    Scalar multiplication: calculate pt*a
    basically adding pt to itself a times
    """
    scale= pt
    acc=None
    while a:
    @@ -49,9 +73,13 @@ def ptmul(pt,a, p):


    def isoncurve(pt,p):
    """
    returns True when pt is on the secp256k1 curve
    """
    (x,y)= pt
    return (y**2 - x**3 - 7)%p == 0

    # (Gx,Gy) is the secp256k1 generator point
    Gx=0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
    Gy=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
    g= (Gx,Gy)
  9. nlitsme created this gist May 21, 2014.
    65 changes: 65 additions & 0 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@

    p = 2**256 - 2**32 - 977

    def inverse(x, p):
    inv1 = 1
    inv2 = 0
    while p != 1 and p!=0:
    inv1, inv2 = inv2, inv1 - inv2 * (x / p)
    x, p = p, x % p

    return inv2


    def dblpt(pt, p):
    if pt is None:
    return None
    (x,y)= pt
    if y==0:
    return None
    slope= 3*pow(x,2,p)*inverse(2*y,p)
    xsum= pow(slope,2,p)-2*x
    ysum= slope*(x-xsum)-y
    return (xsum%p, ysum%p)

    def addpt(p1,p2, p):
    if p1 is None or p2 is None:
    return None
    (x1,y1)= p1
    (x2,y2)= p2
    if x1==x2:
    return dblpt(p1, p)
    slope=(y1-y2)*inverse(x1-x2, p)
    xsum= pow(slope,2,p)-(x1+x2)
    ysum= slope*(x1-xsum)-y1
    return (xsum%p, ysum%p)

    def ptmul(pt,a, p):
    scale= pt
    acc=None
    while a:
    if a&1:
    if acc is None:
    acc= scale
    else:
    acc= addpt(acc,scale, p)
    scale= dblpt(scale, p)
    a >>= 1
    return acc


    def isoncurve(pt,p):
    (x,y)= pt
    return (y**2 - x**3 - 7)%p == 0

    Gx=0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
    Gy=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
    g= (Gx,Gy)
    g2=dblpt(g, p)
    print "2*G= (%x,%x)" % g2
    print "G+2*G= (%x,%x)" % addpt(g, g2, p)

    privkey= 0xf8ef380d6c05116dbed78bfdd6e6625e57426af9a082b81c2fa27b06984c11f3
    print " -> pubkey= (%x,%x)" % ptmul(g, privkey, p)