def deserialize_signature(hex_value): hss_max_levels = 8 levels = hex_u32_to_int(hex_value[0:4]) + 1 if levels > hss_max_levels: raise ValueError("levels exceeds max level value") sig_list = list() pub_list = list() tmp = hex_value[4:] for i in xrange(0, levels - 1): lms_sig, tmp = LmsSerializer.parse_signature(tmp) sig_list.append(lms_sig) lms_pub, tmp = LmsSerializer.parse_public_key(tmp) pub_list.append(lms_pub) msg_sig = tmp return levels, pub_list, sig_list, msg_sig
def verify(self, message, sig, i, k): lms_type, q, lmots_sig, path = LmsSerializer.deserialize_signature(sig) node_num = q + 2**self.lms_type.h if lms_type != self.lms_type: return ValueError( "LMS signature type does not match expected type") path_value = iter(path) lmots = Lmots(self.lmots_type) sig_pub_key = lmots.extract_public_key(signature=lmots_sig, s=i + u32str(q), message=message) sig_pub_key_hash = sha256_hash(i + sig_pub_key.k + u32str(node_num) + D_LEAF) while node_num > 1: if node_num % 2: sig_pub_key_hash = sha256_hash(i + path_value.next() + sig_pub_key_hash + u32str(node_num / 2) + D_INTR) else: sig_pub_key_hash = sha256_hash(i + sig_pub_key_hash + path_value.next() + u32str(node_num / 2) + D_INTR) node_num = node_num / 2 is_valid = sig_pub_key_hash == k return is_valid
def serialize_signature(levels, pub_list, sig_list, msg_sig): serial_sig = u32str(levels - 1) for i in xrange(0, levels - 1): serial_sig = serial_sig + sig_list[i] serial_sig = serial_sig + LmsSerializer.serialize_public_key( pub_list[i + 1]) serial_sig = serial_sig + msg_sig return serial_sig
def deserialize_private_key(hex_value): levels = hex_u32_to_int(hex_value[0:4]) lms_type, lmots_type, seed, i, q = LmsSerializer.deserialize_private_key( hex_value[4:]) lms = Lms(lms_type=lms_type, lmots_type=lmots_type) lms_root_pub_key, lms_root_pvt_key = lms.generate_key_pair(seed=seed, i=i, q=q) return lms_root_pub_key, lms_root_pvt_key, levels, lms_type, lmots_type
def sign(self, message, pub_key, pvt_key): if pvt_key.leaf_num >= 2**self.lms_type.h: raise ValueError("attempted overuse of private key") lmots = Lmots(self.lmots_type) ots_sig = lmots.sign(message, pvt_key.get_next_ots_priv_key()) path = pub_key.get_path(pvt_key.leaf_num + 2**self.lms_type.h) leaf_num = pvt_key.leaf_num pvt_key.leaf_num = pvt_key.leaf_num + 1 lms_sig = LmsSignature(self.lms_type, leaf_num, ots_sig, path) return LmsSerializer.serialize_signature(lms_sig)
def deserialize_public_key(hex_value): levels = hex_u32_to_int(hex_value[0:4]) lms_type, lmots_type, i, k = LmsSerializer.deserialize_public_key( hex_value[4:]) lms_root_pub_key = LmsPublicKey(lms_type=lms_type, lmots_type=lmots_type, i=i, k=k, nodes=None) return lms_root_pub_key, levels
def __str__(self): """ String representation of LMS signature object. :return: string """ s_list = list() StringFormat.line(s_list) s_list.append("LMS signature") # TODO: we should not be deserializing here - we should be working directly with the signature object lms_type, q, lmots_sig, path = LmsSerializer.deserialize_signature(self.signature) StringFormat.format_hex(s_list, "q", u32str(q)) # TODO: we should not be deserializing here - we should be working directly with the signature object sig = LmotsSerializer.deserialize_signature(lmots_sig) s_list.append(str(sig)) StringFormat.format_hex(s_list, "LMS type", u32str(lms_type.type_code), lms_type.name) for i, e in enumerate(path): StringFormat.format_hex(s_list, "path[" + str(i) + "]", e) return "\n".join(s_list)
def print_hss_sig(sig): levels, pub_list, sig_list, lms_sig = HssSerializer.deserialize_signature( sig) s_list = list() StringFormat.line(s_list) s_list.append("HSS signature") StringFormat.format_hex(s_list, "Nspk", u32str(levels - 1)) for i in xrange(0, levels - 1): s_list.append("sig[" + str(i) + "]: ") s_list.append(string_to_hex(sig_list[i])) s_list.append("pub[" + str(i) + "]: ") lms_type, lmots_type, i, k = LmsSerializer.deserialize_public_key( pub_list[i]) lms_pub_key = LmsPublicKey(lms_type=lms_type, lmots_type=lmots_type, i=i, k=k) s_list.append(str(lms_pub_key)) s_list.append("final_signature: ") s_list.append(string_to_hex(lms_sig)) sig_string = "\n".join(s_list) print(sig_string)
def serialize_public_key(public_key): return u32str(public_key.levels) + LmsSerializer.serialize_public_key( public_key.pub1)
def serialize_private_key(private_key): return u32str( private_key.levels) + LmsSerializer.serialize_private_key( private_key.pvt_keys[0])