OpenZeppelin / OpenZeppelin/compact-contracts
N-01: Homomorphic Helpers Cannot Verify That a Ciphertext Was Encrypted Under the Supplied Key
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 55
- Forks
- 29
- Avg merge
- 5d 7h
- Merged PRs (30d)
- 25
Description
N-01 Homomorphic Helpers Cannot Verify That a Ciphertext Was Encrypted Under the Supplied Key
Severity: Note
Source: Midnight Foundation #02 — OpenZeppelin Compact Contracts Audit, Release 0.3.0-alpha.1 (2026-08-18)
The ciphertext type carries only its two curve points and no data binding it to a recipient key. The helpers that fold a plaintext into an existing ciphertext or refresh its randomness accept the public key as a separate argument and have no means of checking it against the ciphertext they modify, so supplying a key other than the one the ciphertext was created under produces a result that decrypts to neither the original plaintext nor any recoverable value. Nothing in the circuit detects the substitution, and a consuming contract that persists the result stores state its rightful holder can no longer open or prove. Correctness is therefore an unstated precondition on every caller rather than a property the module enforces. The consumer in this release satisfies it, taking every key from a lookup in the registration map rather than from a parameter and validating each claimed plaintext against the stored ciphertext before a debit, with no circuit in that module accepting a caller-supplied key, so no path in the library as shipped reaches the failure.
Consider making the key association explicit at the interface, for example by storing a key identifier alongside each ciphertext and deriving the key internally rather than accepting it from the caller. Consider also documenting that these helpers must never receive a caller-controlled or mutable key where long-term decryptability matters.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read contracts/src/crypto/ElGamal.compact around lines 92-95 and 328-385 to understand the ciphertext representation and homomorphic helpers. Then inspect ConfidentialFungibleToken.compact around lines 600 and 604 to compare consumer key handling. Done should mean the key association or caller constraint is explicit and the substitution risk is addressed.
Written by the indexing model from the issue text.
Assessment
- Domain
- cryptography
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100