Browse Source

add signmessage to wallet, update version

master
Adam Gibson 9 years ago
parent
commit
28912acb5f
No known key found for this signature in database
GPG Key ID: B3AE09F1E9A3197A
  1. 2
      jmbase/setup.py
  2. 15
      jmbitcoin/jmbitcoin/secp256k1_main.py
  3. 2
      jmbitcoin/setup.py
  4. 4
      jmclient/setup.py
  5. 4
      jmdaemon/setup.py
  6. 19
      scripts/wallet-tool.py

2
jmbase/setup.py

@ -2,7 +2,7 @@ from setuptools import setup
setup(name='joinmarketbase', setup(name='joinmarketbase',
version='0.2.0', version='0.2.1',
description='Joinmarket client library for Bitcoin coinjoins', description='Joinmarket client library for Bitcoin coinjoins',
url='http://github.com/AdamISZ/joinmarket-clientserver/jmbase', url='http://github.com/AdamISZ/joinmarket-clientserver/jmbase',
author='Adam Gibson', author='Adam Gibson',

15
jmbitcoin/jmbitcoin/secp256k1_main.py

@ -230,12 +230,12 @@ def from_wif_privkey(wif_priv, compressed=True, vbyte=0):
raise Exception("Private key has incorrect compression byte") raise Exception("Private key has incorrect compression byte")
return safe_hexlify(bin_key) return safe_hexlify(bin_key)
def ecdsa_sign(msg, priv, usehex=True): def ecdsa_sign(msg, priv, formsg=False, usehex=True):
hashed_msg = message_sig_hash(msg) hashed_msg = message_sig_hash(msg)
if usehex: if usehex:
#arguments to raw sign must be consistently hex or bin #arguments to raw sign must be consistently hex or bin
hashed_msg = binascii.hexlify(hashed_msg) hashed_msg = binascii.hexlify(hashed_msg)
sig = ecdsa_raw_sign(hashed_msg, priv, usehex, rawmsg=True) sig = ecdsa_raw_sign(hashed_msg, priv, usehex, rawmsg=True, formsg=formsg)
#note those functions only handles binary, not hex #note those functions only handles binary, not hex
if usehex: if usehex:
sig = binascii.unhexlify(sig) sig = binascii.unhexlify(sig)
@ -365,7 +365,8 @@ def ecdsa_raw_sign(msg,
usehex, usehex,
rawpriv=True, rawpriv=True,
rawmsg=False, rawmsg=False,
usenonce=None): usenonce=None,
formsg=False):
'''Take the binary message msg and sign it with the private key '''Take the binary message msg and sign it with the private key
priv. priv.
By default priv is just a 32 byte string, if rawpriv is false By default priv is just a 32 byte string, if rawpriv is false
@ -386,8 +387,12 @@ def ecdsa_raw_sign(msg,
newpriv = secp256k1.PrivateKey(p, raw=True, ctx=ctx) newpriv = secp256k1.PrivateKey(p, raw=True, ctx=ctx)
else: else:
newpriv = secp256k1.PrivateKey(priv, raw=False, ctx=ctx) newpriv = secp256k1.PrivateKey(priv, raw=False, ctx=ctx)
if formsg:
sig = newpriv.ecdsa_sign_recoverable(msg, raw=rawmsg)
s, rid = newpriv.ecdsa_recoverable_serialize(sig)
return chr(31+rid) + s
#Donations, thus custom nonce, currently disabled, hence not covered. #Donations, thus custom nonce, currently disabled, hence not covered.
if usenonce: #pragma: no cover elif usenonce: #pragma: no cover
raise NotImplementedError raise NotImplementedError
#if len(usenonce) != 32: #if len(usenonce) != 32:
# raise ValueError("Invalid nonce passed to ecdsa_sign: " + str( # raise ValueError("Invalid nonce passed to ecdsa_sign: " + str(
@ -395,8 +400,6 @@ def ecdsa_raw_sign(msg,
#nf = ffi.addressof(_noncefunc.lib, "nonce_function_rand") #nf = ffi.addressof(_noncefunc.lib, "nonce_function_rand")
#ndata = ffi.new("char [32]", usenonce) #ndata = ffi.new("char [32]", usenonce)
#usenonce = (nf, ndata) #usenonce = (nf, ndata)
if usenonce: #pragma: no cover
raise NotImplementedError
#sig = newpriv.ecdsa_sign(msg, raw=rawmsg, custom_nonce=usenonce) #sig = newpriv.ecdsa_sign(msg, raw=rawmsg, custom_nonce=usenonce)
else: else:
#partial fix for secp256k1-transient not including customnonce; #partial fix for secp256k1-transient not including customnonce;

2
jmbitcoin/setup.py

@ -2,7 +2,7 @@ from setuptools import setup
setup(name='joinmarketbitcoin', setup(name='joinmarketbitcoin',
version='0.2.0', version='0.2.1',
description='Joinmarket client library for Bitcoin coinjoins', description='Joinmarket client library for Bitcoin coinjoins',
url='http://github.com/AdamISZ/joinmarket-clientserver/jmbitcoin', url='http://github.com/AdamISZ/joinmarket-clientserver/jmbitcoin',
author='Adam Gibson', author='Adam Gibson',

4
jmclient/setup.py

@ -2,12 +2,12 @@ from setuptools import setup
setup(name='joinmarketclient', setup(name='joinmarketclient',
version='0.2.0', version='0.2.1',
description='Joinmarket client library for Bitcoin coinjoins', description='Joinmarket client library for Bitcoin coinjoins',
url='http://github.com/AdamISZ/joinmarket-clientserver/jmclient', url='http://github.com/AdamISZ/joinmarket-clientserver/jmclient',
author='Adam Gibson', author='Adam Gibson',
author_email='ekaggata@gmail.com', author_email='ekaggata@gmail.com',
license='GPL', license='GPL',
packages=['jmclient'], packages=['jmclient'],
install_requires=['joinmarketbase==0.2.0'], install_requires=['joinmarketbase==0.2.1'],
zip_safe=False) zip_safe=False)

4
jmdaemon/setup.py

@ -2,12 +2,12 @@ from setuptools import setup
setup(name='joinmarketdaemon', setup(name='joinmarketdaemon',
version='0.2.0', version='0.2.1',
description='Joinmarket client library for Bitcoin coinjoins', description='Joinmarket client library for Bitcoin coinjoins',
url='http://github.com/AdamISZ/joinmarket-clientserver/jmdaemon', url='http://github.com/AdamISZ/joinmarket-clientserver/jmdaemon',
author='Adam Gibson', author='Adam Gibson',
author_email='ekaggata@gmail.com', author_email='ekaggata@gmail.com',
license='GPL', license='GPL',
packages=['jmdaemon'], packages=['jmdaemon'],
install_requires=['txsocksx', 'pyopenssl', 'libnacl', 'joinmarketbase==0.2.0'], install_requires=['txsocksx', 'pyopenssl', 'libnacl', 'joinmarketbase==0.2.1'],
zip_safe=False) zip_safe=False)

19
scripts/wallet-tool.py

@ -32,7 +32,10 @@ description = (
'privkeys are spaces or commas separated. (dumpprivkey) Export ' 'privkeys are spaces or commas separated. (dumpprivkey) Export '
'a single private key, specify an hd wallet path (listwallets) ' 'a single private key, specify an hd wallet path (listwallets) '
'Lists all wallets with creator and timestamp. (history) Show ' 'Lists all wallets with creator and timestamp. (history) Show '
'all historical transaction details. Requires Bitcoin Core.') 'all historical transaction details. Requires Bitcoin Core.\n'
'signmessage\t\tSign a message with the private key from an address\n'
'\t\t\tin the wallet. Use with -H and specify an HD wallet\n'
'\t\t\tpath for the address.')
parser = OptionParser(usage='usage: %prog [options] [wallet file] [method]', parser = OptionParser(usage='usage: %prog [options] [wallet file] [method]',
description=description) description=description)
@ -92,7 +95,7 @@ noseed_methods = ['generate', 'recover', 'listwallets']
methods = ['display', 'displayall', 'summary', 'showseed', 'importprivkey', methods = ['display', 'displayall', 'summary', 'showseed', 'importprivkey',
'history', 'showutxos'] 'history', 'showutxos']
methods.extend(noseed_methods) methods.extend(noseed_methods)
noscan_methods = ['showseed', 'importprivkey', 'dumpprivkey'] noscan_methods = ['showseed', 'importprivkey', 'dumpprivkey', 'signmessage']
if len(args) < 1: if len(args) < 1:
parser.error('Needs a wallet file or method') parser.error('Needs a wallet file or method')
@ -316,6 +319,18 @@ elif method == 'listwallets':
print(' ') print(' ')
i += 1 i += 1
print(str(i - 1) + ' Wallets have been found.') print(str(i - 1) + ' Wallets have been found.')
elif method == 'signmessage':
message = args[2]
if options.hd_path.startswith('m/0/'):
m, forchange, k = [int(y) for y in options.hd_path[4:].split('/')]
key = wallet.get_key(m, forchange, k)
addr = btc.privkey_to_address(key, magicbyte=get_p2pk_vbyte())
print('Using address: ' + addr)
else:
print('%s is not a valid hd wallet path' % options.hd_path)
sig = btc.ecdsa_sign(message, key, formsg=True)
print("Signature: " + str(sig))
print("To verify this in Bitcoin Core use the RPC command 'verifymessage'")
elif method == 'history': elif method == 'history':
#sort txes in a db because python can be really bad with large lists #sort txes in a db because python can be really bad with large lists
con = sqlite3.connect(":memory:") con = sqlite3.connect(":memory:")

Loading…
Cancel
Save