Esempio n. 1
0
 def keygen(self, seed, masks):
     assert len(seed) == self.n // 8
     assert len(masks) >= 2 * self.tau
     sk = self.Gt(seed)
     sk = chunkbytes(sk, self.n // 8)
     L = list(map(self.F, sk))
     H = lambda x, y, i: self.H(xor(x, masks[2*i]), xor(y, masks[2*i+1]))
     return root(hash_tree(H, L))
Esempio n. 2
0
 def keygen_pub(self, SK1, Q):
     addresses = [self.address(self.d - 1, 0, i)
                  for i in range(1 << (self.h//self.d))]
     leafs = [self.wots_leaf(A, SK1, Q) for A in addresses]
     Qtree = Q[2 * ceil(log(self.wots.l, 2)):]
     H = lambda x, y, i: self.H(xor(x, Qtree[2*i]), xor(y, Qtree[2*i+1]))
     PK1 = root(hash_tree(H, leafs))
     return PK1
Esempio n. 3
0
 def keygen_pub(self, SK1, Q):
     addresses = [self.address(self.d - 1, 0, i)
                  for i in range(1 << (self.h//self.d))]
     leafs = [self.wots_leaf(A, SK1, Q) for A in addresses]
     Qtree = Q[2 * ceil(log(self.wots.l, 2)):]
     H = lambda x, y, i: self.H(xor(x, Qtree[2*i]), xor(y, Qtree[2*i+1]))
     PK1 = root(hash_tree(H, leafs))
     return PK1
Esempio n. 4
0
    def wots_leaf(self, address, SK1, masks):
        seed = self.Fa(address, SK1)
        pk_A = self.wots.keygen(seed, masks)

        def H(x, y, i):
            return self.H(xor(x, masks[2 * i]), xor(y, masks[2 * i + 1]))

        return root(l_tree(H, pk_A))
Esempio n. 5
0
 def keygen(self, seed, masks):
     assert len(seed) == self.n // 8
     assert len(masks) >= 2 * self.tau
     sk = self.Gt(seed)
     sk = chunkbytes(sk, self.n // 8)
     L = list(map(self.F, sk))
     H = lambda x, y, i: self.H(xor(x, masks[2 * i]),
                                xor(y, masks[2 * i + 1]))
     return root(hash_tree(H, L))
Esempio n. 6
0
 def wots_path(self, a, SK1, Q, subh):
     ta = dict(a)
     leafs = []
     for subleaf in range(1 << subh):
         ta['leaf'] = subleaf
         leafs.append(self.wots_leaf(self.address(**ta), SK1, Q))
     Qtree = Q[2 * ceil(log(self.wots.l, 2)):]
     H = lambda x, y, i: self.H(xor(x, Qtree[2*i]), xor(y, Qtree[2*i+1]))
     tree = list(hash_tree(H, leafs))
     return auth_path(tree, a['leaf']), root(tree)
Esempio n. 7
0
 def wots_path(self, a, SK1, Q, subh):
     ta = dict(a)
     leafs = []
     for subleaf in range(1 << subh):
         ta['leaf'] = subleaf
         leafs.append(self.wots_leaf(self.address(**ta), SK1, Q))
     Qtree = Q[2 * ceil(log(self.wots.l, 2)):]
     H = lambda x, y, i: self.H(xor(x, Qtree[2*i]), xor(y, Qtree[2*i+1]))
     tree = list(hash_tree(H, leafs))
     return auth_path(tree, a['leaf']), root(tree)
Esempio n. 8
0
 def sign(self, m, seed, masks):
     assert len(m) == self.m // 8
     assert len(seed) == self.n // 8
     assert len(masks) >= 2 * self.tau
     sk = self.Gt(seed)
     sk = chunkbytes(sk, self.n // 8)
     L = list(map(self.F, sk))
     H = lambda x, y, i: self.H(xor(x, masks[2*i]), xor(y, masks[2*i+1]))
     tree = hash_tree(H, L)
     trunk = list(itertools.islice(tree, 0, self.tau - self.x))
     sigma_k = next(tree)
     M = self.message_indices(m)
     pk = root(tree)
     # the SPHINCS paper suggests to put sigma_k at the end of sigma
     # but the reference code places it at the front
     return ([(sk[Mi], auth_path(trunk, Mi)) for Mi in M] + [sigma_k], pk)
Esempio n. 9
0
 def sign(self, m, seed, masks):
     assert len(m) == self.m // 8
     assert len(seed) == self.n // 8
     assert len(masks) >= 2 * self.tau
     sk = self.Gt(seed)
     sk = chunkbytes(sk, self.n // 8)
     L = list(map(self.F, sk))
     H = lambda x, y, i: self.H(xor(x, masks[2 * i]),
                                xor(y, masks[2 * i + 1]))
     tree = hash_tree(H, L)
     trunk = list(itertools.islice(tree, 0, self.tau - self.x))
     sigma_k = next(tree)
     M = self.message_indices(m)
     pk = root(tree)
     # the SPHINCS paper suggests to put sigma_k at the end of sigma
     # but the reference code places it at the front
     return ([(sk[Mi], auth_path(trunk, Mi)) for Mi in M] + [sigma_k], pk)
Esempio n. 10
0
 def verify(self, m, sig, masks):
     assert len(m) == self.m // 8
     assert len(masks) >= 2 * self.tau
     M = self.message_indices(m)
     H = lambda x, y, i: self.H(xor(x, masks[2*i]), xor(y, masks[2*i+1]))
     sigma_k = sig[-1]
     for (sk, path), Mi in zip(sig, M):
         leaf = self.F(sk)
         r = construct_root(H, path, leaf, Mi)
         # there is an error in the SPHINCS paper for this formula, as it
         # states that y_i = floor(M_i / 2^tau - x)
         # rather than y_i = floor(M_i / 2^{tau - x})
         yi = Mi // (1 << (self.tau - self.x))
         if r != sigma_k[yi]:
             return False
     Qtop = masks[2*(self.tau - self.x):]
     H = lambda x, y, i: self.H(xor(x, Qtop[2*i]), xor(y, Qtop[2*i+1]))
     return root(hash_tree(H, sigma_k))
Esempio n. 11
0
 def verify(self, M, sig, PK):
     i, R1, sig_horst, *sig = sig
     PK1, Q = PK
     Qtree = Q[2 * ceil(log(self.wots.l, 2)):]
     D = self.Hdigest(R1, M)
     pk = pk_horst = self.horst.verify(D, sig_horst, Q)
     if pk_horst is False:
         return False
     subh = self.h // self.d
     H = lambda x, y, i: self.H(xor(x, Q[2*i]), xor(y, Q[2*i+1]))
     Ht = lambda x, y, i: self.H(xor(x, Qtree[2*i]), xor(y, Qtree[2*i+1]))
     for _ in range(self.d):
         wots_sig, wots_path, *sig = sig
         pk_wots = self.wots.verify(pk, wots_sig, Q)
         leaf = root(l_tree(H, pk_wots))
         pk = construct_root(Ht, wots_path, leaf, i & 0x1f)
         i >>= subh
     return PK1 == pk
Esempio n. 12
0
 def verify(self, M, sig, PK):
     i, R1, sig_horst, *sig = sig
     PK1, Q = PK
     Qtree = Q[2 * ceil(log(self.wots.l, 2)):]
     D = self.Hdigest(R1, M)
     pk = pk_horst = self.horst.verify(D, sig_horst, Q)
     if pk_horst is False:
         return False
     subh = self.h // self.d
     H = lambda x, y, i: self.H(xor(x, Q[2*i]), xor(y, Q[2*i+1]))
     Ht = lambda x, y, i: self.H(xor(x, Qtree[2*i]), xor(y, Qtree[2*i+1]))
     for _ in range(self.d):
         wots_sig, wots_path, *sig = sig
         pk_wots = self.wots.verify(pk, wots_sig, Q)
         leaf = root(l_tree(H, pk_wots))
         pk = construct_root(Ht, wots_path, leaf, i & 0x1f)
         i >>= subh
     return PK1 == pk
Esempio n. 13
0
 def verify(self, m, sig, masks):
     assert len(m) == self.m // 8
     assert len(masks) >= 2 * self.tau
     M = self.message_indices(m)
     H = lambda x, y, i: self.H(xor(x, masks[2 * i]),
                                xor(y, masks[2 * i + 1]))
     sigma_k = sig[-1]
     for (sk, path), Mi in zip(sig, M):
         leaf = self.F(sk)
         r = construct_root(H, path, leaf, Mi)
         # there is an error in the SPHINCS paper for this formula, as it
         # states that y_i = floor(M_i / 2^tau - x)
         # rather than y_i = floor(M_i / 2^{tau - x})
         yi = Mi // (1 << (self.tau - self.x))
         if r != sigma_k[yi]:
             return False
     Qtop = masks[2 * (self.tau - self.x):]
     H = lambda x, y, i: self.H(xor(x, Qtop[2 * i]), xor(
         y, Qtop[2 * i + 1]))
     return root(hash_tree(H, sigma_k))
Esempio n. 14
0
 def wots_leaf(self, address, SK1, masks):
     seed = self.Fa(address, SK1)
     pk_A = self.wots.keygen(seed, masks)
     H = lambda x, y, i: self.H(xor(x, masks[2*i]), xor(y, masks[2*i+1]))
     return root(l_tree(H, pk_A))