perathos
docs/vrl-proof-bundle/proofs / tariff-duty-membership-v1

typed proof

vrl.tariff.duty-membership.v1

Domain-specific zero-knowledge proof entry for customs duty verification. Proves the duty figure on a customs filing was computed from a row in a published, root-pinned tariff schedule, without revealing the declared customs value.

proof_typevrl.tariff.duty-membership.v1
proof_version1.0.0
domaintariff
schemevrl-zk-tariff-duty-nizk-v1 + vrl-zk-range-bit-or-v1 + vrl-merkle-v1
grouprfc3526-group14-qr (RFC 3526 group 14, 2048-bit safe prime, QR subgroup)
trusted setupNone. No-trusted-setup Fiat-Shamir NIZK.
reference impl@perathos/vrl-zk-tariff
spec statusDraft amendment for vrl-protocol/spec v0.2.0

What it proves

For a public HS code and duty figure on a customs filing, the verifier learns:

  • the (hsCode, ratePpm, jurisdiction) row is a member of the committed schedule Merkle root — no fabricated rates;
  • the declared customs value is a non-negative integer below 2^36 (range proof);
  • the integer-division remainder is in [0, 1,000,000) (tight range proof);
  • ratePpm × value − remainder = duty × 1,000,000 (Schnorr linear-relation proof under a public coefficient);
  • combined: duty = floor(value × ratePpm / 1,000,000);
  • the entry transcript is bound to the schedule root, range proofs, and Merkle path — no replay or substitution.

Privacy posture

hidden

  • declared customs value (in cents)
  • integer-division remainder

revealed

  • HS code, jurisdiction
  • rate (parts per million)
  • declared duty (in cents)
  • schedule root, leaf hash

HS code and rate are intentionally revealed in v1 because the rate is publicly derivable from the HS code via the same schedule — hiding the rate while revealing the HS code provides no real privacy. A future v2 may hide the HS code too, via a hash-to-commitment encoding of leaves.

What it does not prove

  • That the importer used the correct HS code for the goods. Classification is a separate problem.
  • That the declared value is the true commercial value. The proof binds the arithmetic to a hidden value; it does not certify the value itself.
  • That an authority signed the schedule root. Root pinning to a customs-authority signature is a separate step.

Entry shape

{
  "proof_type": "vrl.tariff.duty-membership.v1",
  "proof_version": "1.0.0",
  "domain": "tariff",
  "scheme": "vrl-zk-tariff-duty-nizk-v1+vrl-zk-range-bit-or-v1+vrl-merkle-v1",
  "group": "rfc3526-group14-qr",
  "created_at": "2026-05-12T17:42:11.823Z",
  "statement": {
    "hs_code": "8471.30.0100",
    "jurisdiction": "US",
    "rate_ppm": 67500,
    "declared_duty_cents": 16875,
    "schedule_root": "sha256:...",
    "leaf": "sha256:...",
    "effective_from": null,
    "effective_until": null,
    "value_bits": 36,
    "remainder_bits": 20,
    "ppm_denominator": 1000000,
    "input_commitment": "sha256:..."
  },
  "payload": {
    "commitments":      { "value": "0x...", "remainder": "0x..." },
    "range_proofs":     { "value": {...}, "remainder": {...} },
    "merkle_path":      [ { "sibling": "sha256:...", "currentIsLeft": true }, ... ],
    "merkle_scheme":    "vrl-merkle-v1",
    "proof":            { "scheme": "...", "challenge": "0x...", "nonceCommitments": {...}, "responses": {...} },
    "group_parameters": { "group": "...", "hGenerator": "0x...", ... }
  },
  "privacy": {
    "hiddenFields":   [ "declaredValueCents", "remainder" ],
    "revealedFields": [ "hsCode", "ratePpm", "jurisdiction", "declaredDutyCents", "scheduleRoot", "leaf" ],
    "rangeProof":     "vrl-zk-range-bit-or-v1"
  },
  "hash": "sha256:<canonical digest of the entry, excluding the hash field>"
}

Stability

This is the v1 proof type. Backward-incompatible changes — different group, different range-proof scheme, hiding the HS code, multi-jurisdiction proofs — will be published as vrl.tariff.duty-membership.v2, not as a silent revision of v1.