Browse Source

minor fixes and cleanups

The MMGen Project 2 years ago
parent
commit
3510841a12
5 changed files with 28 additions and 27 deletions
  1. 8 14
      mmgen/base_proto/ethereum/misc.py
  2. 13 6
      mmgen/main_msg.py
  3. 6 6
      mmgen/msg.py
  4. 0 1
      mmgen/tool/coin.py
  5. 1 0
      test/test_py_d/ts_ethdev.py

+ 8 - 14
mmgen/base_proto/ethereum/misc.py

@@ -12,7 +12,7 @@
 base_proto.ethereum.misc: miscellaneous utilities for Ethereum base protocol
 """
 
-from ...util import die
+from ...util import die,get_keccak
 
 def extract_key_from_geth_keystore_wallet(wallet_fn,passwd,check_addr=True):
 	"""
@@ -41,7 +41,6 @@ def extract_key_from_geth_keystore_wallet(wallet_fn,passwd,check_addr=True):
 		dklen    = sp['dklen'] )
 
 	# Check password by comparing generated MAC to stored MAC
-	from ...util import get_keccak
 	mac_chk = get_keccak()(hashed_pw[16:32] + bytes.fromhex( cdata['ciphertext'] )).digest().hex()
 	if mac_chk != cdata['mac']:
 		die(1,'Incorrect passphrase')
@@ -67,19 +66,19 @@ def extract_key_from_geth_keystore_wallet(wallet_fn,passwd,check_addr=True):
 
 	return key
 
+def hash_message(message):
+	return get_keccak()(
+		'\x19Ethereum Signed Message:\n{}{}'.format( len(message), message ).encode()
+	).digest()
+
 def ec_sign_message_with_privkey(message,key):
 	"""
 	Sign an arbitrary string with an Ethereum private key, returning the signature
 
 	Conforms to the standard defined by the Geth `eth_sign` JSON-RPC call
 	"""
-	from ...util import get_keccak
-	msghash = get_keccak()(
-		'\x19Ethereum Signed Message:\n{}{}'.format( len(message), message ).encode()
-	).digest()
-
 	from py_ecc.secp256k1 import ecdsa_raw_sign
-	v,r,s = ecdsa_raw_sign( msghash, key )
+	v,r,s = ecdsa_raw_sign( hash_message(message), key )
 	return '{:064x}{:064x}{:02x}'.format(r,s,v)
 
 def ec_recover_pubkey(message,sig):
@@ -89,13 +88,8 @@ def ec_recover_pubkey(message,sig):
 
 	Conforms to the standard defined by the Geth `eth_sign` JSON-RPC call
 	"""
-	from ...util import get_keccak
-	msghash = get_keccak()(
-		'\x19Ethereum Signed Message:\n{}{}'.format( len(message), message ).encode()
-	).digest()
-
 	from py_ecc.secp256k1 import ecdsa_raw_recover
 	r,s,v = ( sig[:64], sig[64:128], sig[128:] )
 	return '{:064x}{:064x}'.format(
-		*ecdsa_raw_recover( msghash, tuple(int(hexstr,16) for hexstr in (v,r,s)) )
+		*ecdsa_raw_recover( hash_message(message), tuple(int(hexstr,16) for hexstr in (v,r,s)) )
 	)

+ 13 - 6
mmgen/main_msg.py

@@ -81,14 +81,15 @@ opts_data = {
 		'usage2': [
 			'[opts] create MESSAGE_TEXT ADDRESS_SPEC [...]',
 			'[opts] sign   MESSAGE_FILE [WALLET_FILE ...]',
-			'[opts] verify MESSAGE_FILE or exported JSON dump',
-			'[opts] export MESSAGE_FILE',
+			'[opts] verify MESSAGE_FILE [MMGen ID]',
+			'[opts] verify <exported JSON dump file> [address]',
+			'[opts] export MESSAGE_FILE [MMGen ID]',
 		],
 		'options': """
--h, --help      Print this help message
---, --longhelp  Print help message for long options (common options)
--d, --outdir=d  Output file to directory 'd' instead of working dir
--q, --quiet     Produce quieter output
+-h, --help           Print this help message
+--, --longhelp       Print help message for long options (common options)
+-d, --outdir=d       Output file to directory 'd' instead of working dir
+-q, --quiet          Produce quieter output
 """,
 	'notes': """
 
@@ -168,6 +169,12 @@ $ mmgen-msg verify <signed message file> DEADBEEF:B:98
 
 Export data relevant for a third-party verifier to ‘signatures.json’:
 $ mmgen-msg export <signed message file>
+
+Same as above, but export only one signature:
+$ mmgen-msg export <signed message file> DEADBEEF:B:98
+
+Verify and display the exported JSON signature data:
+$ mmgen-msg verify signatures.json
 """
 	},
 	'code': {

+ 6 - 6
mmgen/msg.py

@@ -171,10 +171,10 @@ class coin_msg:
 						yield res
 
 			hdr_data = {
-				'message':     ('Message:',         lambda v: grnbg(v) ),
-				'network':     ('Network:',         lambda v: v.replace('_',' ').upper() ),
-				'addrlists':   ('Address Ranges:',  lambda v: fmt_list(v,fmt='bare') ),
-				'failed_sids': ('Failed Seed IDs:', lambda v: red(fmt_list(v,fmt='bare')) ),
+				'message':      ('Message:',           lambda v: grnbg(v) ),
+				'network':      ('Network:',           lambda v: v.replace('_',' ').upper() ),
+				'addrlists':    ('Address Ranges:',    lambda v: fmt_list(v,fmt='bare') ),
+				'failed_sids':  ('Failed Seed IDs:',   lambda v: red(fmt_list(v,fmt='bare')) ),
 			}
 
 			if req_addr or type(self).__name__ == 'exported_sigs':
@@ -332,8 +332,8 @@ class coin_msg:
 					desc   = self.desc )
 				)
 
-			self.sigs = {sig['addr']:sig for sig in (
-				[{k:v[2:] for k,v in e.items()} for e in self.data['signatures']]
+			self.sigs = {sig_data['addr']:sig_data for sig_data in (
+				[{k:v[2:] for k,v in e.items()} for e in self.data['signatures']] # remove '0x' prefix
 					if self.proto.base_proto == 'Ethereum' else
 				self.data['signatures']
 			)}

+ 0 - 1
mmgen/tool/coin.py

@@ -168,7 +168,6 @@ class tool_cmd(tool_cmd_base):
 
 	def addr2pubhash(self,addr:'sstr'):
 		"convert coin address to public key hash"
-		from ..opts import opt
 		ap = self.proto.parse_addr(addr)
 		assert ap, f'coin address {addr!r} could not be parsed'
 		if ap.fmt not in MMGenAddrType.pkh_fmts:

+ 1 - 0
test/test_py_d/ts_ethdev.py

@@ -691,6 +691,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
 		imsg(f'Message:   {self.message}')
 		imsg(f'Signature: {sig}')
 		cmp_or_die(sig,sig_chk,'message signatures')
+		imsg('Geth and MMGen signatures match')
 
 		return 'ok'