Beispiel #1
0
 def _kdf(self, z: bitarray, klen: int) -> bitarray:  # 3.4.3
     ct = bitarray(1, 32)
     t = bitarray()
     for i in range(math.ceil(klen / self._v)):
         t = bitarray.concat((t, self._hash(bitarray.concat((z, ct)))))
         ct = ct + bitarray(1, 32)
     return t[:klen]
Beispiel #2
0
 def _padding(self, data: bitarray) -> bitarray:
     mlen = len(data)
     data = bitarray.concat((data, bitarray(1, 1)))
     plen = (-mlen - 65) % 512
     data = bitarray.concat((data, bitarray(0, plen)))
     data = bitarray.concat((data, bitarray(mlen, 64)))
     return data.split(512)
Beispiel #3
0
 def _pad10star1(self, data: bitarray) -> bitarray:
     q = (self._r - len(data) % self._r) // 8
     if q == 1:
         data = bitarray.concat((data, bitarray(0x86, 8)))
     else:
         data = bitarray.concat(
             (data, bitarray(0x06,
                             8), bitarray(0,
                                          8 * (q - 2)), bitarray(0x80, 8)))
     return data
Beispiel #4
0
 def decrypt_data(self, C: bitarray, SK: int) -> bitarray:
     c1, C = C[:self._byteLen * 8 * 2 + 8], C[self._byteLen * 8 * 2 + 8:]
     c3, c2 = C[:self._v], C[self._v:]
     c1 = self._bytes2point(self._bits2bytes(c1))
     p2 = SK * c1
     x2 = self._bytes2bits(self._elem2bytes(p2.x))
     y2 = self._bytes2bits(self._elem2bytes(p2.y))
     t = self._kdf(bitarray.concat((x2, y2)), len(c2))
     M = c2 ^ t
     u = self._hash(bitarray.concat((x2, M, y2)))
     assert u == c3
     return M
Beispiel #5
0
 def encrypt_data(self, M: bitarray, PK: ECC) -> bitarray:
     k = random.randint(1, self._n - 1)
     c1 = k * self._G
     c1 = self._bytes2bits(self._point2bytes(c1))
     p2 = k * PK
     x2 = self._bytes2bits(self._elem2bytes(p2.x))
     y2 = self._bytes2bits(self._elem2bytes(p2.y))
     t = self._kdf(bitarray.concat((x2, y2)), len(M))
     c2 = M ^ t
     c3 = self._hash(bitarray.concat((x2, M, y2)))
     C = bitarray.concat((c1, c3, c2))
     return C
Beispiel #6
0
 def _sponge(self, data: bitarray, dlen: int) -> bitarray:
     data = self._pad10star1(data)
     data = self._permute(data)
     dseq = data.split(self._r)
     s = bitarray(0, self._b)
     for di in dseq:
         s = self._keccak_p(s ^ bitarray.concat((di, bitarray(0, self._c))))
     z = bitarray()
     while len(z) < dlen:
         z = bitarray.concat((z, s[0:self._r]))
         s = self._keccak_p(s)
     z = self._permute(z)
     return z[0:dlen]
Beispiel #7
0
 def __call__(self, key: bytes, data: bytes) -> bytes:
     # padding key
     if len(key) > self._b // 8:
         key = self._hash_func(key).digest
     key = bitarray.from_bytes(key)
     k = bitarray.concat((key, bitarray(0, self._b - len(key))))
     # process data
     data = bitarray.from_bytes(data)
     si = k ^ self._ipad
     data = bitarray.concat((si, data))
     data = self._hash(data)
     so = k ^ self._opad
     data = bitarray.concat((so, data))
     data = self._hash(data)
     return Digest(data.to_bytes())
Beispiel #8
0
 def __call__(self, data: bytes) -> Digest:
     data = bitarray.from_bytes(data)
     chunks = self._padding(data)
     h0, h1, h2, h3, h4 = self._h
     for chunk in chunks:
         w = chunk.split(32)
         for i in range(16, 80):  # 32 words -> 80 words
             w.append((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) << 1)
         a, b, c, d, e = h0, h1, h2, h3, h4
         for i in range(80):
             if 0 <= i <= 19:
                 f = (b & c) | ((~b) & d)
                 k = bitarray(0x5A827999, 32)
             elif 20 <= i <= 39:
                 f = b ^ c ^ d
                 k = bitarray(0x6ED9EBA1, 32)
             elif 40 <= i <= 59:
                 f = (b & c) | (b & d) | (c & d)
                 k = bitarray(0x8F1BBCDC, 32)
             elif 60 <= i <= 79:
                 f = b ^ c ^ d
                 k = bitarray(0xCA62C1D6, 32)
             temp = (a << 5) + f + e + k + w[i]
             a, b, c, d, e = temp, a, b << 30, c, d
         h0, h1, h2, h3, h4 = h0 + a, h1 + b, h2 + c, h3 + d, h4 + e
     digest = bitarray.concat((h0, h1, h2, h3, h4))
     return Digest(digest.to_bytes())
Beispiel #9
0
 def _identity(self, uid:bitarray, PK) -> bitarray:
     entlen = bitarray(len(uid), 16)
     a = self._bytes2bits(self._elem2bytes(self._G.a))
     b = self._bytes2bits(self._elem2bytes(self._G.b))
     gx = self._bytes2bits(self._elem2bytes(self._G.x))
     gy = self._bytes2bits(self._elem2bytes(self._G.y))
     ax = self._bytes2bits(self._elem2bytes(PK.x))
     ay = self._bytes2bits(self._elem2bytes(PK.y))
     return self._hash(bitarray.concat((entlen, uid, a, b, gx, gy, ax, ay)))[:256]
Beispiel #10
0
 def verify(self, M:bytes, sign:tuple, uid:bytes, PK):
     r, s = sign
     r, s = self._bytes2int(r), self._bytes2int(s)
     assert 1 <= r <= self._n-1 and 1 <= s <= self._n-1
     M, uid = self._bytes2bits(M), self._bytes2bits(uid)
     Z = self._identity(uid, PK)
     M = bitarray.concat((Z, M))
     e = self._bytes2int(self._bits2bytes(self._hash(M)))
     t = (r + s) % self._n
     assert t != 0
     P = s * self._G + t * PK
     x1 = self._elem2int(P.x)
     R = (e + x1) % self._n
     return R == r
Beispiel #11
0
 def sign(self, M:bytes, uid:bytes, SK:int) -> tuple:
     M, uid = self._bytes2bits(M), self._bytes2bits(uid)
     PK = SK * self._G
     Z = self._identity(uid, PK)
     M = bitarray.concat((Z, M))
     e = self._bytes2int(self._bits2bytes(self._hash(M)))
     while True:
         k = random.randint(1, self._n-1)
         P = k * self._G
         x1 = self._elem2int(P.x)
         r = (e + x1) % self._n
         if r == 0 or r+k == self._n:
             continue
         s = (inverse(1+SK, self._n) * (k-r*SK)) % self._n
         if s != 0:
             break
     r, s = self._int2bytes(r, self._byteLen), self._int2bytes(s, self._byteLen)
     return (r, s)
Beispiel #12
0
 def __init__(self, hash_func: callable):
     self._hash_func = hash_func
     self._n = hash_func.digest_size * 8
     self._b = hash_func.hmac_size
     self._ipad = bitarray.concat([bitarray(0x36, 8)] * (self._b // 8))
     self._opad = bitarray.concat([bitarray(0x5C, 8)] * (self._b // 8))
Beispiel #13
0
 def _permute(self, b: bitarray) -> bitarray:  # little order transform
     blist = b.split(8)  # per byte
     return bitarray.concat([blist[i].reverse() for i in range(len(blist))])
Beispiel #14
0
 def _state2bits(self, state: list) -> bitarray:
     return bitarray.concat(
         [state[x][y] for y in range(5) for x in range(5)])