Skip to content

Upstream: C' is used before it is defined #5

Description

@OR13

Two related holes in Issuance Step One.

C' is used before definition. Step one says only "It computes a commitment." It never says of what, or how. You only learn the commitment is Pedersen from step two's check: "The client then checks Cprime = aprime G + bprime H". This crate assumes C' = a'G + b'H on that basis.

The generator H is undefined. That H is a group element — and it collides notationally with H the hash function from the same paragraph of the draft. Nothing says where it comes from. This matters: if $\log_G H$ is knowable, the commitment is not binding and the opening in finalize proves nothing.

What this crate chose: H = hash_to_group("pedersen-H") under DST OR13_EXP_MOLE/h2g/pedersen-H/v1 — nothing-up-my-sleeve, so no party knows the discrete log.

Why this is filed as help wanted rather than settled: the choice is defensible but it is a guess about intent, not a reading of text. A specification could equally derive H from the Anchor's key, fix it as a named constant, or restructure the commitment entirely. I do not know which the authors mean, and the notational collision suggests the draft text itself needs an editorial pass here.

Draft text: https://github.com/Moderation-of-unLinkable-Endorsements/internet-drafts/blob/main/draft-authors-mole-crypto.md


Update — upstream PR #39 (open, unmerged): the generator half is RESOLVED

PR #39 adds:

We use two generators. G is the generator of the group. H is Hash2Curve("IHAT second generator").

That is the same nothing-up-my-sleeve construction this crate guessed, arrived at independently — only the label differs (ours hashes "pedersen-H" under OR13_EXP_MOLE/h2g/pedersen-H/v1). The concern that motivated the help wanted tag — that log_G H might be knowable and the commitment therefore not binding — is answered.

Once PR #39 merges, aligning the profile is a one-line change to the hash input.

What remains open, and why this issue stays open:

  1. C' is still never defined. Issuance Step One still says only "It computes a commitment." PR #39 does not touch that sentence. The reader still has to infer C' = a'G + b'H from Step Two's check. Now that both generators are defined two paragraphs earlier, writing the equation is nearly free.

  2. The H collision got worse. H is now simultaneously: the hash in e = H(Y, Zhat, T1, T2, C), the second group generator, and adjacent to a SHAKE128 sponge introduced in the same PR. Three things, overlapping notation, one document.

Retitled to reflect that the generator question is settled and only the missing definition remains.


Update — the generator is now the draft's, verbatim

The profile derives the Pedersen second generator as
Hash2Curve("IHAT second generator"), which is the literal definition PR #39 adds.
Previously it hashed our own "pedersen-H" label; the message is now the draft's
string, under our DST (#2), so this half of the issue is closed in the code as well
as upstream.

Still open, and the reason this issue remains: C' is never defined. Issuance
Step One still says only "It computes a commitment", and PR #39 does not touch that
sentence. The profile continues to assume C' = a'G + b'H, inferred from Step Two's
check. With both generators now defined two paragraphs earlier, writing the equation
is nearly free.


Update — resolved, and PR #39 contradicts the reference implementation

ihat-rs defines the Pedersen generator, but not the way PR #39 does.

PR #39 H = Hash2Curve("IHAT second generator") — one global generator
ihat-rs H = H(endorsement_context) — derived per context

ihat-rs's own comment on why:

Deriving H from the context (rather than fixing one global H) binds the context
into C structurally, so it acts as public metadata every party commits under.

It is load-bearing, and its wire-format doc says so: "a mismatch makes the Client's
Pedersen check fail at finalize, because H would differ." crypto::exp_ihat now
derives H from the context, and
tests/exp_ihat_profile.rs::context_mismatch_fails_the_pedersen_check asserts the
failure.

A consequence worth noting: the Anchor must therefore receive the
endorsement_context (it appears in SignatureRequest), because it needs it to
compute C'. That is a deliberate, benign disclosure — the context is public epoch
metadata — but it means "the Anchor learns nothing" is not quite the right framing.
The nullifier remains hidden behind Y' = vY, which is the property that matters.

Still open: C' is still never defined in Issuance Step One ("It computes a
commitment"), and PR #39 does not touch that sentence. Keeping this issue open for
that, and for the contradiction above, which upstream should resolve one way or the
other.

Metadata

Metadata

Assignees

No one assigned

    Labels

    exp-ihatConcerns the experimental IHAT profileguessed-parameterA choice this crate invented because the drafts do not specify ithelp wantedExtra attention is neededsecuritySecurity-relevant

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions