From 809fd0503d63015f5b2523bf7f7b4709a86191db Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 30 Oct 2019 09:33:57 +0000 Subject: [PATCH] crypto.py: get_random() -> add_user_random(), UI cleanups & fixes --- mmgen/crypto.py | 50 ++++++++++++++++++++++++------------- test/pexpect.py | 4 --- test/test_py_d/ts_main.py | 5 ++-- test/test_py_d/ts_wallet.py | 2 +- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/mmgen/crypto.py b/mmgen/crypto.py index f3151650..8efcc75f 100755 --- a/mmgen/crypto.py +++ b/mmgen/crypto.py @@ -27,12 +27,22 @@ from mmgen.common import * crmsg = { 'usr_rand_notice': """ -Since we don't fully trust our OS's random number generator, we'll provide -some additional entropy of our own. Please type {} symbols on your keyboard. -Type slowly and choose your symbols carefully for maximum randomness. Try to -use both upper and lowercase as well as punctuation and numerals. What you -type will not be displayed on the screen. Note that the timings between your -keystrokes will also be used as a source of randomness. +Now we're going to gather some additional input from the keyboard to +further randomize the {d} we've already gathered. + +An encryption key will be created from this input, and the {d} +will be encrypted using the key. The resulting data is guaranteed to be at +least as random as the original {d}, so even if you type very +predictably no harm will be done. + +However, to gain the maximum benefit, try making your input as random as +possible. Type slowly and choose your symbols carefully. Try to use both +upper and lowercase as well as punctuation and numerals. The timings between +your keystrokes will also be used as a source of entropy, so be as +unpredictable as possible in your timing as well. + +Please type {r} symbols on your keyboard. What you type will not be displayed +on the screen. """ } @@ -142,9 +152,9 @@ def make_key(passwd,salt,hash_preset,desc='encryption key',from_what='passphrase dmsg('Key: {}'.format(key.hex())) return key -def _get_random_data_from_user(uchars): - m = 'Enter {} random symbols' if opt.quiet else crmsg['usr_rand_notice'] - msg(m.format(uchars)) +def _get_random_data_from_user(uchars,desc): + m = 'Enter {r} random symbols' if opt.quiet else crmsg['usr_rand_notice'] + msg(m.format(r=uchars,d=desc)) prompt = 'You may begin typing. {} symbols left: ' import time @@ -163,22 +173,26 @@ def _get_random_data_from_user(uchars): prompt = 'User random data successfully acquired. Press ENTER to continue' prompt_and_get_char(prompt,'',enter_ok=True) - return key_data+''.join(fmt_time_data).encode() + return key_data + ''.join(fmt_time_data).encode() def get_random(length): - os_rand = os.urandom(length) + return add_user_random(os.urandom(length),'OS random data') + +def add_user_random(rand_bytes,desc): + assert type(rand_bytes) == bytes, ( + "{!r}: invalid type for 'rand_bytes'".format(type(rand_bytes).__name__) ) if opt.usr_randchars: - from_what = 'OS random data' if not g.user_entropy: g.user_entropy = \ - sha256(_get_random_data_from_user(opt.usr_randchars)).digest() - from_what += ' plus user-supplied entropy' + sha256(_get_random_data_from_user(opt.usr_randchars,desc)).digest() + urand_desc = 'user-supplied entropy' else: - from_what += ' plus saved user-supplied entropy' - key = make_key(g.user_entropy,b'','2',from_what=from_what,verbose=True) - return encrypt_data(os_rand,key,desc='random data',verify=False) + urand_desc = 'saved user-supplied entropy' + key = make_key(g.user_entropy,b'','2',from_what=urand_desc,verbose=True) + msg('Encrypting {} with key'.format(desc)) + return encrypt_data(rand_bytes,key,desc=desc,verify=False) else: - return os_rand + return rand_bytes def get_hash_preset_from_user(hp=g.hash_preset,desc='data'): prompt = """Enter hash preset for {}, diff --git a/test/pexpect.py b/test/pexpect.py index 9023c3fb..9be697d7 100755 --- a/test/pexpect.py +++ b/test/pexpect.py @@ -95,10 +95,6 @@ class MMGenPexpect(object): def label(self,label='Test Label (UTF-8) α'): self.expect('Enter a wallet label, or hit ENTER for no label: ',label+'\n') - def usr_rand_out(self,saved=False): - fs = 'Generating encryption key from OS random data plus {}user-supplied entropy' - self.expect(fs.format(('','saved ')[saved])) - def usr_rand(self,num_chars): if opt.usr_random: self.interactive() diff --git a/test/test_py_d/ts_main.py b/test/test_py_d/ts_main.py index 0928a41d..34dea64d 100755 --- a/test/test_py_d/ts_main.py +++ b/test/test_py_d/ts_main.py @@ -511,8 +511,9 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared): t.usr_rand(self.usr_rand_chars) if ocls.__name__.startswith('Incog'): - m = 'Generating encryption key from OS random data ' - t.expect(m); t.expect(m) + m = 'Encrypting OS random data with key' + t.expect(m) + t.expect(m) incog_id = t.expect_getend('New Incog Wallet ID: ') t.expect(m) if ocls == IncogWalletHidden: diff --git a/test/test_py_d/ts_wallet.py b/test/test_py_d/ts_wallet.py index 99cab508..37828c8a 100755 --- a/test/test_py_d/ts_wallet.py +++ b/test/test_py_d/ts_wallet.py @@ -208,7 +208,7 @@ class TestSuiteWalletConv(TestSuiteBase,TestSuiteShared): t.usr_rand(self.usr_rand_chars) if wcls in (IncogWallet,IncogWalletHex,IncogWalletHidden): for i in (1,2,3): - t.expect('Generating encryption key from OS random data ') + t.expect('Encrypting OS random data with key') if wcls == IncogWalletHidden: t.hincog_create(hincog_bytes) if out_fmt == 'w':