Author

Topic: Using Electrum codebase in another project. (Read 290 times)

HCP
legendary
Activity: 2086
Merit: 4363
October 04, 2017, 02:11:40 AM
#4
Yeah. I can see that now. However, from what I can gather now, EC_KEY wants a secret not a private key. So if you pass 'BB7529C7834A210374035F50E884C6CA1E42C6DFB43004463AE3BC38A2585E19' as a paremeter, it's not going to work. How would I go about signing messages with that specific private key?.

sign_message_with_wif_privkey also requires the secret.

So let's say I generate a key through bitaddress.org which gives me WIF format, hex format and all that, how would I go about using that?.
Near as I can figure... the "secret" is the 32 bytes of the private key in hex... converted from a string to an Int...

from ecdsa.util import string_to_number, number_to_string
...
class EC_KEY(object):

    def __init__( self, k ):
        secret = string_to_number(k)
...

...
def string_to_number(string):
    return int(binascii.hexlify(string), 16)
..

I'll have a mess around tonight... and see if I can come up with some example code to string some of it together. Smiley


EDIT: I'm too lazy to hack the code, so I was messing with the Electrum console:

Code:
>> import binascii
>> binascii.unhexlify("E705308F9F19BA9292FB0A9F022CC07666AA4D63C14C097F44A674C52599AF2D")
'\xe7\x050\x8f\x9f\x19\xba\x92\x92\xfb\n\x9f\x02,\xc0vf\xaaMc\xc1L\t\x7fD\xa6t\xc5%\x99\xaf-'
>> bitcoin.EC_KEY(binascii.unhexlify("E705308F9F19BA9292FB0A9F022CC07666AA4D63C14C097F44A674C52599AF2D"))

>> mystuff = bitcoin.EC_KEY(binascii.unhexlify("E705308F9F19BA9292FB0A9F022CC07666AA4D63C14C097F44A674C52599AF2D"))
>> print(mystuff.secret)
104493437413910685574809975339575985857145839109407479576256729153645095530285
>> print(mystuff.get_public_key())
03c8759d2cd3dc2b12f9ce4e539d956986b6fd0d2b38303b141cd8ee09e683be13
>> mystuff.sign_message("this is my message", False)
'\x1cEp\x0f\xc9\xae\xb4\x0f\x89\xf7\x80x\x88%\xa7\xc8\xd4Te\xfcRc\xaa\x0fe\xfa \xf2wP/\xf9\x0b?L@g\x1f\x07J\xba\x0b\x10Bj\xb1\xe6~\xb8\x9f\xc8\xbb|\xd8\xaer\x15\xb8X\x87^\\\xa0\xd9\xa5'
>> mystuff.verify_message(mystuff.sign_message("this is my message", False),"this is my message")
>> mystuff.verify_message(mystuff.sign_message("this is my message", False),"bad message")
Traceback (most recent call last):
  File "C:\Users\jared\AppData\Local\Temp\_MEI114882\lib\bitcoin.py", line 642, in verify_message
    raise Exception("Bad signature")
Exception: Bad signature
>>  

If you check bitaddress.org with your original WIF key... L4xnRyP8ARQHZ1BwVkUVfk8sMkXsyBJxd9zhEMXci6NjHkFd9ewp or the HEX: E705308F9F19BA9292FB0A9F022CC07666AA4D63C14C097F44A674C52599AF2D you'll see the public address listed: 19M16LN1k5Emc8qBuDEYv9Aggpe2ttuABk Wink
newbie
Activity: 2
Merit: 0
October 02, 2017, 04:17:39 PM
#3
Yeah. I can see that now. However, from what I can gather now, EC_KEY wants a secret not a private key. So if you pass 'BB7529C7834A210374035F50E884C6CA1E42C6DFB43004463AE3BC38A2585E19' as a paremeter, it's not going to work. How would I go about signing messages with that specific private key?.

sign_message_with_wif_privkey also requires the secret.

So let's say I generate a key through bitaddress.org which gives me WIF format, hex format and all that, how would I go about using that?.

In other side of spectrum, how would I generate a private key & its secret through electrum's source code?. All I can see is mnemonic.py which can create a seed through its make_seed method (to return a set of words) and mnemonic_to_seed which gives me a hex that looks like this:

b'\x1f\x8f\x85S\xe4\x8a\x12mL\xd5&\xe6\x11Z\xdfYAm$-kq|w\xd9\xa1\x00\xd6).L\x95\xc1q\xe6\x1b\x80\xa4w\x19\x1ah\x00[{\xab\x9f\xfe\x8b$\xcc\'a\x99;"Y\xcee(Bx\xa7p' which turns into: b'f7c4fb817c11f2e8e4a93e646168cbbf6fb74648f765b529da2d892a9eb22cbf9dde6e3810f1f28 05d5c522db262f6b3e750beb6f1e4a8bd9f6138ec324d5cfe'

However, regardless of what I pass to EC_KEY, when trying to sign it fails with:

Traceback (most recent call last):
  File "test.py", line 24, in
    print(key.sign_message('Testing', False))
  File "...\src\bitcoin.py", line 739, in sign_message
    signature = self.sign(Hash(msg_magic(message)))
  File "...\src\bitcoin.py", line 731, in sign
    private_key = MySigningKey.from_secret_exponent(self.secret, curve = SECP256k1)
  File "...\Python35\lib\site-packages\ecdsa\keys.py", line 137, in from_secret_exponent
    assert 1 <= secexp < n
AssertionError
HCP
legendary
Activity: 2086
Merit: 4363
October 02, 2017, 06:13:39 AM
#2
You're sending in the WIF formatted private key to the bitcoin.EC_KEY() function... perhaps it is expecting the actual hexidecimal representation of the private key in a 'bytes' object??

Likely to be something like: b'E705308F9F19BA9292FB0A9F022CC07666AA4D63C14C097F44A674C52599AF2D'
newbie
Activity: 2
Merit: 0
October 01, 2017, 11:58:28 PM
#1
Hello!

I'm in the need of using the bitcoin code base for Electrum to generate seeds, addresses, sign messages & verify messages. So I've been taking a look at the the code and I'm slightly confused.

So the flow I' following is:

Use Mnemonic.py to generate new seed, use new seed generate private key, create a EC_KEY object from bitcoin.py then use its sign_message & verify_message class methods to do the whole verifying with said key. I know that I can also use the verify_message function to verify any messages.

However, it's throwing several errors:

This is the verify_message:

assert bytes failed [, ]
Traceback (most recent call last):
  File "test.py", line 8, in
    print(bitcoin.verify_message('19M16LN1k5Emc8qBuDEYv9Aggpe2ttuABk', 'TEST', '19M16LN1k5Emc8qBuDEYv9Aggpe2ttuABk H6jdr/wEW/E8mBYGwIdDOGJLBYyou9kMHT2GCzKaKsJsjjw9Fd4cj1fI2/wbAiRDkuedcd0DZEDxpnEvbYap+DY='))
  File "...\src\bitcoin.py", line 597, in verify_message
    assert_bytes(sig, message)
  File "...\src\util.py", line 255, in assert_bytes
    assert isinstance(x, (bytes, bytearray))
AssertionError

EC_KEY.sign_message:

Traceback (most recent call last):
  File "test.py", line 9, in
    key = bitcoin.EC_KEY('L4xnRyP8ARQHZ1BwVkUVfk8sMkXsyBJxd9zhEMXci6NjHkFd9ewp')
  File "...\src\bitcoin.py", line 722, in __init__
    secret = string_to_number(k)
  File "...\Python\Python35\lib\site-packages\ecdsa\util.py", line 175, in string_to_number
    return int(binascii.hexlify(string), 16)
TypeError: a bytes-like object is required, not 'str'


I can't for the life of me figure out what's wrong, considering I'm not changing anything from the codebase.


Any help is appreciated. Cheers!
Jump to: