def add_password(self, domain_pw_map): #print self.dte.G nG = copy.deepcopy(self.dte.G) nG.update_grammar(*(domain_pw_map.values())) ndte = DTE(nG) if self.dte and (ndte != self.dte): # if new dte is different then data = [(self.dte, ndte, i, p) for i,p in enumerate(self.S) if self.machine_pass_set[i] == '0'] result = ProcessParallel(copy_from_old_parallel, data, func_load=100) for i, p in enumerate(result): self.S[i] = p self.H = self.pcfg.encode_grammar(nG) #print_err(self.H[:10]) G_ = self.pcfg.decode_grammar(self.H) #print_err("-"*50) #print_err("Original: ", nG, '\n', '='*50) #print_err("After Decoding:", G_) assert G_ == nG for d,p in domain_pw_map.items(): i = self.get_domain_index(d) self.S[i] = ndte.encode_pw(p) self.machine_pass_set[i] = '0' self.dte = ndte
def add_password(self, domain_pw_map): #print self.dte.G nG = copy.deepcopy(self.dte.G) nG.update_grammar(*(domain_pw_map.values())) ndte = DTE(nG) if self.dte and (ndte != self.dte): # if new dte is different then data = [(self.dte, ndte, i, p) for i, p in enumerate(self.S) if self.machine_pass_set[i] == '0'] result = ProcessParallel(copy_from_old_parallel, data, func_load=100) for i, p in enumerate(result): self.S[i] = p self.H = self.pcfg.encode_grammar(nG) #print_err(self.H[:10]) G_ = self.pcfg.decode_grammar(self.H) #print_err("-"*50) #print_err("Original: ", nG, '\n', '='*50) #print_err("After Decoding:", G_) assert G_ == nG for d, p in domain_pw_map.items(): i = self.get_domain_index(d) self.S[i] = ndte.encode_pw(p) self.machine_pass_set[i] = '0' self.dte = ndte
def __init__(self, vault_fl, mp): self.pcfg = TrainedGrammar() # Default large trained PCFG domain_hash_map_fl = hny_config.STATIC_DOMAIN_HASH_LIST self.domain_hash_map = json.load(open_(domain_hash_map_fl)) self.vault_fl = vault_fl self.mp = mp self.initialize_vault(mp) self.dte = DTE(self.pcfg.decode_grammar(self.H))
class HoneyVault: s1 = hny_config.HONEY_VAULT_S1 s2 = hny_config.HONEY_VAULT_S2 s_g = hny_config.HONEY_VAULT_GRAMMAR_SIZE s = hny_config.HONEY_VAULT_STORAGE_SIZE vault_total_size = hny_config.HONEY_VAULT_ENCODING_SIZE sample = [10,19,20,31] mpass_set_size = hny_config.HONEY_VAULT_MACHINE_PASS_SET_SIZE def __init__(self, vault_fl, mp): self.pcfg = TrainedGrammar() # Default large trained PCFG domain_hash_map_fl = hny_config.STATIC_DOMAIN_HASH_LIST self.domain_hash_map = json.load(open_(domain_hash_map_fl)) self.vault_fl = vault_fl self.mp = mp self.initialize_vault(mp) self.dte = DTE(self.pcfg.decode_grammar(self.H)) def get_domain_index(self, d): h = SHA256.new() h.update(d) d_hash = h.hexdigest()[:32] try: i = self.domain_hash_map[d_hash] if i>self.s1: raise KeyError; else: return i except KeyError: sys.stderr.write('WARNING! S1 miss for %s\n' % d) x = struct.unpack('8I', h.digest())[0] return self.s1 + x % self.s2 def initialize_vault(self, mp): vd = VaultDistPCFG() if not os.path.exists(self.vault_fl): print_production("\nCould not find the vault file @ {}, so, sit tight, "\ "creating a dummy vault for you."\ "\nShould not take too long...\n".format(self.vault_fl)) t_s = random.randints(0, MAX_INT, hny_config.HONEY_VAULT_ENCODING_SIZE) self.H = t_s[:hny_config.HONEY_VAULT_GRAMMAR_SIZE] t_s = t_s[hny_config.HONEY_VAULT_GRAMMAR_SIZE:] self.S = [t_s[i:i+hny_config.PASSWORD_LENGTH] for i in range(0, self.s*hny_config.PASSWORD_LENGTH, hny_config.PASSWORD_LENGTH)] assert all(len(s)==hny_config.PASSWORD_LENGTH for s in self.S), "All passwords encodings are not of correct length.\n {}".format((len(s), hny_config.PASSWORD_LENGTH) for s in self.S) self.machine_pass_set = list('0'*(self.mpass_set_size*8)) k = int(math.ceil(hny_config.HONEY_VAULT_STORAGE_SIZE * \ hny_config.MACHINE_GENRATED_PASS_PROB/1000.0)) for i in random.sample(range(hny_config.HONEY_VAULT_STORAGE_SIZE), k): self.machine_pass_set[i] = '1' self.salt = os.urandom(8) self.save(mp) else: self.load(mp) def gen_password(self, mp, domain_list, size=10): """ generates random password strings for each of the domail specified, and saves it in corresponding location. Master password (@mp) is required for that. """ r_dte = DTE_random() reply = [] for d in domain_list: i = self.get_domain_index(d) p, encoding = r_dte.generate_and_encode_password(size) self.S[i] = encoding self.machine_pass_set[i] = '1' reply.append(p) self.save() return OrderedDict(zip(domain_list, reply)) def add_password(self, domain_pw_map): #print self.dte.G nG = copy.deepcopy(self.dte.G) print_production("Updating the grammar with new passwords..") nG.update_grammar(*(domain_pw_map.values())) ndte = DTE(nG) # TODO: fix this, currently its a hack to way around my shitty # parsing. A password can be generated in a different way than it is parsed in most probably # way. The code is supposed to pick one parse tree at random. Currently picking the most # probable one. Need to fix for security reason. Will add a ticket. new_encoding_of_old_pw = [] current_passwords = ['' for _ in xrange(hny_config.HONEY_VAULT_STORAGE_SIZE)] if self.dte and (ndte != self.dte): # if new dte is different then copy the existing human chosen passwords. # Machine generated passwords are not necessary to reencode. As their grammar # does not change. NEED TO CHECK SECURITY. print_production("Some new rules found, so adding them to the new grammar. "\ "Should not take too long...\n") data = [(self.dte, ndte, i, p) for i,p in enumerate(self.S) if self.machine_pass_set[i] == '0'] result = ProcessParallel(copy_from_old_parallel, data, func_load=100) for i,pw, pw_encodings in result: if isinstance(pw_encodings, basestring): new_encoding_of_old_pw.append((i, pw_encodings)) current_passwords[i] = pw self.S[i] = pw_encodings # print_err(self.H[:10]) # G_ = self.pcfg.decode_grammar(self.H) # print_err("-"*50) # print_err("Original: ", nG, '\n', '='*50) # print_err("After Decoding:", G_) # assert G_ == nG print_production("\nAdding new passowrds..\n") for domain, pw in domain_pw_map.items(): i = self.get_domain_index(domain) print ">>", i, pw, domain current_passwords[i] = pw self.S[i] = ndte.encode_pw(pw) self.machine_pass_set[i] = '0' # Cleaning the mess because of missed passwords # Because some password might have failed in copy_from_old_function, They need to be # re-encoded if new_encoding_of_old_pw: print_err("\n<<<<<<\nFixing Mess!!\n{}>>>>>>>".format(new_encoding_of_old_pw)) nG.update_grammar(*[p for i,p in new_encoding_of_old_pw]) for i,p in new_encoding_of_old_pw: self.S[i] = ndte.encode_pw(p) self.machine_pass_set[i] = '0' if hny_config.DEBUG: for i,pw_encodings in enumerate(self.S): if self.machine_pass_set[i] == '0': tpw = ndte.decode_pw(pw_encodings) tpwold = current_passwords[i] assert len(tpwold)<=0 or tpw == tpwold,\ "The re-encoding is faulty. Expecting: '{}' at {}. Got '{}'.".format(tpwold, i, tpw) self.H = self.pcfg.encode_grammar(nG) self.dte = ndte def get_password(self, domain_list, send_raw=False): pw_list = [] r_dte = DTE_random() for d in domain_list: i = self.get_domain_index(d) if self.machine_pass_set[i] == '1': pw = r_dte.decode_pw(self.S[i]) else: pw = self.dte.decode_pw(self.S[i]) pw_list.append(pw) return OrderedDict(zip(domain_list, pw_list)) def get_sample_decoding(self): """ check some of the sample decoding to make sure you are not accidentally spoiling the vault """ assert all(len(self.S[i])==hny_config.PASSWORD_LENGTH for i in self.sample),\ "Corrupted Encoding!!" return [self.dte.decode_pw(self.S[i]) for i in self.sample] def get_all_pass(self): """ Returns all the passwords in the vault. """ r_dte = DTE_random() return ((i, self.dte.decode_pw(s)) if self.machine_pass_set[i] == '0'\ else (i, r_dte.decode_pw(s)) for i,s in enumerate(self.S)) def save(self, mp=None): if not mp: mp = self.mp with open(self.vault_fl, 'wb') as fvault: fvault.write(self.salt) buf = list(self.H[:]) for i, a in enumerate(self.S): buf.extend(a) aes = do_crypto_setup(mp, self.salt) fvault.write(aes.encrypt( struct.pack('!%sI' % \ hny_config.HONEY_VAULT_ENCODING_SIZE, *buf)) ) for i in range(self.mpass_set_size): fvault.write(struct.pack('!B', int( ''.join(self.machine_pass_set[i*8:(i+1)*8]), 2))) def load(self, mp): with open(self.vault_fl, 'rb') as fvault: self.salt = fvault.read(8) size_of_int = struct.calcsize('I') aes = do_crypto_setup(mp, self.salt) buf = aes.decrypt( fvault.read(hny_config.HONEY_VAULT_ENCODING_SIZE * size_of_int)) t_s = struct.unpack( '!%sI' % hny_config.HONEY_VAULT_ENCODING_SIZE, buf) self.H = t_s[:hny_config.HONEY_VAULT_GRAMMAR_SIZE] t_s = t_s[hny_config.HONEY_VAULT_GRAMMAR_SIZE:] self.S = [t_s[i*hny_config.PASSWORD_LENGTH:(i+1)*hny_config.PASSWORD_LENGTH] for i in range(self.s)] buf = fvault.read(self.mpass_set_size) self.machine_pass_set = \ list(''.join(["{0:08b}".format(x) for x in struct.unpack( "%sB" % self.mpass_set_size, buf)])) assert len(self.machine_pass_set) >= len(self.S)
def add_password(self, domain_pw_map): #print self.dte.G nG = copy.deepcopy(self.dte.G) print_production("Updating the grammar with new passwords..") nG.update_grammar(*(domain_pw_map.values())) ndte = DTE(nG) # TODO: fix this, currently its a hack to way around my shitty # parsing. A password can be generated in a different way than it is parsed in most probably # way. The code is supposed to pick one parse tree at random. Currently picking the most # probable one. Need to fix for security reason. Will add a ticket. new_encoding_of_old_pw = [] current_passwords = ['' for _ in xrange(hny_config.HONEY_VAULT_STORAGE_SIZE)] if self.dte and (ndte != self.dte): # if new dte is different then copy the existing human chosen passwords. # Machine generated passwords are not necessary to reencode. As their grammar # does not change. NEED TO CHECK SECURITY. print_production("Some new rules found, so adding them to the new grammar. "\ "Should not take too long...\n") data = [(self.dte, ndte, i, p) for i,p in enumerate(self.S) if self.machine_pass_set[i] == '0'] result = ProcessParallel(copy_from_old_parallel, data, func_load=100) for i,pw, pw_encodings in result: if isinstance(pw_encodings, basestring): new_encoding_of_old_pw.append((i, pw_encodings)) current_passwords[i] = pw self.S[i] = pw_encodings # print_err(self.H[:10]) # G_ = self.pcfg.decode_grammar(self.H) # print_err("-"*50) # print_err("Original: ", nG, '\n', '='*50) # print_err("After Decoding:", G_) # assert G_ == nG print_production("\nAdding new passowrds..\n") for domain, pw in domain_pw_map.items(): i = self.get_domain_index(domain) print ">>", i, pw, domain current_passwords[i] = pw self.S[i] = ndte.encode_pw(pw) self.machine_pass_set[i] = '0' # Cleaning the mess because of missed passwords # Because some password might have failed in copy_from_old_function, They need to be # re-encoded if new_encoding_of_old_pw: print_err("\n<<<<<<\nFixing Mess!!\n{}>>>>>>>".format(new_encoding_of_old_pw)) nG.update_grammar(*[p for i,p in new_encoding_of_old_pw]) for i,p in new_encoding_of_old_pw: self.S[i] = ndte.encode_pw(p) self.machine_pass_set[i] = '0' if hny_config.DEBUG: for i,pw_encodings in enumerate(self.S): if self.machine_pass_set[i] == '0': tpw = ndte.decode_pw(pw_encodings) tpwold = current_passwords[i] assert len(tpwold)<=0 or tpw == tpwold,\ "The re-encoding is faulty. Expecting: '{}' at {}. Got '{}'.".format(tpwold, i, tpw) self.H = self.pcfg.encode_grammar(nG) self.dte = ndte
class HoneyVault: s1 = hny_config.HONEY_VAULT_S1 s2 = hny_config.HONEY_VAULT_S2 s_g = hny_config.HONEY_VAULT_GRAMMAR_SIZE s = hny_config.HONEY_VAULT_STORAGE_SIZE vault_total_size = hny_config.HONEY_VAULT_ENCODING_SIZE sample = [10,19,20,31] mpass_set_size = hny_config.HONEY_VAULT_MACHINE_PASS_SET_SIZE def __init__(self, vault_fl, mp): self.pcfg = DTE_large() domain_hash_map_fl = hny_config.STATIC_DOMAIN_HASH_LIST self.domain_hash_map = json.load(open_(domain_hash_map_fl)) self.vault_fl = vault_fl self.mp = mp self.initialize_vault(mp) self.dte = DTE(self.pcfg.decode_grammar(self.H)) #print_err (self.dte.G) def get_domain_index(self, d): h = SHA256.new() h.update(d) d_hash = h.hexdigest()[:32] try: i = self.domain_hash_map[d_hash] if i>self.s1: raise KeyError; else: return i except KeyError: sys.stderr.write('WARNING! S1 miss for %s\n' % d) x = struct.unpack('8I', h.digest())[0] return self.s1 + x % self.s2 def initialize_vault(self, mp): vd = VaultDistribution() if not os.path.exists(self.vault_fl): buf = rnd_source.read(hny_config.HONEY_VAULT_ENCODING_SIZE * 4) t_s = struct.unpack( '!%sI' % hny_config.HONEY_VAULT_ENCODING_SIZE, buf) self.H = t_s[:hny_config.HONEY_VAULT_GRAMMAR_SIZE] t_s = t_s[hny_config.HONEY_VAULT_GRAMMAR_SIZE:] self.S = [t_s[i*hny_config.PASSWORD_LENGTH:(i+1)*hny_config.PASSWORD_LENGTH] for i in range(self.s)] #buf = struct.unpack('!%sI' % self.mpass_set_size, rnd_source.read(self.mpass_set_size)) # self.machine_pass_set = \ # list(''.join(["{0:08b}".format(x) # for x in struct.unpack( # "%sB" % self.mpass_set_size, buf)])) # assert len(self.machine_pass_set) >= len(self.S) self.machine_pass_set = list('0'*(self.mpass_set_size*8)) k = int(math.ceil(hny_config.HONEY_VAULT_STORAGE_SIZE * \ hny_config.MACHINE_GENRATED_PASS_PROB/1000.0)) for i in random.sample(range(hny_config.HONEY_VAULT_STORAGE_SIZE), k): self.machine_pass_set[i] = '1' self.salt = rnd_source.read(8) self.save(mp) else: self.load(mp) def gen_password(self, mp, domain_list, size=10): r_dte = DTE_random() reply = [] for d in domain_list: i = self.get_domain_index(d) p, encoding = r_dte.generate_and_encode_password(size) self.S[i] = encoding self.machine_pass_set[i] = '1' reply.append(p) self.save() return OrderedDict(zip(domain_list, reply)) def add_password(self, domain_pw_map): #print self.dte.G nG = copy.deepcopy(self.dte.G) nG.update_grammar(*(domain_pw_map.values())) ndte = DTE(nG) if self.dte and (ndte != self.dte): # if new dte is different then data = [(self.dte, ndte, i, p) for i,p in enumerate(self.S) if self.machine_pass_set[i] == '0'] result = ProcessParallel(copy_from_old_parallel, data, func_load=100) for i, p in enumerate(result): self.S[i] = p self.H = self.pcfg.encode_grammar(nG) #print_err(self.H[:10]) G_ = self.pcfg.decode_grammar(self.H) #print_err("-"*50) #print_err("Original: ", nG, '\n', '='*50) #print_err("After Decoding:", G_) assert G_ == nG for d,p in domain_pw_map.items(): i = self.get_domain_index(d) self.S[i] = ndte.encode_pw(p) self.machine_pass_set[i] = '0' self.dte = ndte def get_password(self, domain_list): pw_list = [] r_dte = DTE_random() for d in domain_list: i = self.get_domain_index(d) if self.machine_pass_set[i] == '1': print_err("Machine Password") pw = r_dte.decode_pw(self.S[i]) else: pw = self.dte.decode_pw(self.S[i]) pw_list.append(pw) return OrderedDict(zip(domain_list, pw_list)) def get_sample_decoding(self): """ check some of the sample decoding to make sure you are not accidentally spoiling the vault """ return [self.dte.decode_pw(self.S[i]) for i in self.sample] def save(self, mp=None): if not mp: mp = self.mp with open(self.vault_fl, 'wb') as fvault: fvault.write(self.salt) buf = list(self.H[:]) for i, a in enumerate(self.S): buf.extend(a) aes = do_crypto_setup(mp, self.salt) fvault.write(aes.encrypt( struct.pack('!%sI' % \ hny_config.HONEY_VAULT_ENCODING_SIZE, *buf)) ) for i in range(self.mpass_set_size): fvault.write(struct.pack('!B', int( ''.join(self.machine_pass_set[i*8:(i+1)*8]), 2))) def load(self, mp): with open(self.vault_fl, 'rb') as fvault: self.salt = fvault.read(8) size_of_int = struct.calcsize('I') aes = do_crypto_setup(mp, self.salt) buf = aes.decrypt( fvault.read(hny_config.HONEY_VAULT_ENCODING_SIZE * size_of_int)) t_s = struct.unpack( '!%sI' % hny_config.HONEY_VAULT_ENCODING_SIZE, buf) self.H = t_s[:hny_config.HONEY_VAULT_GRAMMAR_SIZE] t_s = t_s[hny_config.HONEY_VAULT_GRAMMAR_SIZE:] self.S = [t_s[i*hny_config.PASSWORD_LENGTH:(i+1)*hny_config.PASSWORD_LENGTH] for i in range(self.s)] buf = fvault.read(self.mpass_set_size) self.machine_pass_set = \ list(''.join(["{0:08b}".format(x) for x in struct.unpack( "%sB" % self.mpass_set_size, buf)])) assert len(self.machine_pass_set) >= len(self.S)
class HoneyVault: s1 = hny_config.HONEY_VAULT_S1 s2 = hny_config.HONEY_VAULT_S2 s_g = hny_config.HONEY_VAULT_GRAMMAR_SIZE s = hny_config.HONEY_VAULT_STORAGE_SIZE vault_total_size = hny_config.HONEY_VAULT_ENCODING_SIZE sample = [10, 19, 20, 31] mpass_set_size = hny_config.HONEY_VAULT_MACHINE_PASS_SET_SIZE def __init__(self, vault_fl, mp): self.pcfg = DTE_large() domain_hash_map_fl = hny_config.STATIC_DOMAIN_HASH_LIST self.domain_hash_map = json.load(open_(domain_hash_map_fl)) self.vault_fl = vault_fl self.mp = mp self.initialize_vault(mp) self.dte = DTE(self.pcfg.decode_grammar(self.H)) #print_err (self.dte.G) def get_domain_index(self, d): h = SHA256.new() h.update(d) d_hash = h.hexdigest()[:32] try: i = self.domain_hash_map[d_hash] if i > self.s1: raise KeyError else: return i except KeyError: sys.stderr.write('WARNING! S1 miss for %s\n' % d) x = struct.unpack('8I', h.digest())[0] return self.s1 + x % self.s2 def initialize_vault(self, mp): vd = VaultDistribution() if not os.path.exists(self.vault_fl): buf = rnd_source.read(hny_config.HONEY_VAULT_ENCODING_SIZE * 4) t_s = struct.unpack('!%sI' % hny_config.HONEY_VAULT_ENCODING_SIZE, buf) self.H = t_s[:hny_config.HONEY_VAULT_GRAMMAR_SIZE] t_s = t_s[hny_config.HONEY_VAULT_GRAMMAR_SIZE:] self.S = [ t_s[i * hny_config.PASSWORD_LENGTH:(i + 1) * hny_config.PASSWORD_LENGTH] for i in range(self.s) ] #buf = struct.unpack('!%sI' % self.mpass_set_size, rnd_source.read(self.mpass_set_size)) # self.machine_pass_set = \ # list(''.join(["{0:08b}".format(x) # for x in struct.unpack( # "%sB" % self.mpass_set_size, buf)])) # assert len(self.machine_pass_set) >= len(self.S) self.machine_pass_set = list('0' * (self.mpass_set_size * 8)) k = int(math.ceil(hny_config.HONEY_VAULT_STORAGE_SIZE * \ hny_config.MACHINE_GENRATED_PASS_PROB/1000.0)) for i in random.sample(range(hny_config.HONEY_VAULT_STORAGE_SIZE), k): self.machine_pass_set[i] = '1' self.salt = rnd_source.read(8) self.save(mp) else: self.load(mp) def gen_password(self, mp, domain_list, size=10): r_dte = DTE_random() reply = [] for d in domain_list: i = self.get_domain_index(d) p, encoding = r_dte.generate_and_encode_password(size) self.S[i] = encoding self.machine_pass_set[i] = '1' reply.append(p) self.save() return OrderedDict(zip(domain_list, reply)) def add_password(self, domain_pw_map): #print self.dte.G nG = copy.deepcopy(self.dte.G) nG.update_grammar(*(domain_pw_map.values())) ndte = DTE(nG) if self.dte and (ndte != self.dte): # if new dte is different then data = [(self.dte, ndte, i, p) for i, p in enumerate(self.S) if self.machine_pass_set[i] == '0'] result = ProcessParallel(copy_from_old_parallel, data, func_load=100) for i, p in enumerate(result): self.S[i] = p self.H = self.pcfg.encode_grammar(nG) #print_err(self.H[:10]) G_ = self.pcfg.decode_grammar(self.H) #print_err("-"*50) #print_err("Original: ", nG, '\n', '='*50) #print_err("After Decoding:", G_) assert G_ == nG for d, p in domain_pw_map.items(): i = self.get_domain_index(d) self.S[i] = ndte.encode_pw(p) self.machine_pass_set[i] = '0' self.dte = ndte def get_password(self, domain_list): pw_list = [] r_dte = DTE_random() for d in domain_list: i = self.get_domain_index(d) if self.machine_pass_set[i] == '1': print_err("Machine Password") pw = r_dte.decode_pw(self.S[i]) else: pw = self.dte.decode_pw(self.S[i]) pw_list.append(pw) return OrderedDict(zip(domain_list, pw_list)) def get_sample_decoding(self): """ check some of the sample decoding to make sure you are not accidentally spoiling the vault """ return [self.dte.decode_pw(self.S[i]) for i in self.sample] def save(self, mp=None): if not mp: mp = self.mp with open(self.vault_fl, 'wb') as fvault: fvault.write(self.salt) buf = list(self.H[:]) for i, a in enumerate(self.S): buf.extend(a) aes = do_crypto_setup(mp, self.salt) fvault.write(aes.encrypt( struct.pack('!%sI' % \ hny_config.HONEY_VAULT_ENCODING_SIZE, *buf)) ) for i in range(self.mpass_set_size): fvault.write( struct.pack( '!B', int(''.join(self.machine_pass_set[i * 8:(i + 1) * 8]), 2))) def load(self, mp): with open(self.vault_fl, 'rb') as fvault: self.salt = fvault.read(8) size_of_int = struct.calcsize('I') aes = do_crypto_setup(mp, self.salt) buf = aes.decrypt( fvault.read(hny_config.HONEY_VAULT_ENCODING_SIZE * size_of_int)) t_s = struct.unpack('!%sI' % hny_config.HONEY_VAULT_ENCODING_SIZE, buf) self.H = t_s[:hny_config.HONEY_VAULT_GRAMMAR_SIZE] t_s = t_s[hny_config.HONEY_VAULT_GRAMMAR_SIZE:] self.S = [ t_s[i * hny_config.PASSWORD_LENGTH:(i + 1) * hny_config.PASSWORD_LENGTH] for i in range(self.s) ] buf = fvault.read(self.mpass_set_size) self.machine_pass_set = \ list(''.join(["{0:08b}".format(x) for x in struct.unpack( "%sB" % self.mpass_set_size, buf)])) assert len(self.machine_pass_set) >= len(self.S)