Glue files not covered by subproject repos: top-level docs, logo, keysat-design-system, and crosscheck tests. Subproject folders are gitignored (each has its own Gitea remote).
3.2 KiB
Format cross-check
Verifies that the three implementations of the LIC1-...-... key format
(licensing-service in Rust, licensing-client-rust SDK, licensing-client-ts SDK)
all agree, byte for byte, on both the legacy v1 payload layout and the
current v2 layout.
Approach
-
reference_signer.pybuilds three license keys from scratch using the exact byte layouts documented inlicensing-service/src/crypto/mod.rs. It uses Python'scryptographyfor Ed25519 signing — an independent implementation from the Rust one, so agreement here is strong evidence the format is correct, not just that the Rust side agrees with itself.The three keys exercise every branch of the parser:
v1— legacy fixed-74 payload, fingerprint-bound. New keys aren't issued in v1 anymore, but SDKs must still accept them indefinitely so old keys in the wild keep working.v2— trial key, fingerprint-bound, with explicit expiry and two entitlements. Stresses the variable-length tail parser.v2_perpetual_unbound— the "happy path" for a normal paid purchase: v2, no expiry, no fingerprint binding, no entitlements.
-
run_ts.mjsimports the built TypeScript SDK (dist/index.js) and runs each of the three fixtures through: field-by-field parse, signature verification, fingerprint binding (positive + negative), entitlement lookup,isExpiredAtboundaries, and tamper detection. Also spot-checkshashFingerprintagainst Python'shashlib.sha256and public-key loading.
Rust SDK coverage
The Rust SDK uses the same crates as the service (data_encoding::BASE32_NOPAD,
ed25519_dalek) with identical byte offsets (licensing-client-rust/src/key.rs
mirrors licensing-service/src/crypto/mod.rs), so round-trip compatibility is
guaranteed by construction. If you change the layout, update the service's
from_bytes, the Rust SDK's from_bytes, and reference_signer.py together.
The Rust SDK's own unit tests (cargo test -p licensing-client) round-trip
every flag + version combination.
Running
# Build the TS SDK first.
cd licensing-client-ts
npm install
npm run build
cd ../tests/crosscheck
python3 reference_signer.py > vector.json
node --experimental-vm-modules run_ts.mjs
Current test vectors
Both vectors share a deterministic signing key seeded with bytes(range(32)),
so the license strings in vector.json are stable across regenerations (a
regression in encoding will produce a git diff).
| fixture | version | expires_at | entitlements | flags |
|---|---|---|---|---|
v1 |
1 | (n/a) | (n/a) | FINGERPRINT_BOUND |
v2 |
2 | 1900000000 | ["pro","multi-device"] |
FINGERPRINT_BOUND | TRIAL |
v2_perpetual_unbound |
2 | 0 | [] |
0 |
Product UUID: 6f46a4f6-0d2f-4a28-b6aa-3e8fbf6f28f0, fingerprint raw string
"test-machine-fingerprint" (SHA-256
d34461ff63170de633b5aa2512ce2e15ac120b1c325acdada67c02e594ba3b3d).