add_user_random(): minor cleanups
This commit is contained in:
parent
c2dc09cbf3
commit
1f7cfafd96
4 changed files with 42 additions and 40 deletions
|
|
@ -25,27 +25,6 @@ from cryptography.hazmat.backends import default_backend
|
|||
from hashlib import sha256
|
||||
from .common import *
|
||||
|
||||
crmsg = {
|
||||
'usr_rand_notice': """
|
||||
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.
|
||||
"""
|
||||
}
|
||||
|
||||
def sha256_rounds(s,n):
|
||||
for i in range(n):
|
||||
s = sha256(s).digest()
|
||||
|
|
@ -152,53 +131,74 @@ 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,desc,test_suite=False):
|
||||
m = 'Enter {r} random symbols' if opt.quiet or test_suite else crmsg['usr_rand_notice']
|
||||
msg(m.format(r=uchars,d=desc))
|
||||
def _get_random_data_from_user(uchars,desc):
|
||||
info1 = f"""
|
||||
Now we're going to gather some additional input from the keyboard to further
|
||||
randomize the random data {desc}.
|
||||
|
||||
An encryption key will be created from this input, and the random data will
|
||||
be encrypted using the key. The resulting data is guaranteed to be at least
|
||||
as random as the original random data, 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 letters as well as punctuation and numerals. The timings
|
||||
between your keystrokes will also be used as a source of entropy, so be as
|
||||
random as possible in your timing as well.
|
||||
"""
|
||||
info2 = f"""
|
||||
Please type {uchars} symbols on your keyboard. What you type will not be displayed
|
||||
on the screen.
|
||||
"""
|
||||
|
||||
msg(f'Enter {uchars} random symbols' if opt.quiet else
|
||||
'\n{}\n{}'.format( fmt(info1,indent=' '), fmt(info2) ))
|
||||
|
||||
prompt = 'You may begin typing. {} symbols left: '
|
||||
|
||||
import time
|
||||
from .term import get_char_raw
|
||||
key_data,time_data = '',[]
|
||||
key_data = ''
|
||||
time_data = []
|
||||
|
||||
for i in range(uchars):
|
||||
key_data += get_char_raw('\r'+prompt.format(uchars-i))
|
||||
time_data.append(time.time())
|
||||
|
||||
msg_r('\r' if opt.quiet else "\rThank you. That's enough.{}\n\n".format(' '*18))
|
||||
msg_r( '\r' if opt.quiet else f"\rThank you. That's enough.{' '*18}\n\n" )
|
||||
|
||||
time_data = ['{:.22f}'.format(t).rstrip('0') for t in time_data]
|
||||
|
||||
avg_prec = sum(len(t.split('.')[1]) for t in time_data) // len(time_data)
|
||||
|
||||
if avg_prec < g.min_time_precision:
|
||||
m = 'WARNING: Avg. time precision of only {} decimal points. User entropy quality is degraded!'
|
||||
ymsg(m.format(avg_prec))
|
||||
ymsg(f'WARNING: Avg. time precision of only {avg_prec} decimal points. User entropy quality is degraded!')
|
||||
|
||||
ret = key_data + '\n' + '\n'.join(time_data)
|
||||
|
||||
if g.debug:
|
||||
msg('USER ENTROPY (user input + keystroke timings):\n{}'.format(ret))
|
||||
msg(f'USER ENTROPY (user input + keystroke timings):\n{ret}')
|
||||
|
||||
if not test_suite:
|
||||
my_raw_input('User random data successfully acquired. Press ENTER to continue: ')
|
||||
my_raw_input('User random data successfully acquired. Press ENTER to continue: ')
|
||||
|
||||
return ret.encode()
|
||||
|
||||
def get_random(length):
|
||||
return add_user_random(os.urandom(length),'OS random data')
|
||||
return add_user_random(
|
||||
rand_bytes = os.urandom(length),
|
||||
desc = 'generated by your operating system' )
|
||||
|
||||
def add_user_random(rand_bytes,desc):
|
||||
assert type(rand_bytes) == bytes, (
|
||||
"{!r}: invalid type for 'rand_bytes'".format(type(rand_bytes).__name__) )
|
||||
assert type(rand_bytes) == bytes, 'add_user_random_chk1'
|
||||
if opt.usr_randchars:
|
||||
if not g.user_entropy:
|
||||
g.user_entropy = \
|
||||
sha256(_get_random_data_from_user(opt.usr_randchars,desc)).digest()
|
||||
g.user_entropy = sha256(_get_random_data_from_user(opt.usr_randchars,desc)).digest()
|
||||
urand_desc = 'user-supplied entropy'
|
||||
else:
|
||||
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))
|
||||
msg(f'Encrypting random data {desc} with key')
|
||||
return encrypt_data(rand_bytes,key,desc=desc,verify=False)
|
||||
else:
|
||||
return rand_bytes
|
||||
|
|
|
|||
|
|
@ -565,7 +565,9 @@ class DieRollSeedFile(WalletUnenc):
|
|||
|
||||
if self.interactive_input and opt.usr_randchars:
|
||||
if keypress_confirm(self.user_entropy_prompt):
|
||||
seed_bytes = add_user_random(seed_bytes,'die roll data')
|
||||
seed_bytes = add_user_random(
|
||||
rand_bytes = seed_bytes,
|
||||
desc = 'gathered from your die rolls' )
|
||||
self.desc += ' plus user-supplied entropy'
|
||||
|
||||
self.seed = Seed(seed_bytes)
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
|
|||
t.usr_rand(self.usr_rand_chars)
|
||||
|
||||
if ocls.__name__.startswith('Incog'):
|
||||
m = 'Encrypting OS random data with key'
|
||||
m = 'Encrypting random data generated by your operating system with key'
|
||||
t.expect(m)
|
||||
t.expect(m)
|
||||
incog_id = t.expect_getend('New Incog Wallet ID: ')
|
||||
|
|
|
|||
|
|
@ -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('Encrypting OS random data with key')
|
||||
t.expect('Encrypting random data generated by your operating system with key')
|
||||
if wcls == IncogWalletHidden:
|
||||
t.hincog_create(hincog_bytes)
|
||||
if out_fmt == 'w':
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue