electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 650ef92c5f41a881788c7f490b77ad7979118cae
parent 16929a40b15c3ca6f5d673adb2ffb5025e218ee9
Author: ThomasV <thomasv@gitorious>
Date:   Fri, 30 May 2014 21:24:23 +0200

class MyVerifyingKey, with constructor to submit to python-ecdsa

Diffstat:
Mlib/bitcoin.py | 57+++++++++++++++++++++++++++++++++------------------------
1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -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) @@ -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") @@ -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: