OpenZeppelin / OpenZeppelin/compact-contracts
dev: ElGamal (#617) review follow-ups — tests, hardening, docs
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 55
- Forks
- 29
- Avg merge
- 5d 7h
- Merged PRs (30d)
- 25
Description
Non-blocking follow-ups from the basic review of #617 (ElGamal module). None block the PR.
Each item below is the verbatim text of its inline review comment on #617, with a link to that comment.
Tests
-
contracts/src/crypto/test/ElGamal.test.ts:44🔵 followup: The hash-to-scalar validity property that justifies
degradeToTransient(that it always yields a valid Jubjub scalar) is only exercised on EK_A / EK_B here. Add a property / fuzz pass over many random 32-byte secrets and(seed, tag)pairs, assertingsecretToScalar/expandRandomnessreturn> 0andderivePk/encryptnever throw. The fault mode is simulator-reproducible, so the test is cheap.added by claude (dev3-midnight-basic-review skill)
-
contracts/src/crypto/test/ElGamal.test.ts:79🔵 followup:
expandRandomnessis the recommended source of encryption randomnessr, but no test feeds its output intoencrypt. Add one round-trip —r = expandRandomness(seed, tag)→encrypt(pk, v, r)→assertDecryptsTo— to cover the recommended path end-to-end (and confirm a ~248-bit Field works asr).added by claude (dev3-midnight-basic-review skill)
Curve structure
-
contracts/src/crypto/ElGamal.compact:138🔵 followup:
JUBJUB_SUBGROUP_ORDER_MINUS_ONE(andecNegjust below) are generic Jubjub curve primitives, not ElGamal-specific. The subgroup-order constant and point negation will be wanted by any module doing embedded-curve arithmetic. Consider extracting them into a dedicatedcrypto/JubJub.compactmodule and importing it here, so the curve layer is reusable and ElGamal stays focused on the encryption scheme.added by claude (dev3-midnight-basic-review skill)
Hardening
-
contracts/src/crypto/ElGamal.compact:121🔵 followup:
secretToScalar([secret]) and thisexpandRandomness([seed, tag]) are distinguished only by input arity. A per-usage domain constant (e.g.EG-KEYvsEG-RAND) is cheap defense-in-depth if a consumer ever reuses one 32-byte secret as both anekand a randomness seed.added by claude (dev3-midnight-basic-review skill)
Docs
-
contracts/src/crypto/ElGamal.compact:258🔵 followup: Worth an integrity & authorization
@devnote near the homomorphic ops: ElGamal here is intentionally malleable (that is the homomorphism), so importers must bind ciphertexts viaassertDecryptsToplus their own nullifiers / commitments and must not treat a ciphertext as authenticated or non-replayable. Implicit today, stated nowhere.added by claude (dev3-midnight-basic-review skill)
-
contracts/src/crypto/ElGamal.compact:67🔵 followup: The new
crypto/family ships no API doc / README entry (module docs live outsidesrc/in this repo). Flag for the docs pass so ElGamal surfaces in the published API reference alongsidetoken/access/ etc.added by claude (dev3-midnight-basic-review skill)
Open questions
-
contracts/src/crypto/ElGamal.compact:156❔ question: This identity (
ecNeg(P) = (ℓ-1)·P = -P) holds only for prime-order-subgroup points, which rests on the module's Subgroup membership note: every assignedJubjubPointis cofactor-cleared into the subgroup. Is that confirmed with the compactc / ledger team, or inferred from observed behaviour? Since compactc and midnight-ledger are unaudited, it is the most load-bearing assumption in the module. If it is an assumption rather than a guarantee, consider promoting it from@devprose to a named trust assumption.added by claude (dev3-midnight-basic-review skill)
-
contracts/src/crypto/ElGamal.compact:227❔ question (non-blocking): Why
Uint<128>for the lifted plaintext? Off-chain recovery is a discrete-log search (practically ~2^32–2^48), so the type advertises a far larger safe range than actually exists. Intentional (caller caps it), or worth narrowing the type / documenting a recommended max here?added by claude (dev3-midnight-basic-review skill)
Source: basic review of #617.
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
Start with contracts/src/crypto/test/ElGamal.test.ts and contracts/src/crypto/ElGamal.compact, reviewing each linked follow-up in order. Add the requested fuzz and round-trip coverage, assess the JubJub extraction and domain separation, update security and API documentation, and resolve the subgroup and plaintext-range questions with the compactc/ledger assumptions made explicit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cryptography, documentation, security, testing-qa
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100