typed proof
vrl.shipping.linear-sum.v1
Domain-specific zero-knowledge proof entry for the VRL Proof Bundle proofs[] array. Proves that hidden per-component shipping costs sum to a public expected total under a committed pricing policy, with each committed value provably in [0, 2^28).
proof_typevrl.shipping.linear-sum.v1proof_version1.0.0domainshippingschemepedersen-linear-nizk-v1 + vrl-zk-range-bit-or-v1grouprfc3526-group14-qr (RFC 3526 group 14, order-q QR subgroup, 2048-bit safe prime)trusted setupNone. No-trusted-setup Fiat-Shamir NIZK.reference impl@perathos/vrl-zk-shippingspec statusDraft amendment for vrl-protocol/spec v0.2.0What it proves
For six private committed components — base rate, fuel surcharge, residential fee, oversize fee, other accessorials, customer discount — a verifier learns, without seeing any component value, that:
- each committed value is a non-negative integer below
2^28(Chaum-Pedersen bit-decomposition range proof); - the signed linear combination of the six values equals a public
expected_total_cents(Schnorr-style Fiat-Shamir NIZK); - the proof transcript is bound to
quote_id,policy_hash, and the range proofs, preventing replay or cross-quote substitution; - the entry as a whole is hash-bound — any tampering with statement, payload, or metadata invalidates
hash.
What it does not prove yet
- That the carrier rate sheet itself is truthful or current.
- That shipment dimensions, weight, or service classification are correct.
- That a private rate-card row belongs to an approved Merkle root (planned:
vrl.shipping.rate-membership.v1). - That an AI model selected the correct shipping method.
Entry shape
{
"proof_type": "vrl.shipping.linear-sum.v1",
"proof_version": "1.0.0",
"domain": "shipping",
"scheme": "pedersen-linear-nizk-v1+vrl-zk-range-bit-or-v1",
"group": "rfc3526-group14-qr",
"created_at": "2026-05-12T17:42:11.823Z",
"statement": {
"quote_id": "...",
"policy_hash": "sha256:...",
"expected_total_cents": 13420,
"billed_total_cents": 13999,
"variance_cents": 579,
"dispute_status": "review",
"formula": "base + fuel + residential + oversize + other_accessorials - discount",
"component_order": [ { "key": "baseRateCents", "coefficient": 1 }, ... ],
"range_bits": 28,
"input_commitment": "sha256:<digest of commitments+range_proofs>"
},
"payload": {
"commitments": { "baseRateCents": "0x...", ... },
"range_proofs": { "baseRateCents": { "scheme": "vrl-zk-range-bit-or-v1", "bits": 36, ... }, ... },
"proof": { "scheme": "pedersen-linear-nizk-v1", "group": "...", "challenge": "0x...", ... },
"group_parameters": { "group": "...", "hGenerator": "0x...", "hDerivation": {...}, ... }
},
"privacy": {
"privateAmountsHidden": true,
"rangeProof": "vrl-zk-range-bit-or-v1",
"rangeBits": 28
},
"hash": "sha256:<canonical digest of the entry, excluding the hash field>"
}Verifier behavior
A generic VRL Proof Bundle consumer that encounters this entry should:
- Dispatch on
proof_typeandproof_version. - Recompute the canonical hash and compare to
hash. - Verify each per-component range proof (bit-OR proofs + aggregation against the parent commitment).
- Verify the Schnorr linear-relation proof against the Fiat-Shamir challenge derived from the transcript.
- Return
{ ok: true | false, reason? }without aggregating other entries — each entry stands or falls on its own.
Stability
This is the v1 proof type. Backward-incompatible changes — different group, different range-proof scheme, expanded statement fields — will be published as vrl.shipping.linear-sum.v2, not as a silent revision of v1.