Skip to content

Commit

Permalink
mmgen-tool: rewrite 'rand2file', add test
Browse files Browse the repository at this point in the history
  • Loading branch information
mmgen committed Mar 21, 2019
1 parent f7b5902 commit 7cc69a2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 34 deletions.
2 changes: 1 addition & 1 deletion mmgen/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ def write_to_file(self):
msg('File size must be an integer no less than {}'.format(min_fsize))

from mmgen.tool import MMGenToolCmd
MMGenToolCmd().rand2file(fn,str(fsize)) # threaded routine TODO: check safe
MMGenToolCmd().rand2file(fn,str(fsize))
check_offset = False
else:
die(1,'Exiting at user request')
Expand Down
67 changes: 34 additions & 33 deletions mmgen/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,61 +587,62 @@ def find_incog_data(self,filename:str,incog_id:str,keep_searching=False):

def rand2file(self,outfile:str,nbytes:str,threads=4,silent=False):
"write 'n' bytes of random data to specified file"
nbytes = parse_bytespec(nbytes)
from Crypto import Random
rh = Random.new()
from queue import Queue
from threading import Thread
bsize = 2**20
roll = bsize * 4
if opt.outdir: outfile = make_full_path(opt.outdir,outfile)
f = open(outfile,'wb')

from Crypto.Cipher import AES
from Crypto.Util import Counter

key = get_random(32)
from queue import Queue
from cryptography.hazmat.primitives.ciphers import Cipher,algorithms,modes
from cryptography.hazmat.backends import default_backend

def encrypt_worker(wid):
ctr_init_val = os.urandom(g.aesctr_iv_len)
c = Cipher(algorithms.AES(key),modes.CTR(ctr_init_val),backend=default_backend())
encryptor = c.encryptor()
while True:
i,d = q1.get()
c = AES.new(key,AES.MODE_CTR,counter=Counter.new(g.aesctr_iv_len*8,initial_value=i))
enc_data = c.encrypt(d)
q2.put(enc_data)
q2.put(encryptor.update(q1.get()))
q1.task_done()

def output_worker():
while True:
data = q2.get()
f.write(data)
f.write(q2.get())
q2.task_done()

q1 = Queue()
nbytes = parse_bytespec(nbytes)
if opt.outdir:
outfile = make_full_path(opt.outdir,outfile)
f = open(outfile,'wb')

key = get_random(32)
q1,q2 = Queue(),Queue()

for i in range(max(1,threads-2)):
t = Thread(target=encrypt_worker,args=(i,))
t = Thread(target=encrypt_worker,args=[i])
t.daemon = True
t.start()

q2 = Queue()
t = Thread(target=output_worker)
t.daemon = True
t.start()

i = 1; rbytes = nbytes
while rbytes > 0:
d = rh.read(min(bsize,rbytes))
q1.put((i,d))
rbytes -= bsize
i += 1
if not (bsize*i) % roll:
msg_r('\rRead: {} bytes'.format(bsize*i))
blk_size = 1024 * 1024
for i in range(nbytes // blk_size):
if not i % 4:
msg_r('\rRead: {} bytes'.format(i * blk_size))
q1.put(os.urandom(blk_size))

if nbytes % blk_size:
q1.put(os.urandom(nbytes % blk_size))

if not silent:
msg('\rRead: {} bytes'.format(nbytes))
qmsg("\r{} bytes of random data written to file '{}'".format(nbytes,outfile))
q1.join()
q2.join()
f.close()

fsize = os.stat(outfile).st_size
if fsize != nbytes:
die(3,'{}: incorrect random file size (should be {})'.format(fsize,nbytes))

if not silent:
msg('\rRead: {} bytes'.format(nbytes))
qmsg("\r{} byte{} of random data written to file '{}'".format(nbytes,suf(nbytes),outfile))

return True

class MMGenToolCmdWallet(MMGenToolCmdBase):
Expand Down
17 changes: 17 additions & 0 deletions test/test_py_d/ts_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,28 @@ class TestSuiteTool(TestSuiteMain,TestSuiteBase):
enc_infn = 'tool_encrypt.in'
cmd_group = (
('tool_find_incog_data', (9,"'mmgen-tool find_incog_data'", [[[hincog_fn],1],[[incog_id_fn],1]])),
('tool_rand2file', (9,"'mmgen-tool rand2file'", [])),
('tool_encrypt', (9,"'mmgen-tool encrypt' (random data)", [])),
('tool_decrypt', (9,"'mmgen-tool decrypt' (random data)", [[[enc_infn+'.mmenc'],9]])),
# ('tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)", [])),
)

def tool_rand2file(self):
outfile = os.path.join(self.tmpdir,'rand2file.out')
from mmgen.tool import MMGenToolCmd
tu = MMGenToolCmd()
for nbytes in ('1','1023','1K','1048575','1M','1048577','123M'):
t = self.spawn( 'mmgen-tool',
['-d',self.tmpdir,'-r0','rand2file','rand2file.out',nbytes],
extra_desc='({} byte{})'.format(nbytes,suf(tu.bytespec(nbytes)))
)
t.expect('random data written to file')
t.read()
t.p.wait()
t.ok()
t.skip_ok = True
return t

def tool_encrypt(self):
infile = joinpath(self.tmpdir,self.enc_infn)
write_to_file(infile,os.urandom(1033),binary=True)
Expand Down

0 comments on commit 7cc69a2

Please sign in to comment.