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
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 | |
| 4 | This is a test oracle only. Product SDKs must call the portable C++ core. |
| 5 | It uses polynomial long division with shift/XOR field multiplication. |
| 6 | """ |
| 7 | import json |
| 8 | from pathlib import Path |
| 9 | |
| 10 | |
| 11 | def 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 | |
| 23 | def 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 | |
| 30 | def 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 | |
| 42 | def 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 | |
| 52 | if __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}") |