scripts/crypto/gen-hash-testvecs.py
Source file repositories/reference/linux-study-clean/scripts/crypto/gen-hash-testvecs.py
File Facts
- System
- Linux kernel
- Corpus path
scripts/crypto/gen-hash-testvecs.py- Extension
.py- Size
- 12804 bytes
- Lines
- 365
- Domain
- Support Tooling And Documentation
- Bucket
- scripts
- Inferred role
- Support Tooling And Documentation: scripts
- Status
- atlas-only
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
- No top-level syscall, struct, function, initcall, or export declaration detected by the generator.
Annotated Snippet
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Script that generates test vectors for the given hash function.
#
# Requires that python-cryptography be installed.
#
# Copyright 2025 Google LLC
import cryptography.hazmat.primitives.ciphers
import cryptography.hazmat.primitives.cmac
import hashlib
import hmac
import sys
DATA_LENS = [0, 1, 2, 3, 16, 32, 48, 49, 63, 64, 65, 127, 128, 129, 256, 511,
513, 1000, 3333, 4096, 4128, 4160, 4224, 16384]
# Generate the given number of random bytes, using the length itself as the seed
# for a simple linear congruential generator (LCG). The C test code uses the
# same LCG with the same seeding strategy to reconstruct the data, ensuring
# reproducibility without explicitly storing the data in the test vectors.
def rand_bytes(length):
seed = length
out = []
for _ in range(length):
seed = (seed * 25214903917 + 11) % 2**48
out.append((seed >> 16) % 256)
return bytes(out)
AES_256_KEY_SIZE = 32
# AES-CMAC. Just wraps the implementation from python-cryptography.
class AesCmac:
def __init__(self, key):
aes = cryptography.hazmat.primitives.ciphers.algorithms.AES(key)
self.cmac = cryptography.hazmat.primitives.cmac.CMAC(aes)
def update(self, data):
self.cmac.update(data)
def digest(self):
return self.cmac.finalize()
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')
Annotation
- Atlas domain: Support Tooling And Documentation / scripts.
- Implementation status: atlas-only.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.