diff options
author | Eric Biggers <ebiggers@kernel.org> | 2025-07-09 23:01:12 +0300 |
---|---|---|
committer | Eric Biggers <ebiggers@kernel.org> | 2025-07-14 21:29:36 +0300 |
commit | 6dd4d9f7919e73bc7ad247eca82e8be1c123af0a (patch) | |
tree | 590b35e24e3142b498ab55c63611249e76609fd6 /scripts/crypto/gen-hash-testvecs.py | |
parent | 571eaeddb67df84c4fd59c5496866c049fb25efe (diff) | |
download | linux-6dd4d9f7919e73bc7ad247eca82e8be1c123af0a.tar.xz |
lib/crypto: tests: Add KUnit tests for Poly1305
Add a KUnit test suite for the Poly1305 functions. Most of its test
cases are instantiated from hash-test-template.h, which is also used by
the SHA-2 tests. A couple additional test cases are also included to
test edge cases specific to Poly1305.
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250709200112.258500-5-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Diffstat (limited to 'scripts/crypto/gen-hash-testvecs.py')
-rwxr-xr-x | scripts/crypto/gen-hash-testvecs.py | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py index 55f1010339a6..4ac927d40cf5 100755 --- a/scripts/crypto/gen-hash-testvecs.py +++ b/scripts/crypto/gen-hash-testvecs.py @@ -24,7 +24,37 @@ def rand_bytes(length): out.append((seed >> 16) % 256) return bytes(out) +POLY1305_KEY_SIZE = 32 + +# A straightforward, unoptimized implementation of Poly1305. +# Reference: https://cr.yp.to/mac/poly1305-20050329.pdf +class Poly1305: + def __init__(self, key): + assert len(key) == POLY1305_KEY_SIZE + self.h = 0 + rclamp = 0x0ffffffc0ffffffc0ffffffc0fffffff + self.r = int.from_bytes(key[:16], byteorder='little') & rclamp + self.s = int.from_bytes(key[16:], byteorder='little') + + # Note: this supports partial blocks only at the end. + def update(self, data): + for i in range(0, len(data), 16): + chunk = data[i:i+16] + c = int.from_bytes(chunk, byteorder='little') + 2**(8 * len(chunk)) + self.h = ((self.h + c) * self.r) % (2**130 - 5) + return self + + # Note: gen_additional_poly1305_testvecs() relies on this being + # nondestructive, i.e. not changing any field of self. + def digest(self): + m = (self.h + self.s) % 2**128 + return m.to_bytes(16, byteorder='little') + def hash_init(alg): + if alg == 'poly1305': + # Use a fixed random key here, to present Poly1305 as an unkeyed hash. + # This allows all the test cases for unkeyed hashes to work on Poly1305. + return Poly1305(rand_bytes(POLY1305_KEY_SIZE)) return hashlib.new(alg) def hash_update(ctx, data): @@ -89,9 +119,21 @@ def gen_hmac_testvecs(alg): f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]', ctx.digest()) +def gen_additional_poly1305_testvecs(): + key = b'\xff' * POLY1305_KEY_SIZE + data = b'' + ctx = Poly1305(key) + for _ in range(32): + for j in range(0, 4097, 16): + ctx.update(b'\xff' * j) + data += ctx.digest() + print_static_u8_array_definition( + 'poly1305_allones_macofmacs[POLY1305_DIGEST_SIZE]', + Poly1305(key).update(data).digest()) + if len(sys.argv) != 2: sys.stderr.write('Usage: gen-hash-testvecs.py ALGORITHM\n') - sys.stderr.write('ALGORITHM may be any supported by Python hashlib.\n') + sys.stderr.write('ALGORITHM may be any supported by Python hashlib, or poly1305.\n') sys.stderr.write('Example: gen-hash-testvecs.py sha512\n') sys.exit(1) @@ -99,4 +141,7 @@ alg = sys.argv[1] print('/* SPDX-License-Identifier: GPL-2.0-or-later */') print(f'/* This file was generated by: {sys.argv[0]} {" ".join(sys.argv[1:])} */') gen_unkeyed_testvecs(alg) -gen_hmac_testvecs(alg) +if alg == 'poly1305': + gen_additional_poly1305_testvecs() +else: + gen_hmac_testvecs(alg) |