diff --git a/docs/frost-wallet-dev.md b/docs/frost-wallet-dev.md index af68f23..743c14d 100644 --- a/docs/frost-wallet-dev.md +++ b/docs/frost-wallet-dev.md @@ -240,13 +240,11 @@ self.mcc.prepare_privmsg(nick, 'frostinit', init_msg) part of FROST exchange ``` -round1_msg = f'{session_id} {hostpubkeyhash} {pub_nonce}' +round1_msg = f'{session_id} pub_nonce}' self.mcc.prepare_privmsg(nick, "frostround1", round1_msg) ``` - `session_id`: 32 bytes to idenify FROST session -- `hostpubkeyhash`: sha256 hash of wallet `hostpubkey` to identify -wallet for coordinator - `pub_nonce`: public part of `sec_nonce`/`pub_nonce` pair **frostagg1**: private encrypted command from coorinator to send aggregated diff --git a/src/jmbase/commands.py b/src/jmbase/commands.py index ba7f149..849ca9f 100644 --- a/src/jmbase/commands.py +++ b/src/jmbase/commands.py @@ -152,7 +152,6 @@ class JMFROSTRound1(JMCommand): arguments = [ (b'nick', Unicode()), (b'session_id', Unicode()), - (b'hostpubkeyhash', Unicode()), (b'pub_nonce', Unicode()), ] @@ -365,7 +364,6 @@ class JMFROSTRound1Seen(JMCommand): arguments = [ (b'nick', Unicode()), (b'session_id', Unicode()), - (b'hostpubkeyhash', Unicode()), (b'pub_nonce', Unicode()), ] diff --git a/src/jmclient/client_protocol.py b/src/jmclient/client_protocol.py index 6429d7e..bbd7af7 100644 --- a/src/jmclient/client_protocol.py +++ b/src/jmclient/client_protocol.py @@ -641,20 +641,17 @@ class JMClientProtocol(BaseClientProtocol): client = self.factory.client session_id = hextobin(session_id) - nick, session_id, pubkeyhash, pub_nonce = \ - client.on_frost_init(nick, session_id) + nick, session_id, pub_nonce = client.on_frost_init(nick, session_id) if pub_nonce: pub_nonce_b64 = base64.b64encode(pub_nonce).decode('ascii') d = self.callRemote(commands.JMFROSTRound1, nick=nick, session_id=session_id, - hostpubkeyhash=pubkeyhash, pub_nonce=pub_nonce_b64) self.defaultCallbacks(d) return {'accepted': True} @commands.JMFROSTRound1Seen.responder - def on_JM_FROST_ROUND1_SEEN(self, nick, session_id, - hostpubkeyhash, pub_nonce): + def on_JM_FROST_ROUND1_SEEN(self, nick, session_id, pub_nonce): wallet = self.client.wallet_service.wallet if not isinstance(wallet, FrostWallet) or wallet._dkg is None: return {'accepted': True} @@ -663,8 +660,7 @@ class JMClientProtocol(BaseClientProtocol): bin_session_id = hextobin(session_id) pub_nonce = base64.b64decode(pub_nonce) ready_nicks, nonce_agg, dkg_session_id, ids, msg = \ - client.on_frost_round1( - nick, bin_session_id, hostpubkeyhash, pub_nonce) + client.on_frost_round1(nick, bin_session_id, pub_nonce) if ready_nicks and nonce_agg: for nick in ready_nicks: self.frost_agg1(nick, session_id, nonce_agg, diff --git a/src/jmclient/frost_clients.py b/src/jmclient/frost_clients.py index b8544e4..cd3ca64 100644 --- a/src/jmclient/frost_clients.py +++ b/src/jmclient/frost_clients.py @@ -796,12 +796,20 @@ class FROSTClient(DKGClient): def on_frost_ack(self, nick, hostpubkeyhash, sig, session_id): try: + coordinator = self.frost_coordinators.get(session_id) + if not coordinator: + raise Exception(f'session {session_id.hex()} not found') pubkey = self.find_pubkey_by_pubkeyhash(hostpubkeyhash) if not pubkey: raise Exception(f'pubkey for {hostpubkeyhash} not found') xpubkey = XOnlyPubKey(pubkey[1:]) if not xpubkey.verify_schnorr(session_id, hextobin(sig)): raise Exception('signature verification failed') + if pubkey in coordinator.parties: + jlog.debug(f'pubkey {pubkey.hex()} already in' + f' coordinator parties') + return False + coordinator.parties[pubkey] = nick return True except Exception as e: jlog.error(f'on_frost_ack: {repr(e)}') @@ -815,15 +823,11 @@ class FROSTClient(DKGClient): if session.sec_nonce: raise Exception(f'session.sec_nonce already set ' f'for {session_id.hex()}') - wallet = self.wallet_service.wallet - hostseckey = wallet._hostseckey[:32] - hostpubkey = hostpubkey_gen(hostseckey) - pubkeyhash = sha256(hostpubkey).digest() pub_nonce = self.frost_round1(session_id) - return (nick, session_id.hex(), pubkeyhash.hex(), pub_nonce) + return (nick, session_id.hex(), pub_nonce) except Exception as e: jlog.error(f'on_frost_init: {repr(e)}') - return None, None, None, None + return None, None, None def frost_round1(self, session_id): try: @@ -841,7 +845,7 @@ class FROSTClient(DKGClient): except Exception as e: jlog.error(f'frost_round1: {repr(e)}') - def on_frost_round1(self, nick, session_id, pubkeyhash, pub_nonce): + def on_frost_round1(self, nick, session_id, pub_nonce): try: coordinator = self.frost_coordinators.get(session_id) if not coordinator: @@ -850,14 +854,14 @@ class FROSTClient(DKGClient): jlog.debug('on_frost_round1: miminum pub_nonce set already ' 'presented, ignoring additional pub_nonce') return None, None, None, None, None - pubkey = self.find_pubkey_by_pubkeyhash(pubkeyhash) - if not pubkey: - raise Exception(f'pubkey for {pubkeyhash} not found') - if pubkey in coordinator.parties: - jlog.debug(f'pubkey {pubkey.hex()} already in' + pubkey = None + for party_pubk, party_nick in coordinator.parties.items(): + if party_nick == nick: + pubkey = party_pubk + if pubkey is None: + jlog.debug(f'pubkey for nick {nick} not found in the' f' coordinator parties') return None, None, None, None, None - coordinator.parties[pubkey] = nick if not pubkey in coordinator.sessions: coordinator.sessions[pubkey] = {} diff --git a/src/jmdaemon/daemon_protocol.py b/src/jmdaemon/daemon_protocol.py index 80be05b..d253a96 100644 --- a/src/jmdaemon/daemon_protocol.py +++ b/src/jmdaemon/daemon_protocol.py @@ -762,12 +762,12 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch): return {'accepted': True} @JMFROSTRound1.responder - def on_JM_FROST_ROUND1(self, nick, hostpubkeyhash, session_id, pub_nonce): + def on_JM_FROST_ROUND1(self, nick, session_id, pub_nonce): self.frost_expected_msgs[nick]['frostagg1'] = { 'session_id': session_id, 'created': time.time(), } - round1_msg = f'{session_id} {hostpubkeyhash} {pub_nonce}' + round1_msg = f'{session_id} {pub_nonce}' self.mcc.prepare_privmsg(nick, "frostround1", round1_msg) return {'accepted': True} @@ -1013,10 +1013,9 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch): nick=nick, session_id=session_id) self.defaultCallbacks(d) - def on_frostround1(self, nick, session_id, hostpubkeyhash, pub_nonce): + def on_frostround1(self, nick, session_id, pub_nonce): d = self.callRemote(JMFROSTRound1Seen, nick=nick, session_id=session_id, - hostpubkeyhash=hostpubkeyhash, pub_nonce=pub_nonce) self.defaultCallbacks(d) diff --git a/src/jmdaemon/message_channel.py b/src/jmdaemon/message_channel.py index 6212e8e..94364f3 100644 --- a/src/jmdaemon/message_channel.py +++ b/src/jmdaemon/message_channel.py @@ -1216,11 +1216,9 @@ class MessageChannel(object): self.on_frostinit(nick, session_id) elif _chunks[0] == 'frostround1': session_id = _chunks[1] - pubkeyhash = _chunks[2] - pub_nonce = _chunks[3] + pub_nonce = _chunks[2] if self.on_frostround1: - self.on_frostround1( - nick, session_id, pubkeyhash, pub_nonce) + self.on_frostround1(nick, session_id, pub_nonce) elif _chunks[0] == 'frostagg1': session_id = _chunks[1] nonce_agg = _chunks[2]