choose_tx_from account, and use deterministic signatures (issue #323)
This commit is contained in:
@@ -794,7 +794,7 @@ class ElectrumWindow(QMainWindow):
|
|||||||
if self.amount_e.is_shortcut:
|
if self.amount_e.is_shortcut:
|
||||||
self.amount_e.is_shortcut = False
|
self.amount_e.is_shortcut = False
|
||||||
c, u = self.wallet.get_account_balance(self.current_account)
|
c, u = self.wallet.get_account_balance(self.current_account)
|
||||||
inputs, total, fee = self.wallet.choose_tx_inputs( c + u, 0, self.current_account)
|
inputs, total, fee = self.wallet.choose_tx_inputs_from_account( c + u, 0, self.current_account)
|
||||||
fee = self.wallet.estimated_fee(inputs)
|
fee = self.wallet.estimated_fee(inputs)
|
||||||
amount = c + u - fee
|
amount = c + u - fee
|
||||||
self.amount_e.setText( self.format_amount(amount) )
|
self.amount_e.setText( self.format_amount(amount) )
|
||||||
@@ -807,7 +807,7 @@ class ElectrumWindow(QMainWindow):
|
|||||||
if not is_fee: fee = None
|
if not is_fee: fee = None
|
||||||
if amount is None:
|
if amount is None:
|
||||||
return
|
return
|
||||||
inputs, total, fee = self.wallet.choose_tx_inputs( amount, fee, self.current_account )
|
inputs, total, fee = self.wallet.choose_tx_inputs_from_account( amount, fee, self.current_account )
|
||||||
if not is_fee:
|
if not is_fee:
|
||||||
self.fee_e.setText( self.format_amount( fee ) )
|
self.fee_e.setText( self.format_amount( fee ) )
|
||||||
if inputs:
|
if inputs:
|
||||||
@@ -1676,7 +1676,7 @@ class ElectrumWindow(QMainWindow):
|
|||||||
def do_verify():
|
def do_verify():
|
||||||
message = unicode(verify_message.toPlainText())
|
message = unicode(verify_message.toPlainText())
|
||||||
message = message.encode('utf-8')
|
message = message.encode('utf-8')
|
||||||
if self.wallet.verify_message(verify_address.text(), str(verify_signature.toPlainText()), message):
|
if bitcoin.verify_message(verify_address.text(), str(verify_signature.toPlainText()), message):
|
||||||
self.show_message(_("Signature verified"))
|
self.show_message(_("Signature verified"))
|
||||||
else:
|
else:
|
||||||
self.show_message(_("Error: wrong signature"))
|
self.show_message(_("Error: wrong signature"))
|
||||||
|
|||||||
@@ -272,18 +272,9 @@ def is_valid(addr):
|
|||||||
|
|
||||||
########### end pywallet functions #######################
|
########### end pywallet functions #######################
|
||||||
|
|
||||||
# secp256k1, http://www.oid-info.com/get/1.3.132.0.10
|
|
||||||
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
|
|
||||||
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
|
|
||||||
_b = 0x0000000000000000000000000000000000000000000000000000000000000007L
|
|
||||||
_a = 0x0000000000000000000000000000000000000000000000000000000000000000L
|
|
||||||
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
|
|
||||||
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
|
|
||||||
curve_secp256k1 = ecdsa.ellipticcurve.CurveFp( _p, _a, _b )
|
|
||||||
generator_secp256k1 = ecdsa.ellipticcurve.Point( curve_secp256k1, _Gx, _Gy, _r )
|
|
||||||
oid_secp256k1 = (1,3,132,0,10)
|
|
||||||
SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1 )
|
|
||||||
|
|
||||||
|
from ecdsa.ecdsa import curve_secp256k1, generator_secp256k1
|
||||||
|
from ecdsa.curves import SECP256k1
|
||||||
from ecdsa.util import string_to_number, number_to_string
|
from ecdsa.util import string_to_number, number_to_string
|
||||||
|
|
||||||
def msg_magic(message):
|
def msg_magic(message):
|
||||||
@@ -293,6 +284,16 @@ def msg_magic(message):
|
|||||||
return "\x18Bitcoin Signed Message:\n" + encoded_varint + message
|
return "\x18Bitcoin Signed Message:\n" + encoded_varint + message
|
||||||
|
|
||||||
|
|
||||||
|
def verify_message(address, signature, message):
|
||||||
|
try:
|
||||||
|
EC_KEY.verify_message(address, signature, message)
|
||||||
|
return True
|
||||||
|
except BaseException as e:
|
||||||
|
print_error("Verification error: {0}".format(e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EC_KEY(object):
|
class EC_KEY(object):
|
||||||
def __init__( self, secret ):
|
def __init__( self, secret ):
|
||||||
self.pubkey = ecdsa.ecdsa.Public_key( generator_secp256k1, generator_secp256k1 * secret )
|
self.pubkey = ecdsa.ecdsa.Public_key( generator_secp256k1, generator_secp256k1 * secret )
|
||||||
@@ -302,7 +303,7 @@ class EC_KEY(object):
|
|||||||
def sign_message(self, message, compressed, address):
|
def sign_message(self, message, compressed, address):
|
||||||
private_key = ecdsa.SigningKey.from_secret_exponent( self.secret, curve = SECP256k1 )
|
private_key = ecdsa.SigningKey.from_secret_exponent( self.secret, curve = SECP256k1 )
|
||||||
public_key = private_key.get_verifying_key()
|
public_key = private_key.get_verifying_key()
|
||||||
signature = private_key.sign_digest( Hash( msg_magic(message) ), sigencode = ecdsa.util.sigencode_string )
|
signature = private_key.sign_digest_deterministic( Hash( msg_magic(message) ), hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_string )
|
||||||
assert public_key.verify_digest( signature, Hash( msg_magic(message) ), sigdecode = ecdsa.util.sigdecode_string)
|
assert public_key.verify_digest( signature, Hash( msg_magic(message) ), sigdecode = ecdsa.util.sigdecode_string)
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
sig = base64.b64encode( chr(27 + i + (4 if compressed else 0)) + signature )
|
sig = base64.b64encode( chr(27 + i + (4 if compressed else 0)) + signature )
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class Commands:
|
|||||||
|
|
||||||
|
|
||||||
def verifymessage(self, address, signature, message):
|
def verifymessage(self, address, signature, message):
|
||||||
return self.wallet.verify_message(address, signature, message)
|
return bitcoin.verify_message(address, signature, message)
|
||||||
|
|
||||||
|
|
||||||
def _mktx(self, outputs, fee = None, change_addr = None, domain = None):
|
def _mktx(self, outputs, fee = None, change_addr = None, domain = None):
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ class Transaction:
|
|||||||
secexp = pkey.secret
|
secexp = pkey.secret
|
||||||
private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
|
private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
|
||||||
public_key = private_key.get_verifying_key()
|
public_key = private_key.get_verifying_key()
|
||||||
sig = private_key.sign_digest( Hash( tx_for_sig.decode('hex') ), sigencode = ecdsa.util.sigencode_der )
|
sig = private_key.sign_digest_deterministic( Hash( tx_for_sig.decode('hex') ), hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
|
||||||
assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der)
|
assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der)
|
||||||
signatures.append( sig.encode('hex') )
|
signatures.append( sig.encode('hex') )
|
||||||
print_error("adding signature for", pubkey)
|
print_error("adding signature for", pubkey)
|
||||||
|
|||||||
@@ -673,14 +673,6 @@ class Wallet:
|
|||||||
compressed = is_compressed(sec)
|
compressed = is_compressed(sec)
|
||||||
return key.sign_message(message, compressed, address)
|
return key.sign_message(message, compressed, address)
|
||||||
|
|
||||||
def verify_message(self, address, signature, message):
|
|
||||||
try:
|
|
||||||
EC_KEY.verify_message(address, signature, message)
|
|
||||||
return True
|
|
||||||
except BaseException as e:
|
|
||||||
print_error("Verification error: {0}".format(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def change_gap_limit(self, value):
|
def change_gap_limit(self, value):
|
||||||
if value >= self.gap_limit:
|
if value >= self.gap_limit:
|
||||||
@@ -1005,6 +997,11 @@ class Wallet:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def choose_tx_inputs_from_account( self, amount, fixed_fee, account ):
|
||||||
|
domain = self.get_account_addresses(account) if account else None
|
||||||
|
return self.choose_tx_inputs( amount, fixed_fee, domain )
|
||||||
|
|
||||||
|
|
||||||
def choose_tx_inputs( self, amount, fixed_fee, domain = None ):
|
def choose_tx_inputs( self, amount, fixed_fee, domain = None ):
|
||||||
""" todo: minimize tx size """
|
""" todo: minimize tx size """
|
||||||
total = 0
|
total = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user