URI: 
       tclass MyVerifyingKey, with constructor to submit to python-ecdsa - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 650ef92c5f41a881788c7f490b77ad7979118cae
   DIR parent 16929a40b15c3ca6f5d673adb2ffb5025e218ee9
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Fri, 30 May 2014 21:24:23 +0200
       
       class MyVerifyingKey, with constructor to submit to python-ecdsa
       
       Diffstat:
         M lib/bitcoin.py                      |      57 ++++++++++++++++++-------------
       
       1 file changed, 33 insertions(+), 24 deletions(-)
       ---
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -406,6 +406,34 @@ def ser_to_point(Aser):
        
        
        
       +class MyVerifyingKey(ecdsa.VerifyingKey):
       +    @classmethod
       +    def from_signature(klass, sig, recid, h, curve):
       +        """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """
       +        from ecdsa import util, numbertheory
       +        import msqr
       +        curveFp = curve.curve
       +        G = curve.generator
       +        order = G.order()
       +        # extract r,s from signature
       +        r, s = util.sigdecode_string(sig, order)
       +        # 1.1
       +        x = r + (recid/2) * order
       +        # 1.3
       +        alpha = ( x * x * x  + curveFp.a() * x + curveFp.b() ) % curveFp.p()
       +        beta = msqr.modular_sqrt(alpha, curveFp.p())
       +        y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta
       +        # 1.4 the constructor checks that nR is at infinity
       +        R = Point(curveFp, x, y, order)
       +        # 1.5 compute e from message:
       +        e = string_to_number(h)
       +        minus_e = -e % order
       +        # 1.6 compute Q = r^-1 (sR - eG)
       +        inv_r = numbertheory.inverse_mod(r,order)
       +        Q = inv_r * ( s * R + minus_e * G )
       +        return klass.from_public_point( Q, curve )
       +
       +
        class EC_KEY(object):
            def __init__( self, k ):
                secret = string_to_number(k)
       t@@ -434,16 +462,9 @@ class EC_KEY(object):
        
            @classmethod
            def verify_message(self, address, signature, message):
       -        """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """
       -        from ecdsa import numbertheory, util
       -        import msqr
       -        curve = curve_secp256k1
       -        G = generator_secp256k1
       -        order = G.order()
       -        # extract r,s from signature
                sig = base64.b64decode(signature)
                if len(sig) != 65: raise Exception("Wrong encoding")
       -        r,s = util.sigdecode_string(sig[1:], order)
       +
                nV = ord(sig[0])
                if nV < 27 or nV >= 35:
                    raise Exception("Bad encoding")
       t@@ -454,24 +475,12 @@ class EC_KEY(object):
                    compressed = False
        
                recid = nV - 27
       -        # 1.1
       -        x = r + (recid/2) * order
       -        # 1.3
       -        alpha = ( x * x * x  + curve.a() * x + curve.b() ) % curve.p()
       -        beta = msqr.modular_sqrt(alpha, curve.p())
       -        y = beta if (beta - recid) % 2 == 0 else curve.p() - beta
       -        # 1.4 the constructor checks that nR is at infinity
       -        R = Point(curve, x, y, order)
       -        # 1.5 compute e from message:
                h = Hash( msg_magic(message) )
       -        e = string_to_number(h)
       -        minus_e = -e % order
       -        # 1.6 compute Q = r^-1 (sR - eG)
       -        inv_r = numbertheory.inverse_mod(r,order)
       -        Q = inv_r * ( s * R + minus_e * G )
       -        public_key = ecdsa.VerifyingKey.from_public_point( Q, curve = SECP256k1 )
       -        # check that Q is the public key
       +        public_key = MyVerifyingKey.from_signature( sig[1:], recid, h, curve = SECP256k1 )
       +
       +        # check public key
                public_key.verify_digest( sig[1:], h, sigdecode = ecdsa.util.sigdecode_string)
       +
                # check that we get the original signing address
                addr = public_key_to_bc_address( point_to_ser(public_key.pubkey.point, compressed) )
                if address != addr: