Skip to content

docs: mark orbinum-zk-circuits as a non-production reference implementation - #137

Open
0xrlawrence wants to merge 1 commit into
orbinum:mainfrom
0xrlawrence:docs/mark-zk-circuits-non-production
Open

docs: mark orbinum-zk-circuits as a non-production reference implementation#137
0xrlawrence wants to merge 1 commit into
orbinum:mainfrom
0xrlawrence:docs/mark-zk-circuits-non-production

Conversation

@0xrlawrence

Copy link
Copy Markdown

The verification keys registered on chain are generated from the Circom sources in orbinum/circuits. primitives/zk-circuits is a separate arkworks implementation of the same circuits, and nothing in its documentation says so. It carries a crates.io badge, an install snippet, and a "Prove" usage example, so the reasonable reading is that it is what produces Orbinum proofs.

The two have drifted:

primitives/zk-circuits orbinum/circuits
Unshield public signals 6 7, including change_commitment
Unshield change note not modelled supported
Range checks on note values none Num2Bits(128)

The signal count is the easy one to spot: UnshieldCircuit::public_inputs() returns six, while UNSHIELD_PUBLIC_INPUTS, encode_unshield and unshield.circom all agree on seven.

The range checks are why this is worth a warning rather than a note. Balance conservation in this crate is enforced as field arithmetic with no bound on any value, so sum(inputs) == sum(outputs) + fee can be satisfied by wrapping modulo the BN254 scalar field. A trusted setup run against TransferCircuit or UnshieldCircuit would produce a verifier that accepts inflated notes, and nothing currently warns a reader off doing exactly that. The deployed Circom circuits apply Num2Bits(128) to every value and are not affected, which is why this is a packaging problem rather than a chain problem.

What this changes

Adds the warning to the crate README and to the crate-level docs, and links orbinum/circuits from the root README, which described the circuits without saying where they live.

The divergences are described rather than fixed. Which direction to reconcile them is your call: deleting the crate, demoting it to a checked reference implementation with cross-implementation vector tests against the orbinum/circuits fixtures, or bringing it back into line all seem defensible, and I did not want to pick one on your behalf.

Verification

Documentation and comments only, no code changed. I was not able to build the workspace, so cargo doc is unrun; the crate-level block is plain //! text with intra-doc links avoided, so I would not expect rustdoc warnings, but treat that as unverified.


Separately, I have emailed security@orbinum.net about a number of higher-severity findings from the same review pass. Those are deliberately not in this PR, in any other PR, or in a public issue. Nothing above is one of them: the range-check gap is confined to this unused crate, and I confirmed the deployed circuits are sound before writing any of this down.

…tation

The verification keys registered on chain are generated from the Circom
sources in orbinum/circuits. This crate is a separate arkworks implementation
of the same circuits, and nothing in its documentation says so. It carries a
crates.io badge, an install snippet, and a "Prove" usage example, so the
reasonable reading is that it is the thing that produces Orbinum proofs.

The two have drifted:

- UnshieldCircuit exposes 6 public signals; unshield.circom declares 7,
  including change_commitment, which is also what UNSHIELD_PUBLIC_INPUTS and
  encode_unshield expect.
- UnshieldCircuit does not model a change note at all, while both the pallet
  and the deployed circuit support partial unshield.
- Neither circuit here constrains note values to a range. Balance conservation
  is enforced as field arithmetic, so sum(inputs) == sum(outputs) + fee can be
  satisfied by wrapping modulo the BN254 scalar field. The deployed Circom
  circuits apply Num2Bits(128) to every value and are not affected.

The last point is why this is worth a warning rather than a note: a trusted
setup run against TransferCircuit or UnshieldCircuit would produce a verifier
that accepts inflated notes, and nothing currently warns a reader off doing
that.

Adds the warning to the crate README and the crate-level docs, and links
orbinum/circuits from the root README, which described the circuits without
saying where they live.

Documentation only. No code is changed, and the divergences above are
described rather than fixed, since which direction to reconcile them is a
decision for the team.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant