OpenZeppelin / OpenZeppelin/compact-contracts

N-04: Clarify Documentation Around Deterministic Encryption Of Zero And Resulting Metadata Leakage

Open Beginner friendly
#809 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

2-low audit
Dominant language
TypeScript
Stars
55
Forks
29
Avg merge
5d 7h
Merged PRs (30d)
25

Description

N-02 Clarify Documentation Around Deterministic Encryption Of Zero And Resulting Metadata Leakage

Severity: Note

Source: Midnight Foundation #02 — OpenZeppelin Compact Contracts Audit, Release 0.3.0-alpha.1 (2026-08-18)


The encryption of zero returns a fixed pair of identity points rather than a randomized ciphertext, and that value is persisted into the balance and pending maps at registration and written back to pending on every sweep. An observer can therefore identify by inspection any slot still holding it, which discloses that an account is registered but never credited, or that a pending pool has just been swept. A zero arrived at by spending is not identifiable, because subtraction produces a randomized ciphertext, so what leaks is the provenance of the value rather than the value itself.

The deterministic form cannot be replaced because _refundPriorEscrow adds the stored owner copy onto the balance homomorphically, and only the identity leaves that ciphertext byte-identical on a first approve, so a randomized encryption of zero would re-randomize the owner's balance for no value moved. It would also extend the set of operations that depend on seed freshness and cost additional circuit rows, while offering no privacy gain, since register and sweep are public calls and the same facts are derivable from transaction history regardless. The remedy therefore lies in documentation rather than in the construction.

That property is recorded on encryptZero itself, which describes the value as not hiding and warns that a slot left at it is distinguishable as never written. It is absent, however, from the plaintext-disclosure enumeration in the ConfidentialFungibleToken header, which lists amounts, the supply delta, the approve cap and the counterparty graph. An integrator reasoning about what reaches the public ledger consults that enumeration rather than a primitive's docstring, and would otherwise carry an assumption of indistinguishability into a privacy interface.

Consider recording in the ElGamal module header, and as a further entry in the ConfidentialFungibleToken plaintext-disclosure enumeration, that a slot still holding the deterministic sentinel is publicly identifiable as never written or freshly reset, so that a single authoritative place exists for an integrator to consult.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ElGamal module header and the plaintext-disclosure enumeration in contracts/src/token/ConfidentialFungibleToken.compact, then compare them with the encryptZero documentation. Document that the deterministic zero sentinel is publicly identifiable as never written or freshly reset, and ensure both authoritative documentation locations state this metadata leakage.

Written by the indexing model from the issue text.

Assessment

Domain
cryptography, documentation
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.