electrum

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

commit fb00e29f1c5c1fffcc430c2084472eede6a2cdfa
parent fca5c9379f9770462fc2a5bd63b278d29ac7e76e
Author: SomberNight <somber.night@protonmail.com>
Date:   Fri, 20 Jul 2018 16:53:51 +0200

bolt-08 handshake must use ephemeral key

Diffstat:
Melectrum/ecc.py | 10+++++++---
Melectrum/lnbase.py | 20++++++++++----------
2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/electrum/ecc.py b/electrum/ecc.py @@ -280,9 +280,7 @@ class ECPubkey(object): """ assert_bytes(message) - randint = ecdsa.util.randrange(CURVE_ORDER) - ephemeral_exponent = number_to_string(randint, CURVE_ORDER) - ephemeral = ECPrivkey(ephemeral_exponent) + ephemeral = ECPrivkey.generate_random_key() ecdh_key = (self * ephemeral.secret_scalar).get_public_key_bytes(compressed=True) key = hashlib.sha512(ecdh_key).digest() iv, key_e, key_m = key[0:16], key[16:32], key[32:] @@ -390,6 +388,12 @@ class ECPrivkey(ECPubkey): def __repr__(self): return f"<ECPrivkey {self.get_public_key_hex()}>" + @classmethod + def generate_random_key(cls): + randint = ecdsa.util.randrange(CURVE_ORDER) + ephemeral_exponent = number_to_string(randint, CURVE_ORDER) + return ECPrivkey(ephemeral_exponent) + def get_secret_bytes(self) -> bytes: return number_to_string(self.secret_scalar, CURVE_ORDER) diff --git a/electrum/lnbase.py b/electrum/lnbase.py @@ -242,9 +242,7 @@ def get_bolt8_hkdf(salt, ikm): assert len(T1 + T2) == 64 return T1, T2 -def act1_initiator_message(hs, my_privkey): - #Get a new ephemeral key - epriv, epub = create_ephemeral_key(my_privkey) +def act1_initiator_message(hs, epriv, epub): hs.update(epub) ss = get_ecdh(epriv, hs.responder_pub) ck2, temp_k1 = get_bolt8_hkdf(hs.ck, ss) @@ -256,12 +254,12 @@ def act1_initiator_message(hs, my_privkey): assert len(msg) == 50 return msg -def privkey_to_pubkey(priv): +def privkey_to_pubkey(priv: bytes) -> bytes: return ecc.ECPrivkey(priv[:32]).get_public_key_bytes() -def create_ephemeral_key(privkey): - pub = privkey_to_pubkey(privkey) - return (privkey[:32], pub) +def create_ephemeral_key() -> (bytes, bytes): + privkey = ecc.ECPrivkey.generate_random_key() + return privkey.get_secret_bytes(), privkey.get_public_key_bytes() def aiosafe(f): @@ -349,7 +347,10 @@ class Peer(PrintError): async def handshake(self): hs = HandshakeState(self.pubkey) - msg = act1_initiator_message(hs, self.privkey) + # Get a new ephemeral key + epriv, epub = create_ephemeral_key() + + msg = act1_initiator_message(hs, epriv, epub) # act 1 self.writer.write(msg) rspns = await self.reader.read(2**10) @@ -358,8 +359,7 @@ class Peer(PrintError): assert bytes([hver]) == hs.handshake_version # act 2 hs.update(alice_epub) - myepriv, myepub = create_ephemeral_key(self.privkey) - ss = get_ecdh(myepriv, alice_epub) + ss = get_ecdh(epriv, alice_epub) ck, temp_k2 = get_bolt8_hkdf(hs.ck, ss) hs.ck = ck p = aead_decrypt(temp_k2, 0, hs.h, tag)