Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

rs_reference.py

v0.1.0-build.85 Latest Commit ede38f5

Size
1.8 KB
Lines
58
Language
python
SHA-256
ae64316cee28…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1#!/usr/bin/env python3
2"""Independent RS parity reference for the current versioned CKey locator test vector.
3
4This is a test oracle only. Product SDKs must call the portable C++ core.
5It uses polynomial long division with shift/XOR field multiplication.
6"""
7import json
8from pathlib import Path
9
10
11def gf_mul(a: int, b: int) -> int:
12 result = 0
13 while b:
14 if b & 1:
15 result ^= a
16 a <<= 1
17 if a & 0x100:
18 a ^= 0x11D
19 b >>= 1
20 return result
21
22
23def gf_pow(a: int, n: int) -> int:
24 result = 1
25 for _ in range(n):
26 result = gf_mul(result, a)
27 return result
28
29
30def generator(parity_bytes: int) -> list[int]:
31 coefficients = [1]
32 for i in range(parity_bytes):
33 root = gf_pow(2, i)
34 product = [0] * (len(coefficients) + 1)
35 for j, coefficient in enumerate(coefficients):
36 product[j] ^= coefficient
37 product[j + 1] ^= gf_mul(coefficient, root)
38 coefficients = product
39 return coefficients
40
41
42def encode(data: bytes, parity_bytes: int) -> bytes:
43 gen = generator(parity_bytes)
44 remainder = list(data) + [0] * parity_bytes
45 for i in range(len(data)):
46 factor = remainder[i]
47 for j, coefficient in enumerate(gen):
48 remainder[i + j] ^= gf_mul(factor, coefficient)
49 return bytes(remainder[-parity_bytes:])
50
51
52if __name__ == "__main__":
53 fixture = json.loads(Path("tests/vectors/locator-v11.json").read_text())
54 actual = encode(bytes.fromhex(fixture["frame_hex"]), fixture["rs_parameters"]["n"] - fixture["rs_parameters"]["k"]).hex()
55 expected = fixture["rs_parameters"]["parity_hex"]
56 if actual != expected:
57 raise SystemExit(f"RS fixture mismatch: {actual} != {expected}")
58 print(f"Independent RS fixture verified: {actual}")