For the complete documentation index, see llms.txt.
aztec-nr - noir_aztec::messages::delivery::handshake

Function protect_from_forgery

pub fn protect_from_forgery(
    secret: EmbeddedCurvePoint,
    eph_pk: EmbeddedCurvePoint,
    recipient_point: EmbeddedCurvePoint,
) -> EmbeddedCurvePoint

Protects a handshake's shared secret from recipient forgery.

The handshake's ECDH shared secret is symmetric: S = eph_sk * recipient_pub, where (eph_sk, eph_pk) is the sender's ephemeral key pair, also equals recipient_priv * eph_pk. The recipient recomputing S this way is normal: it is how they derive the handshake's tags when scanning. The attack is minting a second handshake with the same secret: the ephemeral key is unconstrained, so a malicious recipient can register its own handshake crafted to land on S again, with a different sender-only secret, and emit logs under the honest handshake's constrained-delivery tag. That breaks the invariant that a constrained-delivery log sequence is tied to a single sender: by colliding on the tag it blocks the honest sender, who can no longer emit the next note in their sequence.

The protection multiplies S by the scalar k = hash(eph_pk, recipient_point): a forgery must announce a different eph_pk, so the protected secrets diverge. The result is still a point and silos like S.

The recipient point must be part of k: were k independent of it, an attacker choosing the fake recipient point as a multiple of the honest protected secret could solve for the multiplier that makes the forged secret land exactly on it.

Concretely, on the sender's side: S = eph_sk * recipient_point S' = protect_from_forgery(S, eph_pk, recipient_point) = k * S

See forgery_protected_eph_pk for how that arrives at the same S'.