def spx_verify(self, m, sig, public_key):
        adrs = ADRS()
        r = sig[0]
        sig_fors = sig[1]
        sig_ht = sig[2]

        public_seed = public_key[0]
        public_root = public_key[1]

        size_md = math.floor((self._k * self._a + 7) / 8)
        size_idx_tree = math.floor((self._h - self._h // self._d + 7) / 8)
        size_idx_leaf = math.floor((self._h // self._d + 7) / 8)

        digest = hash_msg(r, public_seed, public_root, m, size_md + size_idx_tree + size_idx_leaf)
        tmp_md = digest[:size_md]
        tmp_idx_tree = digest[size_md:(size_md + size_idx_tree)]
        tmp_idx_leaf = digest[(size_md + size_idx_tree):len(digest)]

        md_int = int.from_bytes(tmp_md, 'big') >> (len(tmp_md) * 8 - self._k * self._a)
        md = md_int.to_bytes(math.ceil(self._k * self._a / 8), 'big')

        idx_tree = int.from_bytes(tmp_idx_tree, 'big') >> (len(tmp_idx_tree) * 8 - (self._h - self._h // self._d))
        idx_leaf = int.from_bytes(tmp_idx_leaf, 'big') >> (len(tmp_idx_leaf) * 8 - (self._h // self._d))

        adrs.set_layer_address(0)
        adrs.set_tree_address(idx_tree)
        adrs.set_type(ADRS.FORS_TREE)
        adrs.set_key_pair_address(idx_leaf)

        pk_fors = self.fors_pk_from_sig(sig_fors, md, public_seed, adrs)

        adrs.set_type(ADRS.TREE)
        return self.ht_verify(pk_fors, sig_ht, public_seed, idx_tree, idx_leaf, public_root)
    def ht_verify(self, m, sig_ht, public_seed, idx_tree, idx_leaf, public_key_ht):
        adrs = ADRS()

        sigs_xmss = self.sigs_xmss_from_sig_ht(sig_ht)
        sig_tmp = sigs_xmss[0]

        adrs.set_layer_address(0)
        adrs.set_tree_address(idx_tree)
        node = self.xmss_pk_from_sig(idx_leaf, sig_tmp, m, public_seed, adrs)

        for j in range(1, self._d):
            idx_leaf = idx_tree % 2 ** self._h_prime
            idx_tree = idx_tree >> self._h_prime

            sig_tmp = sigs_xmss[j]

            adrs.set_layer_address(j)
            adrs.set_tree_address(idx_tree)

            node = self.xmss_pk_from_sig(idx_leaf, sig_tmp, node, public_seed, adrs)

        if node == public_key_ht:
            return True
        else:
            return False
Beispiel #3
0
    def ht_sign(self, m, secret_seed, public_seed, idx_tree, idx_leaf):
        adrs = ADRS()
        adrs.set_layer_address(0)
        adrs.set_tree_address(idx_tree)

        sig_tmp = self.xmss_sign(m, secret_seed, idx_leaf, public_seed,
                                 adrs.copy())
        sig_ht = sig_tmp
        root = self.xmss_pk_from_sig(idx_leaf, sig_tmp, m, public_seed,
                                     adrs.copy())

        for j in range(1, self._d):
            idx_leaf = idx_tree % 2**self._h_prime
            idx_tree = idx_tree >> self._h_prime

            adrs.set_layer_address(j)
            adrs.set_tree_address(idx_tree)

            sig_tmp = self.xmss_sign(root, secret_seed, idx_leaf, public_seed,
                                     adrs.copy())
            sig_ht = sig_ht + sig_tmp

            if j < self._d - 1:
                root = self.xmss_pk_from_sig(idx_leaf, sig_tmp, root,
                                             public_seed, adrs.copy())

        return sig_ht
Beispiel #4
0
    def spx_sign(self, m, secret_key):
        adrs = ADRS()

        secret_seed = secret_key[0]
        secret_prf = secret_key[1]
        public_seed = secret_key[2]
        public_root = secret_key[3]

        opt = bytes(self._n)
        if self._randomize:
            opt = os.urandom(self._n)
        r = prf_msg(secret_prf, opt, m, self._n)
        sig = [r]

        size_md = math.floor((self._k * self._a + 7) / 8)
        size_idx_tree = math.floor((self._h - self._h // self._d + 7) / 8)
        size_idx_leaf = math.floor((self._h // self._d + 7) / 8)

        digest = hash_msg(r, public_seed, public_root, m,
                          size_md + size_idx_tree + size_idx_leaf)
        tmp_md = digest[:size_md]
        tmp_idx_tree = digest[size_md:(size_md + size_idx_tree)]
        tmp_idx_leaf = digest[(size_md + size_idx_tree):len(digest)]

        md_int = int.from_bytes(tmp_md,
                                'big') >> (len(tmp_md) * 8 - self._k * self._a)
        md = md_int.to_bytes(math.ceil(self._k * self._a / 8), 'big')

        idx_tree = int.from_bytes(tmp_idx_tree,
                                  'big') >> (len(tmp_idx_tree) * 8 -
                                             (self._h - self._h // self._d))
        idx_leaf = int.from_bytes(tmp_idx_leaf,
                                  'big') >> (len(tmp_idx_leaf) * 8 -
                                             (self._h // self._d))

        adrs.set_layer_address(0)
        adrs.set_tree_address(idx_tree)
        adrs.set_type(ADRS.FORS_TREE)
        adrs.set_key_pair_address(idx_leaf)

        sig_fors = self.fors_sign(md, secret_seed, public_seed, adrs.copy())
        sig += [sig_fors]

        pk_fors = self.fors_pk_from_sig(sig_fors, md, public_seed, adrs.copy())

        adrs.set_type(ADRS.TREE)
        sig_ht = self.ht_sign(pk_fors, secret_seed, public_seed, idx_tree,
                              idx_leaf)
        sig += [sig_ht]

        return sig
 def ht_pk_gen(self, secret_seed, public_seed):
     adrs = ADRS()
     adrs.set_layer_address(self._d - 1)
     adrs.set_tree_address(0)
     root = self.xmss_pk_gen(secret_seed, public_seed, adrs.copy())
     return root