# 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 1. `reference_signer.py` builds three license keys from scratch using the exact byte layouts documented in `licensing-service/src/crypto/mod.rs`. It uses Python's `cryptography` for 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. 2. `run_ts.mjs` imports 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, `isExpiredAt` boundaries, and tamper detection. Also spot-checks `hashFingerprint` against Python's `hashlib.sha256` and 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 ```bash # 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`).