Advertisement
Guest User

Untitled

a guest
Oct 21st, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.67 KB | None | 0 0
  1. # the code below is 'borrowed' almost verbatim from electrum,
  2. # https://gitorious.org/electrum/electrum
  3. # and is under the GPLv3.
  4.  
  5. import ecdsa
  6. import base64
  7. import hashlib
  8. from ecdsa.util import string_to_number
  9.  
  10. # secp256k1, http://www.oid-info.com/get/1.3.132.0.10
  11. _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
  12. _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
  13. _b = 0x0000000000000000000000000000000000000000000000000000000000000007L
  14. _a = 0x0000000000000000000000000000000000000000000000000000000000000000L
  15. _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
  16. _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
  17. curve_secp256k1 = ecdsa.ellipticcurve.CurveFp( _p, _a, _b )
  18. generator_secp256k1 = ecdsa.ellipticcurve.Point( curve_secp256k1, _Gx, _Gy, _r )
  19. oid_secp256k1 = (1,3,132,0,10)
  20. SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1 )
  21.  
  22. addrtype = 0
  23.  
  24. # from http://eli.thegreenplace.net/2009/03/07/computing-modular-square-roots-in-python/
  25.  
  26. def modular_sqrt(a, p):
  27.     """ Find a quadratic residue (mod p) of 'a'. p
  28.    must be an odd prime.
  29.    
  30.    Solve the congruence of the form:
  31.    x^2 = a (mod p)
  32.    And returns x. Note that p - x is also a root.
  33.    
  34.    0 is returned is no square root exists for
  35.    these a and p.
  36.    
  37.    The Tonelli-Shanks algorithm is used (except
  38.    for some simple cases in which the solution
  39.    is known from an identity). This algorithm
  40.    runs in polynomial time (unless the
  41.    generalized Riemann hypothesis is false).
  42.    """
  43.     # Simple cases
  44.     #
  45.     if legendre_symbol(a, p) != 1:
  46.         return 0
  47.     elif a == 0:
  48.         return 0
  49.     elif p == 2:
  50.         return p
  51.     elif p % 4 == 3:
  52.         return pow(a, (p + 1) / 4, p)
  53.    
  54.     # Partition p-1 to s * 2^e for an odd s (i.e.
  55.     # reduce all the powers of 2 from p-1)
  56.     #
  57.     s = p - 1
  58.     e = 0
  59.     while s % 2 == 0:
  60.         s /= 2
  61.         e += 1
  62.        
  63.     # Find some 'n' with a legendre symbol n|p = -1.
  64.     # Shouldn't take long.
  65.     #
  66.     n = 2
  67.     while legendre_symbol(n, p) != -1:
  68.         n += 1
  69.        
  70.     # Here be dragons!
  71.     # Read the paper "Square roots from 1; 24, 51,
  72.     # 10 to Dan Shanks" by Ezra Brown for more
  73.     # information
  74.     #
  75.    
  76.     # x is a guess of the square root that gets better
  77.     # with each iteration.
  78.     # b is the "fudge factor" - by how much we're off
  79.     # with the guess. The invariant x^2 = ab (mod p)
  80.     # is maintained throughout the loop.
  81.     # g is used for successive powers of n to update
  82.     # both a and b
  83.     # r is the exponent - decreases with each update
  84.     #
  85.     x = pow(a, (s + 1) / 2, p)
  86.     b = pow(a, s, p)
  87.     g = pow(n, s, p)
  88.     r = e
  89.    
  90.     while True:
  91.         t = b
  92.         m = 0
  93.         for m in xrange(r):
  94.             if t == 1:
  95.                 break
  96.             t = pow(t, 2, p)
  97.            
  98.         if m == 0:
  99.             return x
  100.        
  101.         gs = pow(g, 2 ** (r - m - 1), p)
  102.         g = (gs * gs) % p
  103.         x = (x * gs) % p
  104.         b = (b * g) % p
  105.         r = m
  106.        
  107. def legendre_symbol(a, p):
  108.     """ Compute the Legendre symbol a|p using
  109.    Euler's criterion. p is a prime, a is
  110.    relatively prime to p (if p divides
  111.    a, then a|p = 0)
  112.    
  113.    Returns 1 if a has a square root modulo
  114.    p, -1 otherwise.
  115.    """
  116.     ls = pow(a, (p - 1) / 2, p)
  117.     return -1 if ls == p - 1 else ls
  118.  
  119. __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  120. __b58base = len(__b58chars)
  121.  
  122. def b58encode(v):
  123.     """ encode v, which is a string of bytes, to base58.       
  124.    """
  125.  
  126.     long_value = 0L
  127.     for (i, c) in enumerate(v[::-1]):
  128.         long_value += (256**i) * ord(c)
  129.  
  130.     result = ''
  131.     while long_value >= __b58base:
  132.         div, mod = divmod(long_value, __b58base)
  133.         result = __b58chars[mod] + result
  134.         long_value = div
  135.     result = __b58chars[long_value] + result
  136.  
  137.     # Bitcoin does a little leading-zero-compression:
  138.     # leading 0-bytes in the input become leading-1s
  139.     nPad = 0
  140.     for c in v:
  141.         if c == '\0': nPad += 1
  142.         else: break
  143.  
  144.     return (__b58chars[0]*nPad) + result
  145.  
  146. def msg_magic(message):
  147.     return "\x18Bitcoin Signed Message:\n" + chr( len(message) ) + message
  148.  
  149. def Hash(data):
  150.     return hashlib.sha256(hashlib.sha256(data).digest()).digest()
  151.  
  152. def hash_160(public_key):
  153.     md = hashlib.new('ripemd160')
  154.     md.update(hashlib.sha256(public_key).digest())
  155.     return md.digest()
  156.  
  157. def hash_160_to_bc_address(h160):
  158.     vh160 = chr(addrtype) + h160
  159.     h = Hash(vh160)
  160.     addr = vh160 + h[0:4]
  161.     return b58encode(addr)
  162.  
  163. def public_key_to_bc_address(public_key):
  164.     h160 = hash_160(public_key)
  165.     return hash_160_to_bc_address(h160)
  166.  
  167. def encode_point(pubkey, compressed=False):
  168.     order = generator_secp256k1.order()
  169.     p = pubkey.pubkey.point
  170.     x_str = ecdsa.util.number_to_string(p.x(), order)
  171.     y_str = ecdsa.util.number_to_string(p.y(), order)
  172.     if compressed:
  173.         return chr(2 + (p.y() & 1)) + x_str
  174.     else:
  175.         return chr(4) + x_str + y_str
  176.  
  177. def sign_message(private_key, message, compressed=False):
  178.     public_key = private_key.get_verifying_key()
  179.     signature = private_key.sign_digest( Hash( msg_magic( message ) ), sigencode = ecdsa.util.sigencode_string )
  180.     address = public_key_to_bc_address(encode_point(public_key, compressed))
  181.     assert public_key.verify_digest( signature, Hash( msg_magic( message ) ), sigdecode = ecdsa.util.sigdecode_string)
  182.     for i in range(4):
  183.         nV = 27 + i
  184.         if compressed:
  185.             nV += 4
  186.         sig = base64.b64encode( chr(nV) + signature )
  187.         try:
  188.             if verify_message( address, sig, message):
  189.                 return sig
  190.         except:
  191.             continue
  192.     else:
  193.         raise BaseException("error: cannot sign message")
  194.  
  195. def verify_message(signature, message):
  196.     """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """
  197.     from ecdsa import numbertheory, ellipticcurve, util
  198.     curve = curve_secp256k1
  199.     G = generator_secp256k1
  200.     order = G.order()
  201.     # extract r,s from signature
  202.     sig = base64.b64decode(signature)
  203.     if len(sig) != 65: raise BaseException("Wrong encoding")
  204.     r,s = util.sigdecode_string(sig[1:], order)
  205.     nV = ord(sig[0])
  206.     if nV < 27 or nV >= 35:
  207.         return False
  208.     if nV >= 31:
  209.         compressed = True
  210.         nV -= 4
  211.     else:
  212.         compressed = False
  213.     recid = nV - 27
  214.     # 1.1
  215.     x = r + (recid/2) * order
  216.     # 1.3
  217.     alpha = ( x * x * x  + curve.a() * x + curve.b() ) % curve.p()
  218.     beta = modular_sqrt(alpha, curve.p())
  219.     y = beta if (beta - recid) % 2 == 0 else curve.p() - beta
  220.     # 1.4 the constructor checks that nR is at infinity
  221.     R = ellipticcurve.Point(curve, x, y, order)
  222.     # 1.5 compute e from message:
  223.     h = Hash( msg_magic( message ) )
  224.     e = string_to_number(h)
  225.     minus_e = -e % order
  226.     # 1.6 compute Q = r^-1 (sR - eG)
  227.     inv_r = numbertheory.inverse_mod(r,order)
  228.     Q = inv_r * ( s * R + minus_e * G )
  229.     public_key = ecdsa.VerifyingKey.from_public_point( Q, curve = SECP256k1 )
  230.     # check that Q is the public key
  231.     public_key.verify_digest( sig[1:], h, sigdecode = ecdsa.util.sigdecode_string)
  232.     # check that we get the original signing address
  233.     addr = public_key_to_bc_address(encode_point(public_key, compressed))
  234.     return addr
  235.        
  236. if __name__ == '__main__':
  237.     print verify_message('H81xEoFTGDmmAAA7YTDlLJCyK7jc2XfY9jUPj7WoY+QhLO73FXEgDTo0hkL7C8h2gAWmtJhT5mQZi5FYJqxfJjU=',
  238.                          'This night was fantastic. I can not wait to see you again, my bloodyheart.')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement