def testcase(self, blocklen, degree, comb_deg): """ Test case constructor :param function: :param cur_round: :param size_mb: :param blocklen: :param degree: :param comb_deg: :param data_file: :return: """ hwanalysis = HWAnalysis() hwanalysis.deg = degree hwanalysis.blocklen = blocklen hwanalysis.top_comb = comb_deg hwanalysis.comb_random = self.args.comb_random hwanalysis.top_k = self.top_k hwanalysis.combine_all_deg = self.all_deg hwanalysis.zscore_thresh = self.zscore_thresh hwanalysis.do_ref = None hwanalysis.skip_print_res = True hwanalysis.input_poly = self.input_poly hwanalysis.no_comb_and = self.args.no_comb_and hwanalysis.no_comb_xor = self.args.no_comb_xor hwanalysis.prob_comb = self.args.prob_comb hwanalysis.all_deg_compute = len(self.input_poly) == 0 hwanalysis.do_only_top_comb = self.args.only_top_comb hwanalysis.do_only_top_deg = self.args.only_top_deg hwanalysis.no_term_map = self.args.no_term_map hwanalysis.use_zscore_heap = self.args.topterm_heap hwanalysis.sort_best_zscores = max( common.replace_none([self.args.topterm_heap_k, self.top_k, 100])) hwanalysis.best_x_combinations = self.args.best_x_combinations return hwanalysis
def work(self): """ Main entry point - data processing. RandVerif is used to benchmark particular data sources, with different seeds. It takes e.g., AES-CTR(SHA256(random)), runs it 1000 times and stores the results. This particular computation was used to determine reference z-scores of the test. Another usual scenario is to take Java util.Random, seed it 1000 times with a different random seed and analyze the results. RandVerif supports supplying custom distinguishers so the whole space is not searched. This setup is used to assess found distinguishers on more data / independent data streams with different seeds. RandVerif produces results on STDOUT, it contains multiple sections, separated by -----BEGIN SECTION----- Sections contain stats (avg. z-score), all z-scores, the best distinguishers for further analysis... :return: """ self.blocklen = int(self.defset(self.args.blocklen, 128)) deg = int(self.defset(self.args.degree, 3)) tvsize_orig = int( self.defset(self.process_size(self.args.tvsize), 1024 * 256)) zscore_thresh = float(self.args.conf) rounds = int( self.args.rounds) if self.args.rounds is not None else None top_k = int(self.args.topk) if self.args.topk is not None else None top_comb = int(self.defset(self.args.combdeg, 2)) reffile = self.defset(self.args.reffile) all_deg = self.args.alldeg tvsize = tvsize_orig top_distinguishers = [] # Load input polynomials self.load_input_poly() script_path = common.get_script_path() logger.info( 'Basic settings, deg: %s, blocklen: %s, TV size: %s, rounds: %s' % (deg, self.blocklen, tvsize_orig, rounds)) total_terms = int(common.comb(self.blocklen, deg, True)) hwanalysis = HWAnalysis() hwanalysis.deg = deg hwanalysis.blocklen = self.blocklen hwanalysis.top_comb = top_comb hwanalysis.comb_random = self.args.comb_random hwanalysis.top_k = top_k hwanalysis.combine_all_deg = all_deg hwanalysis.zscore_thresh = zscore_thresh hwanalysis.do_ref = reffile is not None hwanalysis.skip_print_res = True hwanalysis.input_poly = self.input_poly hwanalysis.no_comb_and = self.args.no_comb_and hwanalysis.no_comb_xor = self.args.no_comb_xor hwanalysis.prob_comb = self.args.prob_comb hwanalysis.all_deg_compute = len(self.input_poly) == 0 hwanalysis.do_only_top_comb = self.args.only_top_comb hwanalysis.do_only_top_deg = self.args.only_top_deg hwanalysis.no_term_map = self.args.no_term_map hwanalysis.use_zscore_heap = self.args.topterm_heap hwanalysis.sort_best_zscores = max( common.replace_none([self.args.topterm_heap_k, top_k, 100])) hwanalysis.best_x_combinations = self.args.best_x_combinations logger.info('Initializing test') hwanalysis.init() dist_result_map = {} for idx, poly in enumerate(self.input_poly): dist_result_map[idx] = [] for test_idx in range(self.args.tests): seed = random.randint(0, 2**32 - 1) iobj = None if self.args.test_randc: path = os.path.realpath( os.path.join(script_path, '../assets/rndgen-c/rand')) cmd = '%s %s' % (path, seed) iobj = common.CommandStdoutInputObject(cmd=cmd, seed=seed, desc='randc-%s' % seed) elif self.args.test_randc_small: path = os.path.realpath( os.path.join(script_path, '../assets/rndgen-c-small/rand')) cmd = '%s %s' % (path, seed) iobj = common.CommandStdoutInputObject(cmd=cmd, seed=seed, desc='randc-small-%s' % seed) elif self.args.test_java: path = os.path.realpath( os.path.join(script_path, '../assets/rndgen-java/')) cmd = 'java -cp %s Main %s' % (path, seed) iobj = common.CommandStdoutInputObject(cmd=cmd, seed=seed, desc='randjava-%s' % seed) elif self.args.test_aes: iobj = common.AESInputObject(seed=seed) else: raise ValueError('No generator to test') size = iobj.size() logger.info( 'Testing input object: %s, size: %d kB, iteration: %d' % (iobj, size / 1024.0, test_idx)) # size smaller than TV? Adapt tv then if size >= 0 and size < tvsize: logger.info('File size is smaller than TV, updating TV to %d' % size) tvsize = size if tvsize * 8 % self.blocklen != 0: rem = tvsize * 8 % self.blocklen logger.warning( 'Input data size not aligned to the block size. ' 'Input bytes: %d, block bits: %d, rem: %d' % (tvsize, self.blocklen, rem)) tvsize -= rem // 8 logger.info('Updating TV to %d' % tvsize) hwanalysis.reset() logger.info('BlockLength: %d, deg: %d, terms: %d' % (self.blocklen, deg, total_terms)) with iobj: data_read = 0 cur_round = 0 while size < 0 or data_read < size: if rounds is not None and cur_round > rounds: break data = iobj.read(tvsize) bits = common.to_bitarray(data) if len(bits) == 0: logger.info('File read completely') break logger.info( 'Pre-computing with TV, deg: %d, blocklen: %04d, tvsize: %08d = %8.2f kB = %8.2f MB, ' 'round: %d, avail: %d' % (deg, self.blocklen, tvsize, tvsize / 1024.0, tvsize / 1024.0 / 1024.0, cur_round, len(bits))) hwanalysis.process_chunk(bits, None) cur_round += 1 pass res = hwanalysis.input_poly_last_res if res is not None and len(res) > 0: res_top = res[0] top_distinguishers.append((res_top, seed)) for cur in res: dist_result_map[cur.idx].append(cur.zscore) elif hwanalysis.last_res is not None and len( hwanalysis.last_res) > 0: res_top = hwanalysis.last_res[0] top_distinguishers.append((res_top, seed)) else: raise ValueError('No data from the analysis') logger.info('Finished processing %s ' % iobj) logger.info('Data read %s ' % iobj.data_read) logger.info('Read data hash %s ' % iobj.sha1.hexdigest()) all_zscores = [] print('-----BEGIN JSON-----') js = [] for dist in top_distinguishers: cr = collections.OrderedDict() cr['z'] = dist[0].zscore try: cr['d'] = dist[0].idx except: pass cr['seed'] = dist[1] js.append(cr) all_zscores.append(dist[0].zscore) print(json.dumps(js, indent=2)) print('-----BEGIN JSON-STATS-----') js = [] for idx in dist_result_map: cur = dist_result_map[idx] cr = collections.OrderedDict() cr['idx'] = idx cr['poly'] = common.poly2str(self.input_poly[idx]) cr['avg'] = sum([abs(x) for x in cur]) / float(len(cur)) cr['cnt'] = len(cur) cr['zscores'] = cur js.append(cr) print(json.dumps(js, indent=2)) print('-----BEGIN RUN-CONFIG-----') js = collections.OrderedDict() js['block'] = self.blocklen js['deg'] = deg js['top_comb'] = top_comb js['top_k'] = top_k js['tvsize'] = tvsize js['tests'] = self.args.tests js['prob_comb'] = self.args.prob_comb js['all_deg'] = all_deg print(json.dumps(js)) print('-----BEGIN Z-SCORES-NORM-----') print(all_zscores) print('-----BEGIN Z-SCORES-ABS-----') print([abs(x) for x in all_zscores]) print('-----BEGIN Z-SCORES-AVG-----') print(sum([abs(x) for x in all_zscores]) / float(len(all_zscores))) print('-----BEGIN Z-SCORES-NAVG-----') print(sum([x for x in all_zscores]) / float(len(all_zscores))) if self.args.csv_zscore: print('-----BEGIN Z-SCORES-CSV-----') print('zscore') for x in [abs(x) for x in all_zscores]: print(x) logger.info('Processing finished')
def work(self): """ Main entry point - data processing :return: """ start=time.time() self.blocklen = int(self.defset(self.args.blocklen, 128)) deg = int(self.defset(self.args.degree, 3)) tvsize_orig = int(self.defset(self.process_size(self.args.tvsize), 1024*256)) zscore_thresh = float(self.args.conf) rounds = int(self.args.rounds) if self.args.rounds is not None else None top_k = int(self.args.topk) if self.args.topk is not None else None top_comb = int(self.defset(self.args.combdeg, 2)) reffile = self.defset(self.args.reffile) all_deg = self.args.alldeg # Load input polynomials self.load_input_poly() self.load_input_objects() logger.info('Basic settings, deg: %s, blocklen: %s, TV size: %s, rounds: %s' % (deg, self.blocklen, tvsize_orig, rounds)) # specific polynomial testing logger.info('Initialising') # read file by file for iobj in self.input_objects: tvsize = tvsize_orig iobj.check() size = iobj.size() logger.info('Testing input object: %s, size: %d kB' % (iobj, size/1024.0)) # size smaller than TV? Adapt tv then if size >= 0 and size < tvsize: logger.info('File size is smaller than TV, updating TV to %d' % size) tvsize = size if tvsize*8 % self.blocklen != 0: rem = tvsize*8 % self.blocklen logger.warning('Input data size not aligned to the block size. ' 'Input bytes: %d, block bits: %d, rem: %d' % (tvsize, self.blocklen, rem)) tvsize -= rem//8 logger.info('Updating TV to %d' % tvsize) hwanalysis = HWAnalysis() hwanalysis.deg = deg hwanalysis.blocklen = self.blocklen hwanalysis.top_comb = top_comb hwanalysis.comb_random = self.args.comb_random hwanalysis.top_k = top_k hwanalysis.combine_all_deg = all_deg hwanalysis.zscore_thresh = zscore_thresh hwanalysis.do_ref = reffile is not None hwanalysis.input_poly = self.input_poly hwanalysis.no_comb_and = self.args.no_comb_and hwanalysis.no_comb_xor = self.args.no_comb_xor hwanalysis.prob_comb = self.args.prob_comb hwanalysis.do_only_top_comb = self.args.only_top_comb hwanalysis.do_only_top_deg = self.args.only_top_deg hwanalysis.no_term_map = self.args.no_term_map hwanalysis.use_zscore_heap = self.args.topterm_heap hwanalysis.sort_best_zscores = max(common.replace_none([self.args.topterm_heap_k, top_k, 100])) hwanalysis.best_x_combinations = self.args.best_x_combinations hwanalysis.compute_on_cpu = self.args.compute_on_cpu hwanalysis.verify = self.args.verify # compute classical analysis only if there are no input polynomials hwanalysis.all_deg_compute = len(self.input_poly) == 0 logger.info('Initializing test') hwanalysis.init() total_terms = int(scipy.misc.comb(self.blocklen, deg, True)) logger.info('BlockLength: %d, deg: %d, terms: %d' % (self.blocklen, deg, total_terms)) # Reference data stream reading # Read the file until there is no data. fref = None if reffile is not None: fref = open(reffile, 'r') with iobj: data_read = 0 cur_round = 0 while size < 0 or data_read < size: if rounds is not None and cur_round > rounds: break data = iobj.read(tvsize) bits = common.to_bitarray(data) if len(bits) == 0: logger.info('File read completely') break ref_bits = None if fref is not None: ref_data = fref.read(tvsize) ref_bits = common.to_bitarray(ref_data) logger.info('Pre-computing with TV, deg: %d, blocklen: %04d, tvsize: %08d = %8.2f kB = %8.2f MB, ' 'round: %d, avail: %d' % (deg, self.blocklen, tvsize, tvsize/1024.0, tvsize/1024.0/1024.0, cur_round, len(bits))) hwanalysis.proces_chunk(bits, ref_bits) cur_round += 1 pass logger.info('Finished processing %s ' % iobj) logger.info('Data read %s ' % iobj.data_read) logger.info('Read data hash %s ' % iobj.sha1.hexdigest()) if fref is not None: fref.close() logger.info('Processing finished') end = time.time() print(end-start)
def testcase(self, function, cur_round, size_mb, blocklen, degree, comb_deg, data_file, tmpdir): """ Test case executor :param function: :param cur_round: :param size_mb: :param blocklen: :param degree: :param comb_deg: :param data_file: :return: """ rounds = 0 tvsize = 1024 * 1024 * size_mb # Load input polynomials self.load_input_poly() script_path = common.get_script_path() logger.info('Basic settings, deg: %s, blocklen: %s, TV size: %s' % (degree, blocklen, tvsize)) total_terms = int(common.comb(blocklen, degree, True)) hwanalysis = HWAnalysis() hwanalysis.deg = degree hwanalysis.blocklen = blocklen hwanalysis.top_comb = comb_deg hwanalysis.comb_random = self.args.comb_random hwanalysis.top_k = self.top_k hwanalysis.combine_all_deg = self.all_deg hwanalysis.zscore_thresh = self.zscore_thresh hwanalysis.do_ref = None hwanalysis.skip_print_res = True hwanalysis.input_poly = self.input_poly hwanalysis.no_comb_and = self.args.no_comb_and hwanalysis.no_comb_xor = self.args.no_comb_xor hwanalysis.prob_comb = self.args.prob_comb hwanalysis.all_deg_compute = len(self.input_poly) == 0 hwanalysis.do_only_top_comb = self.args.only_top_comb hwanalysis.do_only_top_deg = self.args.only_top_deg hwanalysis.no_term_map = self.args.no_term_map hwanalysis.use_zscore_heap = self.args.topterm_heap hwanalysis.sort_best_zscores = max( common.replace_none([self.args.topterm_heap_k, self.top_k, 100])) hwanalysis.best_x_combinations = self.args.best_x_combinations logger.info('Initializing test') time_test_start = time.time() hwanalysis.init() # Process input object iobj = common.FileInputObject(data_file) size = iobj.size() logger.info('Testing input object: %s, size: %d kB' % (iobj, size / 1024.0)) # size smaller than TV? Adapt tv then if size >= 0 and size < tvsize: logger.info('File size is smaller than TV, updating TV to %d' % size) tvsize = size if tvsize * 8 % blocklen != 0: rem = tvsize * 8 % blocklen logger.warning('Input data size not aligned to the block size. ' 'Input bytes: %d, block bits: %d, rem: %d' % (tvsize, blocklen, rem)) tvsize -= rem // 8 logger.info('Updating TV to %d' % tvsize) hwanalysis.reset() logger.info('BlockLength: %d, deg: %d, terms: %d' % (blocklen, degree, total_terms)) with iobj: data_read = 0 cur_round = 0 while size < 0 or data_read < size: if rounds is not None and cur_round > rounds: break data = iobj.read(tvsize) bits = common.to_bitarray(data) if len(bits) == 0: logger.info('File read completely') break logger.info( 'Pre-computing with TV, deg: %d, blocklen: %04d, tvsize: %08d = %8.2f kB = %8.2f MB, ' 'round: %d, avail: %d' % (degree, blocklen, tvsize, tvsize / 1024.0, tvsize / 1024.0 / 1024.0, cur_round, len(bits))) hwanalysis.process_chunk(bits, None) cur_round += 1 pass # RESULT process... total_results = len(hwanalysis.last_res) best_dists = hwanalysis.last_res[0:min(128, total_results)] data_hash = iobj.sha1.hexdigest() jsres = collections.OrderedDict() jsres['best_zscore'] = best_dists[0].zscore jsres['best_poly'] = best_dists[0].poly jsres['blocklen'] = blocklen jsres['degree'] = degree jsres['comb_degree'] = comb_deg jsres['top_k'] = self.top_k jsres['all_deg'] = self.all_deg jsres['time_elapsed'] = time.time() - time_test_start jsres['data_hash'] = data_hash jsres['data_read'] = iobj.data_read jsres['generator'] = self.config_js jsres['best_dists'] = best_dists logger.info('Finished processing %s ' % iobj) logger.info('Data read %s ' % iobj.data_read) logger.info('Read data hash %s ' % data_hash) return jsres