All checks were successful
joule-moq-remote host agent / joule-moq-remote · does this change touch it (pull_request) Successful in 9s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 10s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 9s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 9s
wai-app and Create / wai-app · does this change touch it (pull_request) Successful in 6s
wai-audit collector and player integration / does this change touch it (pull_request) Successful in 7s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (pull_request) Successful in 8s
WAI energy receipts / does this change touch it (pull_request) Successful in 6s
WAI examples / WAI examples · does this change touch them (pull_request) Successful in 6s
wai-fleet service / does this change touch it (pull_request) Successful in 6s
WAI operation catalogue / does this change touch it (pull_request) Successful in 13s
WAI conformance / does this change touch it (pull_request) Successful in 13s
wai-key-proxy / does this change touch it (pull_request) Successful in 6s
wai-ledger service / does this change touch it (pull_request) Successful in 6s
WAI neural sink gates / does this change touch it (pull_request) Successful in 5s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 7s
wai-sink-android native sink library / does this change touch it (pull_request) Successful in 6s
wai-quantum for JavaScript / does this change touch it (pull_request) Successful in 9s
wai-sink-swift native sink package / does this change touch it (pull_request) Successful in 7s
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Successful in 14s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 15s
WAI Studio / does this change touch it (pull_request) Successful in 6s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 7s
wai-web wasm32 / does this change touch it (pull_request) Successful in 13s
WAI conformance / fast integer kernels, every x86_64 kernel set (AVX-512 silicon) (pull_request) Successful in 3m27s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (pull_request) Successful in 33s
wai-audit collector and player integration / collector · linux (pull_request) Successful in 1m8s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (pull_request) Successful in 2m56s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 33s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (pull_request) Successful in 3m29s
wai-fleet service / service · linux (pull_request) Successful in 2m40s
wai-key-proxy / proxy · linux (pull_request) Successful in 1m5s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 3m17s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m50s
wai-quantum studio and desktop / desktop app · windows (pull_request) Successful in 9m14s
wai-ledger service / service · linux (pull_request) Successful in 2m4s
WAI operation catalogue / the catalogue and every door · linux (pull_request) Successful in 5m10s
WAI conformance / faces from keypoints under wasm32-wasip2 (wasmtime) (pull_request) Successful in 3m51s
WAI neural sink gates / the exact JPEG-AI decoder reports its path (pinned inputs, required) (pull_request) Successful in 2m38s
wai-pack / wai-pack · linux (pull_request) Successful in 1m47s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 3m57s
wai-quantum for JavaScript / javascript · linux (pull_request) Successful in 2m57s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (pull_request) Successful in 2m31s
WAI examples / WAI examples · portable · linux (pull_request) Successful in 8m25s
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Successful in 3m32s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m36s
wai-quantum studio and desktop / desktop app · linux (pull_request) Successful in 5m39s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m29s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 5m56s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 11m58s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 30m34s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 38m39s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 1m5s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m47s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 10m35s
wai-fleet service / service · macos (pull_request) Successful in 42s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Successful in 10m37s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 55s
wai-ledger service / service · macos (pull_request) Successful in 1m10s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 2m1s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 16m26s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 12m18s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 6m34s
wai-pack / wai-pack · macos (pull_request) Successful in 2m57s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 7m29s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 14m38s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 11m1s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 15m43s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 15m44s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 12m18s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 1m24s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (pull_request) Successful in 1m11s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 3m35s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 6m14s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 5m41s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 44s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 12m22s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 16s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 32s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 2m3s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m38s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m53s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 17m20s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 25s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 15s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 6m59s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 18m2s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h12m0s
The change of wai/prior-carriage-spec (98192fe63..26834bb4c, 6 commits), on the fix branch: its changelog entries as files of wai/changes/, its wai-conformance.yml edits as step files, corpus files and test tags, and every other file as the branch has it. - e5db9b313 wai: where a parameter set is fetched — set roots, location hints, and <base> defined - 29fe43ea2 wai: a parameter set as an RFC 9842 compression dictionary, with a vector a stock client checks - faaeb6c73 wai: when a parameter set is worth holding — amortisation charged per sink, bootstrap and generations - 9a820db4a wai: a parameter set's usage statement, sealed sets released by key, leakage, and the privacy of held sets - 89a9f9924 wai: the chunk-tree prior form, wai.prior.tree — a set verified piece by piece from any peers - 26834bb4c wai: one playlist line of set roots, inner forms as the layouts list them, and a listing's usage statement read or the set refused Co-Authored-By: Claude Opus 5.5 <[email protected]>
100 lines
3.4 KiB
Python
100 lines
3.4 KiB
Python
"""AES-128 encryption of one block, written from FIPS 197, and counter mode from NIST SP 800-38A
|
|
§6.5, in pure Python, for the prior-carriage verifier's sealed sets (prior-carriage §18.2).
|
|
|
|
It shares no code with wai-rs, which uses a Rust AES implementation. Only the forward cipher is
|
|
needed: counter mode encrypts and decrypts with it alike.
|
|
"""
|
|
|
|
|
|
def _xtime(a):
|
|
a <<= 1
|
|
return (a ^ 0x11B) & 0xFF if a & 0x100 else a
|
|
|
|
|
|
def _mul(a, b):
|
|
r = 0
|
|
while b:
|
|
if b & 1:
|
|
r ^= a
|
|
a = _xtime(a)
|
|
b >>= 1
|
|
return r
|
|
|
|
|
|
def _sbox():
|
|
"""FIPS 197 §5.1.1: the multiplicative inverse in GF(2^8), then the affine transformation."""
|
|
inv = [0] * 256
|
|
for a in range(1, 256):
|
|
for b in range(1, 256):
|
|
if _mul(a, b) == 1:
|
|
inv[a] = b
|
|
break
|
|
box = []
|
|
for a in range(256):
|
|
b = inv[a]
|
|
s = b
|
|
for k in range(1, 5):
|
|
s ^= ((b << k) | (b >> (8 - k))) & 0xFF
|
|
box.append(s ^ 0x63)
|
|
return box
|
|
|
|
|
|
SBOX = _sbox()
|
|
|
|
|
|
def expand_key(key):
|
|
"""FIPS 197 §5.2 for a 16-byte key: 11 round keys of 16 bytes."""
|
|
assert len(key) == 16
|
|
w = [list(key[4 * i:4 * i + 4]) for i in range(4)]
|
|
rcon = 1
|
|
for i in range(4, 44):
|
|
t = list(w[i - 1])
|
|
if i % 4 == 0:
|
|
t = [SBOX[x] for x in t[1:] + t[:1]]
|
|
t[0] ^= rcon
|
|
rcon = _xtime(rcon)
|
|
w.append([a ^ b for a, b in zip(w[i - 4], t)])
|
|
return [sum(w[4 * r:4 * r + 4], []) for r in range(11)]
|
|
|
|
|
|
def encrypt_block(round_keys, block):
|
|
"""FIPS 197 §5.1: the state in column order, ten rounds."""
|
|
s = [b ^ k for b, k in zip(block, round_keys[0])]
|
|
for r in range(1, 11):
|
|
s = [SBOX[x] for x in s]
|
|
# ShiftRows: byte (row, column) at index 4 * column + row moves left by its row.
|
|
s = [s[4 * ((c + row) % 4) + row] for c in range(4) for row in range(4)]
|
|
if r != 10:
|
|
out = []
|
|
for c in range(4):
|
|
a = s[4 * c:4 * c + 4]
|
|
out += [_mul(a[0], 2) ^ _mul(a[1], 3) ^ a[2] ^ a[3],
|
|
a[0] ^ _mul(a[1], 2) ^ _mul(a[2], 3) ^ a[3],
|
|
a[0] ^ a[1] ^ _mul(a[2], 2) ^ _mul(a[3], 3),
|
|
_mul(a[0], 3) ^ a[1] ^ a[2] ^ _mul(a[3], 2)]
|
|
s = out
|
|
s = [b ^ k for b, k in zip(s, round_keys[r])]
|
|
return bytes(s)
|
|
|
|
|
|
def ctr(key, iv, data):
|
|
"""Counter mode: the counter block from `iv`, incremented as one 128-bit big-endian integer."""
|
|
rk = expand_key(key)
|
|
counter = int.from_bytes(iv, "big")
|
|
out = bytearray()
|
|
for i in range(0, len(data), 16):
|
|
ks = encrypt_block(rk, counter.to_bytes(16, "big"))
|
|
out += bytes(a ^ b for a, b in zip(data[i:i + 16], ks))
|
|
counter = (counter + 1) % (1 << 128)
|
|
return bytes(out)
|
|
|
|
|
|
def self_test():
|
|
"""FIPS 197 Appendix C.1 and NIST SP 800-38A F.5.1's first two blocks."""
|
|
rk = expand_key(bytes.fromhex("000102030405060708090a0b0c0d0e0f"))
|
|
if encrypt_block(rk, bytes.fromhex("00112233445566778899aabbccddeeff")).hex() != "69c4e0d86a7b0430d8cdb78070b4c55a":
|
|
return False
|
|
key = bytes.fromhex("2b7e151628aed2a6abf7158809cf4f3c")
|
|
iv = bytes.fromhex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
|
|
plain = bytes.fromhex("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
|
|
return ctr(key, iv, plain).hex() == "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff"
|