Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
- 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
- 11253563012059685825953619222107823549092147699031672238385790369351542642469
- 36422191471907241029883925342251831624200921388586025344128047678873736520530
- 20277110887056303803699431755396003735040374760118964734768299847012543114150
- 1*G
- 2*G = G+G
- 4*G = 2*G + 2*G
- 8*G = 4*G + 4*G
- 16*G = 8*G + 8*G
- 32*G = 16*G + 16*G
- 64*G = 32*G + 32*G
- privkey pointlist
- 1 1*G
- 0 2*G
- 0 4*G
- 1 8*G
- 0 16*G
- 1 32*G
- 1 64*G
- 9*G = 1*G + 8*G
- 41*G = (9+32)*G = 9*G + 32*G
- 105*G = (41+64)*G = 41*G + 64*G
- #! /usr/bin/env python
- # python 2.x
- class CurveFp( object ):
- def __init__( self, p, a, b ):
- self.__p = p
- self.__a = a
- self.__b = b
- def p( self ):
- return self.__p
- def a( self ):
- return self.__a
- def b( self ):
- return self.__b
- def contains_point( self, x, y ):
- return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
- class Point( object ):
- def __init__( self, curve, x, y, order = None ):
- self.__curve = curve
- self.__x = x
- self.__y = y
- self.__order = order
- if self.__curve: assert self.__curve.contains_point( x, y )
- if order: assert self * order == INFINITY
- def __add__( self, other ):
- if other == INFINITY: return self
- if self == INFINITY: return other
- assert self.__curve == other.__curve
- if self.__x == other.__x:
- if ( self.__y + other.__y ) % self.__curve.p() == 0:
- return INFINITY
- else:
- return self.double()
- p = self.__curve.p()
- l = ( ( other.__y - self.__y ) *
- inverse_mod( other.__x - self.__x, p ) ) % p
- x3 = ( l * l - self.__x - other.__x ) % p
- y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
- return Point( self.__curve, x3, y3 )
- def __mul__( self, other ):
- def leftmost_bit( x ):
- assert x > 0
- result = 1L
- while result <= x: result = 2 * result
- return result / 2
- e = other
- if self.__order: e = e % self.__order
- if e == 0: return INFINITY
- if self == INFINITY: return INFINITY
- assert e > 0
- e3 = 3 * e
- negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
- i = leftmost_bit( e3 ) / 2
- result = self
- while i > 1:
- result = result.double()
- if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
- if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
- i = i / 2
- return result
- def __rmul__( self, other ):
- return self * other
- def __str__( self ):
- if self == INFINITY: return "infinity"
- return "(%d,%d)" % ( self.__x, self.__y )
- def double( self ):
- if self == INFINITY:
- return INFINITY
- p = self.__curve.p()
- a = self.__curve.a()
- l = ( ( 3 * self.__x * self.__x + a ) *
- inverse_mod( 2 * self.__y, p ) ) % p
- x3 = ( l * l - 2 * self.__x ) % p
- y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
- return Point( self.__curve, x3, y3 )
- def x( self ):
- return self.__x
- def y( self ):
- return self.__y
- def curve( self ):
- return self.__curve
- def order( self ):
- return self.__order
- INFINITY = Point( None, None, None )
- def inverse_mod( a, m ):
- if a < 0 or m <= a: a = a % m
- c, d = a, m
- uc, vc, ud, vd = 1, 0, 0, 1
- while c != 0:
- q, c, d = divmod( d, c ) + ( c, )
- uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
- assert d == 1
- if ud > 0: return ud
- else: return ud + m
- # secp256k1
- _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
- _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
- _b = 0x0000000000000000000000000000000000000000000000000000000000000007L
- _a = 0x0000000000000000000000000000000000000000000000000000000000000000L
- _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
- _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
- class Public_key( object ):
- def __init__( self, generator, point ):
- self.curve = generator.curve()
- self.generator = generator
- self.point = point
- n = generator.order()
- if not n:
- raise RuntimeError, "Generator point must have order."
- if not n * point == INFINITY:
- raise RuntimeError, "Generator point order is bad."
- if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
- raise RuntimeError, "Generator point has x or y out of range."
- curve_256 = CurveFp( _p, _a, _b )
- generator_256 = Point( curve_256, _Gx, _Gy, _r )
- g = generator_256
- if __name__ == "__main__":
- print '======================================================================='
- ### set privkey
- # wiki
- #secret = 0xE9873D79C6D87DC0FB6A5778633389F4453213303DA61F20BD67FC233AA33262L
- # question
- secret = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725L
- ### print privkey
- print 'secret', hex(secret)
- ### generate pubkey
- pubkey = Public_key( g, g * secret )
- ### print pubkey
- print 'pubkey', hex(pubkey.point.x()), hex(pubkey.point.y())
- print '======================================================================='
- class CalcPub
- {
- public static void Main()
- {
- var p = BigInteger.Parse("0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", NumberStyles.HexNumber);
- var b = (BigInteger)7;
- var a = BigInteger.Zero;
- var Gx = BigInteger.Parse("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", NumberStyles.HexNumber);
- var Gy = BigInteger.Parse("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", NumberStyles.HexNumber);
- CurveFp curve256 = new CurveFp(p, a, b);
- Point generator256 = new Point(curve256, Gx, Gy);
- var secret = BigInteger.Parse("18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725", NumberStyles.HexNumber);
- Console.WriteLine("secret {0}", secret.ToString("X"));
- var pubkeyPoint = generator256 * secret;
- Console.WriteLine("pubkey {0}{1}", pubkeyPoint.X.ToString("X"), pubkeyPoint.Y.ToString("X"));
- }
- }
- class Point
- {
- public static readonly Point INFINITY = new Point(null, default(BigInteger), default(BigInteger));
- public CurveFp Curve { get; private set; }
- public BigInteger X { get; private set; }
- public BigInteger Y { get; private set; }
- public Point(CurveFp curve, BigInteger x, BigInteger y)
- {
- this.Curve = curve;
- this.X = x;
- this.Y = y;
- }
- public Point Double()
- {
- if (this == INFINITY)
- return INFINITY;
- BigInteger p = this.Curve.p;
- BigInteger a = this.Curve.a;
- BigInteger l = ((3 * this.X * this.X + a) * InverseMod(2 * this.Y, p)) % p;
- BigInteger x3 = (l * l - 2 * this.X) % p;
- BigInteger y3 = (l * (this.X - x3) - this.Y) % p;
- return new Point(this.Curve, x3, y3);
- }
- public override string ToString()
- {
- if (this == INFINITY)
- return "infinity";
- return string.Format("({0},{1})", this.X, this.Y);
- }
- public static Point operator +(Point left, Point right)
- {
- if (right == INFINITY)
- return left;
- if (left == INFINITY)
- return right;
- if (left.X == right.X)
- {
- if ((left.Y + right.Y) % left.Curve.p == 0)
- return INFINITY;
- else
- return left.Double();
- }
- var p = left.Curve.p;
- var l = ((right.Y - left.Y) * InverseMod(right.X - left.X, p)) % p;
- var x3 = (l * l - left.X - right.X) % p;
- var y3 = (l * (left.X - x3) - left.Y) % p;
- return new Point(left.Curve, x3, y3);
- }
- public static Point operator *(Point left, BigInteger right)
- {
- var e = right;
- if (e == 0 || left == INFINITY)
- return INFINITY;
- var e3 = 3 * e;
- var negativeLeft = new Point(left.Curve, left.X, -left.Y);
- var i = LeftmostBit(e3) / 2;
- var result = left;
- while (i > 1)
- {
- result = result.Double();
- if ((e3 & i) != 0 && (e & i) == 0)
- result += left;
- if ((e3 & i) == 0 && (e & i) != 0)
- result += negativeLeft;
- i /= 2;
- }
- return result;
- }
- private static BigInteger LeftmostBit(BigInteger x)
- {
- BigInteger result = 1;
- while (result <= x)
- result = 2 * result;
- return result / 2;
- }
- private static BigInteger InverseMod(BigInteger a, BigInteger m)
- {
- while (a < 0) a += m;
- if (a < 0 || m <= a)
- a = a % m;
- BigInteger c = a;
- BigInteger d = m;
- BigInteger uc = 1;
- BigInteger vc = 0;
- BigInteger ud = 0;
- BigInteger vd = 1;
- while (c != 0)
- {
- BigInteger r;
- //q, c, d = divmod( d, c ) + ( c, );
- var q = BigInteger.DivRem(d, c, out r);
- d = c;
- c = r;
- //uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc;
- var uct = uc;
- var vct = vc;
- var udt = ud;
- var vdt = vd;
- uc = udt - q * uct;
- vc = vdt - q * vct;
- ud = uct;
- vd = vct;
- }
- if (ud > 0) return ud;
- else return ud + m;
- }
- }
- class CurveFp
- {
- public BigInteger p { get; private set; }
- public BigInteger a { get; private set; }
- public BigInteger b { get; private set; }
- public CurveFp(BigInteger p, BigInteger a, BigInteger b)
- {
- this.p = p;
- this.a = a;
- this.b = b;
- }
- }
- #! /usr/bin/env python
- class Point(object):
- def __init__(self, _x, _y, _order = None): self.x, self.y, self.order = _x, _y, _order
- def calc(self, top, bottom, other_x):
- l = (top * inverse_mod(bottom)) % p
- x3 = (l * l - self.x - other_x) % p
- return Point(x3, (l * (self.x - x3) - self.y) % p)
- def double(self):
- if self == INFINITY: return INFINITY
- return self.calc(3 * self.x * self.x, 2 * self.y, self.x)
- def __add__(self, other):
- if other == INFINITY: return self
- if self == INFINITY: return other
- if self.x == other.x:
- if (self.y + other.y) % p == 0: return INFINITY
- return self.double()
- return self.calc(other.y - self.y, other.x - self.x, other.x)
- def __mul__(self, e):
- if self.order: e %= self.order
- if e == 0 or self == INFINITY: return INFINITY
- result, q = INFINITY, self
- while e:
- if e&1: result += q
- e, q = e >> 1, q.double()
- return result
- def __str__(self):
- if self == INFINITY: return "infinity"
- return "04 %x %x" % (self.x, self.y)
- def inverse_mod(a):
- if a < 0 or a >= p: a = a % p
- c, d, uc, vc, ud, vd = a, p, 1, 0, 0, 1
- while c:
- q, c, d = divmod(d, c) + (c,)
- uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
- if ud > 0: return ud
- return ud + p
- p, INFINITY = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL, Point(None, None) # secp256k1
- g = Point(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L,
- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L)
- secret = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725L
- print ' privkey: %xn pubkey: %s' % (secret, g * secret)
- privkey: 18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725
- pubkey: 04 50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352 2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6
- def sk_to_pk(sk):
- """
- Derive the public key of a secret secp256k1 key.
- Args:
- sk: An integer representing the secret key (also known as secret
- exponent).
- Returns:
- A coordinate (x, y) on the curve repesenting the public key
- for the given secret key.
- Raises:
- ValueError: The given key was not valid.
- """
- # base point (generator)
- G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
- 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
- # field prime
- P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
- # order
- N = (1 << 256) - 0x14551231950B75FC4402DA1732FC9BEBF
- # check if the key is valid
- if not(0 < sk < N):
- msg = "{} is not a valid key (not in range [1, {}]"
- raise ValueError(msg.format(hex(sk), hex(N-1)))
- # addition operation on the elliptic curve
- # see: https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Point_addition
- # note that the coordinates need to be given modulo P and that division is
- # done by computing the multiplicative inverse, which can be done with
- # x^-1 = x^(P-2) mod P using fermat's little theorem (the pow function of python
- # can do this efficiently even for very large P)
- def add(p, q):
- px, py = p
- qx, qy = q
- if p == q:
- lam = (3 * px * px) * pow(2 * py, P - 2, P)
- else:
- lam = (qy - py) * pow(qx - px, P - 2, P)
- xr = (lam**2 - px - qx)
- yr = (lam * (px - xr) - py)
- return xr % P, yr % P
- # compute G * sk by repeatedly adding
- # by using the binary representation of sk this can be done in 256
- # iterations
- ret = None
- for i in xrange(256):
- if sk & (1 << i):
- if ret is None:
- ret = G
- else:
- ret = add(ret, G)
- G = add(G, G)
- return ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement