def _compressauth(m, a, k): k0 = k[0:32] k1 = k[32:48] + bytearray([0] * 16) k2 = k[48:64] + bytearray([0] * 16) p1 = Poly1305(k1) p2 = Poly1305(k2) p1.update(a) p2.update(a) if len(a) & 0xf: pad = bytearray([0] * (16 - (len(a) & 0xf))) p1.update(pad) p2.update(pad) p1.update(m) p2.update(m) if len(m) & 0xf: pad = bytearray([0] * (16 - (len(m) & 0xf))) p1.update(pad) p2.update(pad) len64 = struct.pack('<QQ', len(a), len(m)) p1.update(len64) p2.update(len64) h1 = p1.finalize() h2 = p2.finalize() u0 = hchacha(h1, k0) u = hchacha(h2, u0) return u[0:24]
def test_invalid_verify(self, backend): poly = Poly1305(b"0" * 32) poly.update(b"msg") with pytest.raises(InvalidSignature): poly.verify(b"") p2 = Poly1305(b"0" * 32) p2.update(b"msg") with pytest.raises(InvalidSignature): p2.verify(b"\x00" * 16)
def test_verify(self, backend): poly = Poly1305(b"0" * 32) poly.update(b"msg") tag = poly.finalize() with pytest.raises(AlreadyFinalized): poly.verify(b"") poly2 = Poly1305(b"0" * 32) poly2.update(b"msg") poly2.verify(tag)
def test_invalid_key_length(self, backend): with pytest.raises(ValueError): Poly1305(b"0" * 31) with pytest.raises(ValueError): Poly1305.generate_tag(b"0" * 31, b"msg") with pytest.raises(ValueError): Poly1305(b"0" * 33) with pytest.raises(ValueError): Poly1305.generate_tag(b"0" * 33, b"msg")
def test_verify_reject_unicode(self, backend): poly = Poly1305(b"0" * 32) with pytest.raises(TypeError): poly.verify("") # type:ignore[arg-type] with pytest.raises(TypeError): Poly1305.verify_tag(b"0" * 32, b"msg", "") # type:ignore[arg-type]
def test_reject_unicode(self, backend): poly = Poly1305(b"0" * 32) with pytest.raises(TypeError): poly.update("") # type:ignore[arg-type] with pytest.raises(TypeError): Poly1305.generate_tag(b"0" * 32, "") # type:ignore[arg-type]
def test_verify_reject_unicode(self, backend): poly = Poly1305(b"0" * 32) with pytest.raises(TypeError): poly.verify(u"") with pytest.raises(TypeError): Poly1305.verify_tag(b"0" * 32, b"msg", u"")
def test_vectors(self, vector, backend): key = binascii.unhexlify(vector["key"]) msg = binascii.unhexlify(vector["msg"]) tag = binascii.unhexlify(vector["tag"]) poly = Poly1305(key) poly.update(msg) assert poly.finalize() == tag
def test_reject_unicode(self, backend): poly = Poly1305(b"0" * 32) with pytest.raises(TypeError): poly.update(u"") with pytest.raises(TypeError): Poly1305.generate_tag(b"0" * 32, u"")
def test_raises_after_finalize(self, backend): poly = Poly1305(b"0" * 32) poly.finalize() with pytest.raises(AlreadyFinalized): poly.update(b"foo") with pytest.raises(AlreadyFinalized): poly.finalize()
def test_vectors(self, vector, backend): key = binascii.unhexlify(vector["key"]) msg = binascii.unhexlify(vector["msg"]) tag = binascii.unhexlify(vector["tag"]) poly = Poly1305(key) poly.update(msg) assert poly.finalize() == tag assert Poly1305.generate_tag(key, msg) == tag Poly1305.verify_tag(key, msg, tag)
def poly1305_verify(key, data, nonce, tag): """Verify a Poly1305 tag for a block of data""" poly = Poly1305(poly1305_key(key, nonce)) try: poly.update(data) poly.verify(tag) return True except InvalidSignature: return False
def test_buffer_protocol(self, backend): key = binascii.unhexlify( b"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cb" b"c207075c0") msg = binascii.unhexlify( b"2754776173206272696c6c69672c20616e642074686520736c69746" b"87920746f7665730a446964206779726520616e642067696d626c65" b"20696e2074686520776162653a0a416c6c206d696d7379207765726" b"52074686520626f726f676f7665732c0a416e6420746865206d6f6d" b"65207261746873206f757467726162652e") key = bytearray(key) poly = Poly1305(key) poly.update(bytearray(msg)) assert poly.finalize() == binascii.unhexlify( b"4541669a7eaaee61e708dc7cbcc5eb62")
def __init__(self, encrypt, key, nonce): self._encrypt = encrypt self._dataLength = 0 self._aadLength = 0 self._nonceCounter = (0).to_bytes(4, byteorder='little') + nonce self._nonceEncrypt = (1).to_bytes(4, byteorder='little') + nonce cipher = Cipher(algo.ChaCha20(key, self._nonceEncrypt), None, defb()) if encrypt: self._cipher = cipher.encryptor() else: self._cipher = cipher.decryptor() polyKey = self.__getPolyKey(key) self._auth = Poly1305(polyKey)
def __init__(self, key: bytes, iv: bytes, decrypt: bool = False, aad: bytes = b''): super().__init__(decrypt) self.cipher = Cipher(ChaCha20(key, iv), None, default_backend()).encryptor() # Initialize MAC key mac_key = self.cipher.update(bytes(64))[:32] self.mac = Poly1305(mac_key & b'\xff\xff\xff\x0f\xfc\xff\xff\x0f' b'\xfc\xff\xff\x0f\xfc\xff\xff\x0f' b'\xff\xff\xff\xff\xff\xff\xff\xff' b'\xff\xff\xff\xff\xff\xff\xff\xff') # if AAD exists, update AAD to self.mac if not aad: return self.aad_len = len(aad) pad1_len = 16 - (self.aad_len % 16) % 16 self.mac.update(aad + bytes(pad1_len))
def __init__(self, encrypting, key, nonce): if not len(nonce) in (8, 12): raise ValueError("A 8 or 12 byte nonce is required") if len(nonce) == 8: nonce = bytes(4) + nonce cipher = Cipher( algo.ChaCha20( key, (1).to_bytes(4, "little") + nonce, ), None, defb(), ) ctx = cipher.encryptor() if encrypting else cipher.decryptor() self._encrypting = encrypting self._auth = Poly1305(derive_poly1305_key(key, nonce)) self._ctx = self._get_auth_ctx(encrypting, ctx, self._auth) self._len_aad, self._len_ct = 0, 0 self._updated = False self._tag = None
def test_verify_reject_unicode(self, backend): poly = Poly1305(b"0" * 32) with pytest.raises(TypeError): poly.verify(u'')
def test_key_with_no_additional_references(self, backend): poly = Poly1305(os.urandom(32)) assert len(poly.finalize()) == 16
def test_invalid_key_type(self, backend): with pytest.raises(TypeError): Poly1305(object())
def test_poly1305_unsupported(backend): with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MAC): Poly1305(b"0" * 32)
def test_invalid_key_length(self, backend): with pytest.raises(ValueError): Poly1305(b"0" * 31) with pytest.raises(ValueError): Poly1305(b"0" * 33)
def test_invalid_key_type(self, backend): with pytest.raises(TypeError): Poly1305(object()) with pytest.raises(TypeError): Poly1305.generate_tag(object(), b"msg")
def poly1305(key, data, nonce): """Compute a Poly1305 tag for a block of data""" poly = Poly1305(poly1305_key(key, nonce)) poly.update(data) return poly.finalize()