OpenZeppelin / OpenZeppelin/compact-contracts

N-01: Homomorphic Helpers Cannot Verify That a Ciphertext Was Encrypted Under the Supplied Key

Open
#806 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-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

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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.