Browse Source

workaround for broken hashlib.scrypt()

MMGen 5 years ago
parent
commit
1c5277572e
2 changed files with 18 additions and 6 deletions
  1. 14 3
      mmgen/crypto.py
  2. 4 3
      mmgen/globalvars.py

+ 14 - 3
mmgen/crypto.py

@@ -111,14 +111,25 @@ def scrypt_hash_passphrase(passwd,salt,hash_preset,buflen=32):
 	N,r,p = get_hash_params(hash_preset)
 	if type(passwd) == str: passwd = passwd.encode()
 
-	try:
-		assert not g.use_standalone_scrypt_module
+	def do_hashlib_scrypt():
 		from hashlib import scrypt # Python >= v3.6
 		return scrypt(passwd,salt=salt,n=2**N,r=r,p=p,maxmem=0,dklen=buflen)
-	except:
+
+	def do_standalone_scrypt():
 		import scrypt
 		return scrypt.hash(passwd,salt,2**N,r,p,buflen=buflen)
 
+	msg_r('Hashing passphrase...')
+	# hashlib.scrypt doesn't support N > 14 (hash preset 3)
+	if N > 14 or g.force_standalone_scrypt_module:
+		ret = do_standalone_scrypt()
+	else:
+		try: ret = do_hashlib_scrypt()
+		except: ret = do_standalone_scrypt()
+	msg('done')
+
+	return ret
+
 def make_key(passwd,salt,hash_preset,desc='encryption key',from_what='passphrase',verbose=False):
 	if from_what: desc += ' from '
 	if opt.verbose or verbose:

+ 4 - 3
mmgen/globalvars.py

@@ -221,10 +221,11 @@ class g(object):
 	key_generators = 'python-ecdsa','secp256k1' # '1','2'
 	key_generator  = 2 # secp256k1 is default
 
-	use_standalone_scrypt_module = False
+	force_standalone_scrypt_module = False
+	# Scrypt params: 'id_num': [N, p, r] (N is an exponent of two)
+	# NB: hashlib.scrypt in Python (>=v3.6) supports max N value of 14.  This means that
+	# for hash presets > 3 the standalone scrypt library must be used!
 	hash_presets = {
-	#   Scrypt params:
-	#   ID    N   p  r (N is an exponent of two)
 		'1': [12, 8, 1],
 		'2': [13, 8, 4],
 		'3': [14, 8, 8],