OpenZeppelin / OpenZeppelin/compact-contracts

dev: ElGamal (#617) review follow-ups — tests, hardening, docs

Open
#633 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

documentation enhancement feat:crypto
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, asserting secretToScalar / expandRandomness return > 0 and derivePk / encrypt never 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: expandRandomness is the recommended source of encryption randomness r, but no test feeds its output into encrypt. 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 as r).

    added by claude (dev3-midnight-basic-review skill)

Curve structure
  • contracts/src/crypto/ElGamal.compact:138

    🔵 followup: JUBJUB_SUBGROUP_ORDER_MINUS_ONE (and ecNeg just 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 dedicated crypto/JubJub.compact module 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 this expandRandomness ([seed, tag]) are distinguished only by input arity. A per-usage domain constant (e.g. EG-KEY vs EG-RAND) is cheap defense-in-depth if a consumer ever reuses one 32-byte secret as both an ek and a randomness seed.

    added by claude (dev3-midnight-basic-review skill)

Docs
  • contracts/src/crypto/ElGamal.compact:258

    🔵 followup: Worth an integrity & authorization @dev note near the homomorphic ops: ElGamal here is intentionally malleable (that is the homomorphism), so importers must bind ciphertexts via assertDecryptsTo plus 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 outside src/ in this repo). Flag for the docs pass so ElGamal surfaces in the published API reference alongside token / 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 assigned JubjubPoint is 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 @dev prose 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

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.