MoLE Protocols
draft-jms-mole-protocols-00
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Authors | Samuel Schlesinger , Dennis Jackson , Thibault Meunier | ||
| Last updated | 2026-07-06 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Stream | Stream state | (No stream defined) | |
| Consensus boilerplate | Unknown | ||
| RFC Editor Note | (None) | ||
| IESG | IESG state | I-D Exists | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-jms-mole-protocols-00
Network Working Group S. Schlesinger
Internet-Draft Google LLC
Intended status: Informational D. Jackson
Expires: 7 January 2027 Mozilla
T. Meunier
Cloudflare
6 July 2026
MoLE Protocols
draft-jms-mole-protocols-00
Abstract
This document defines protocols that instantiate the MoLE
architecture: two endorsement protocols, by which a Client proves to
a Moderator that it holds an Endorsement from a trusted Anchor
without revealing which one, and three credential protocols, by which
a Moderator issues, verifies, and updates per-Client state without
being able to link presentations. It also establishes the registries
that identify these protocols.
About This Document
This note is to be removed before publishing as an RFC.
The latest revision of this draft can be found at https://moderation-
of-unlinkable-endorsements.github.io/internet-drafts/draft-jms-mole-
protocols.html. Status information for this document may be found at
https://datatracker.ietf.org/doc/draft-jms-mole-protocols/.
Source for this draft and an issue tracker can be found at
https://github.com/Moderation-of-unLinkable-Endorsements/internet-
drafts.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Schlesinger, et al. Expires 7 January 2027 [Page 1]
Internet-Draft MoLE Protocols July 2026
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 7 January 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4
3. Common Requirements . . . . . . . . . . . . . . . . . . . . . 4
3.1. Message Types . . . . . . . . . . . . . . . . . . . . . . 4
3.2. Greasing . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3. Challenge Binding . . . . . . . . . . . . . . . . . . . . 5
4. Endorsement Protocols . . . . . . . . . . . . . . . . . . . . 6
4.1. Issuer-Hiding Anonymous Token (IHAT) . . . . . . . . . . 7
4.1.1. Configuration . . . . . . . . . . . . . . . . . . . . 7
4.1.2. Grant . . . . . . . . . . . . . . . . . . . . . . . . 7
4.1.3. Redemption . . . . . . . . . . . . . . . . . . . . . 8
4.2. Longfellow . . . . . . . . . . . . . . . . . . . . . . . 9
4.2.1. Configuration . . . . . . . . . . . . . . . . . . . . 9
4.2.2. Redemption . . . . . . . . . . . . . . . . . . . . . 9
4.2.3. Differences from IHAT . . . . . . . . . . . . . . . . 10
5. Credential Protocols . . . . . . . . . . . . . . . . . . . . 10
5.1. Anonymous Credit Tokens (ACT) . . . . . . . . . . . . . . 12
5.1.1. Configuration . . . . . . . . . . . . . . . . . . . . 12
5.1.2. Redeem & Issue . . . . . . . . . . . . . . . . . . . 12
5.1.3. Presentation and Update . . . . . . . . . . . . . . . 12
5.2. Privacy Pass with a Reverse Flow . . . . . . . . . . . . 13
5.2.1. Redeem & Issue . . . . . . . . . . . . . . . . . . . 13
5.2.2. Presentation and Update . . . . . . . . . . . . . . . 14
5.2.3. Limitations . . . . . . . . . . . . . . . . . . . . . 14
5.3. Budget Privacy Pass . . . . . . . . . . . . . . . . . . . 14
Schlesinger, et al. Expires 7 January 2027 [Page 2]
Internet-Draft MoLE Protocols July 2026
5.3.1. Redeem & Issue . . . . . . . . . . . . . . . . . . . 15
5.3.2. Presentation and Update . . . . . . . . . . . . . . . 15
5.3.3. When to use it . . . . . . . . . . . . . . . . . . . 15
6. Key Rotation and Discovery . . . . . . . . . . . . . . . . . 16
7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 16
8. Security Considerations . . . . . . . . . . . . . . . . . . . 17
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 17
9.1. MoLE Endorsement Types . . . . . . . . . . . . . . . . . 17
9.1.1. IHAT . . . . . . . . . . . . . . . . . . . . . . . . 18
9.1.2. Longfellow . . . . . . . . . . . . . . . . . . . . . 18
9.2. MoLE Credential Types . . . . . . . . . . . . . . . . . . 19
9.2.1. ACT . . . . . . . . . . . . . . . . . . . . . . . . . 19
9.2.2. Privacy Pass Reverse Flow . . . . . . . . . . . . . . 19
9.2.3. Budget Privacy Pass . . . . . . . . . . . . . . . . . 20
9.2.4. Greased Values . . . . . . . . . . . . . . . . . . . 20
9.3. Media Types . . . . . . . . . . . . . . . . . . . . . . . 20
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 20
10.1. Normative References . . . . . . . . . . . . . . . . . . 20
10.2. Informative References . . . . . . . . . . . . . . . . . 22
Appendix A. Example . . . . . . . . . . . . . . . . . . . . . . 22
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 24
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 24
1. Introduction
The MoLE architecture [ARCHITECTURE] defines three roles. Clients
obtain Endorsements from Anchors, redeem them at Moderators in
exchange for Credentials, and present those Credentials to Moderators
to access resources. The architecture states the required properties
of Endorsements and Credentials but does not say how to build them.
This document does.
TODO: the protocols below reflect our current understanding of how
MoLE may work, and showcase agility. They are not final. Some may
be removed, others added.
It defines two endorsement protocols and three credential protocols.
Each is identified by a type value from a registry established in
this document (Section 9). The HTTP carriage of challenges,
redemptions, and presentations is defined in [HTTP-TRANSPORT]. This
document defines the messages themselves and, for the grant flow, the
HTTP exchanges that carry them.
Schlesinger, et al. Expires 7 January 2027 [Page 3]
Internet-Draft MoLE Protocols July 2026
2. Conventions and Definitions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
Protocol messages are described in TLS presentation language
(Section 3 of [TLS13]). This document also uses the optional-value
and variable-size vector conventions (optional<T>, <V>) defined in
[HTTP-TRANSPORT]. All constants are in network byte order.
This document uses the following terms for protocol actions:
Grant: An Anchor gives a Client an Endorsement.
Redeem: A Client spends an Endorsement at a Moderator. Each
Endorsement can be redeemed once.
Issue: A Moderator gives a Client a Credential in return for a
redemption.
Present: A Client shows a Credential to a Moderator. Each
Credential can be presented once. The update replaces it.
Update: The Moderator's adjustment to a presented Credential,
returned in the same exchange.
Finalize: The Client-local step that turns a protocol response into
a stored Endorsement or Credential.
3. Common Requirements
3.1. Message Types
Every MoLE protocol message MUST begin with a uint16 type field:
endorsement_type for messages in the endorsement flow,
credential_type for messages in the credential flow. Values are
assigned in the registries defined in Section 9. A recipient that
does not recognize the type MUST ignore the message. A Client that
receives a challenge with an unknown type simply does not respond to
it.
The value 0x0000 is reserved in both registries and MUST NOT appear
on the wire. Endorsement type 0x0001 means the Moderator establishes
trust in the Client on its own, and no Endorsement is redeemed.
Schlesinger, et al. Expires 7 January 2027 [Page 4]
Internet-Draft MoLE Protocols July 2026
3.2. Greasing
In order to prevent Moderators from becoming incompatible with future
credential types, Clients SHOULD send presentations whose
credential_type is a random value from the reserved greased values
(Section 9.2.4), with some non-trivial probability. The body of a
greased presentation is random bytes.
The greased values follow the pattern 0x?A?A, spread uniformly across
the registry space. Moderators MUST handle them exactly as any other
unknown type and MUST NOT special-case the reserved list: a Moderator
that enumerates greased values defeats their purpose and will still
receive unknown types it did not enumerate.
Additionally, when a credential is not required, Clients SHOULD
randomly choose not to answer a challenge with some non-trivial
probability. This helps ensure that Moderators maintain their
behavior for handling Clients without credentials, rather than
relying on a presentation always being present.
3.3. Challenge Binding
Every redemption and presentation is bound to the challenge that
triggered it. The binding value is:
challenge_digest = SHA-256(challenge)
where challenge is the challenge structure in its binary form: the
octets of its TLS-presentation encoding. When a challenge arrives
base64url encoded in an HTTP header ([HTTP-TRANSPORT]), the Client
first decodes it, then hashes the resulting octets. The digest is
never computed over the ASCII form. SHA-256 is defined in [SHA2].
Each protocol in this document states where challenge_digest enters
its messages. A verifier MUST reject a redemption or presentation
bound to a different challenge. This prevents a message captured in
one context from being replayed in another.
In the endorsement protocols, the presentation is a proof generated
at redemption time, and challenge_digest is an input to that proof:
it enters the proof transcript in IHAT and the public inputs in
Longfellow. A proof produced for one challenge does not verify under
another. Challenge binding is separate from the nullifier. The
nullifier is a PRF output over a credential-bound secret and the
epoch; it limits a Client to one presentation per epoch.
Schlesinger, et al. Expires 7 January 2027 [Page 5]
Internet-Draft MoLE Protocols July 2026
4. Endorsement Protocols
An endorsement protocol has two parts. First, the Client runs one or
more request/response exchanges with an Anchor and finalizes the
result into an Endorsement. This is the grant. Second, the Client
redeems the Endorsement at a Moderator, proving it came from an
Anchor in the Moderator's accepted set without revealing which one.
Redemption happens inside the Redeem & Issue flow (Section 5).
+--------+ +--------+
| Client | | Anchor |
+---+----+ +---+----+
| |
+--- EndorsementRequest ----->| \
|<-- EndorsementResponse -----+ | one or more
| ... | / exchanges
Finalize |
|
| +-----------+
| | Moderator |
| +-----+-----+
| |
|<-------- Challenge ----------+
+------- Presentation -------->|
| |
Figure 1: Endorsement grant and redemption
Exchanges with the Anchor are HTTP POST requests. The request body
has media type application/mole-endorsement-request and contains an
EndorsementRequest. The response body has media type application/
mole-endorsement-response and contains an EndorsementResponse. The
endorsement type determines how many exchanges are needed and what
the body field contains at each step.
struct {
uint16 endorsement_type;
opaque body<V>;
} EndorsementRequest;
struct {
uint16 endorsement_type;
opaque body<V>;
} EndorsementResponse;
Every endorsement protocol defines two structures. Challenge is the
type-specific content of the Moderator's challenge, carried in its
challenge field ([HTTP-TRANSPORT]). Its content, including any
Schlesinger, et al. Expires 7 January 2027 [Page 6]
Internet-Draft MoLE Protocols July 2026
Anchor set, is opaque at the transport level. Each endorsement type
refines it, for example into a list of accepted Anchor keys.
Presentation is the protocol's final output: the message a Client
sends to redeem the Endorsement, carried in the
endorsement_presentation field of a CredentialRequest (Section 5).
4.1. Issuer-Hiding Anonymous Token (IHAT)
Endorsement type: 0x0002.
TODO: IHAT is a placeholder name. Once we have a first version for
[CRYPTO], we would align.
IHAT is a pairing-free, issuer-hiding endorsement scheme over P-256.
The Anchor blindly signs a Client-chosen nullifier. The Client later
proves, with a 1-of-n OR proof, that its Endorsement verifies under
one of the Anchor keys the Moderator accepts. The cryptographic
operations, and the contents of every message body, are defined in
[CRYPTO]. Until that document is complete, bodies in this section
are opaque byte strings produced and consumed by the functions named
below.
The following primitive types are used in this section:
opaque Scalar[32]; /* big-endian integer mod the group order */
opaque Point[33]; /* P-256 point, SEC1 compressed */
4.1.1. Configuration
The Client needs, from Anchor configuration (Section 6):
Anchor Public Key pkA, a Point, as generated in [CRYPTO].
Endorsement Context an opaque byte string identifying the current
epoch. Endorsements are valid for one epoch, see Section 6.
4.1.2. Grant
The grant takes two exchanges with the Anchor.
In the first exchange, the Client runs Prepare(pkA,
endorsement_context) ([CRYPTO]), keeps the returned client state, and
sends the resulting request as the body of an EndorsementRequest.
The Anchor runs Sign(skA, body), keeps its own state for the second
exchange, and returns the result in an EndorsementResponse.
Schlesinger, et al. Expires 7 January 2027 [Page 7]
Internet-Draft MoLE Protocols July 2026
In the second exchange, the Client runs RequestProof(state, body) and
sends the result. The Anchor runs Prove(state, body) and returns the
result.
The Client finalizes with Finalize(state, body), which verifies the
Anchor's commitment opening and produces an Endorsement. The
Endorsement contains a nullifier nf and the endorsement_context it
was granted under. If finalization fails, the Client MUST discard
the session. It MUST NOT retry with the same state.
The Anchor learns neither nf nor the final Endorsement, so it cannot
recognize the Endorsement when it is later redeemed.
TODO: the two exchanges must be correlated, since the Anchor holds
state between them. Either [CRYPTO] adds a session identifier to its
messages or this document mandates connection reuse.
4.1.3. Redemption
The Moderator's challenge ([HTTP-TRANSPORT]) carries the set of
Anchor keys it accepts:
struct {
Point keys<V>; /* accepted Anchor public keys */
} Challenge;
The order of keys is significant: OR-proof branches are matched to
keys by position. Moderators MUST present the set in the order
published in their configuration (Section 6).
The Client runs Present(endorsement, keys, challenge_digest)
([CRYPTO]), with challenge_digest computed as in Section 3.3, and
sends the result:
struct {
opaque bytes<V>; /* output of Present */
} Presentation;
Present MUST bind challenge_digest into the proof transcript, and
Verify MUST fail when given any other challenge_digest. This is a
requirement on [CRYPTO].
The Moderator runs Verify(presentation, keys, challenge_digest)
([CRYPTO]), which exposes nf and endorsement_context, and
additionally checks that:
1. endorsement_context names the current epoch, and
Schlesinger, et al. Expires 7 January 2027 [Page 8]
Internet-Draft MoLE Protocols July 2026
2. nf has not been seen before in this epoch.
If all checks pass, the Moderator records nf and proceeds with
credential issuance. The Endorsement is spent: redeeming it again
MUST fail check 2.
4.2. Longfellow
Endorsement type: 0x0003.
Where IHAT requires Anchors to run new cryptography, this protocol
preserves backward compatibility with credentials Clients may hold,
such as mdocs. The Client proves in zero knowledge, using the scheme
of [LONGFELLOW], that it holds a valid credential from one of an
accepted set of issuers, without revealing which issuer or any
credential attribute. An experimental circuit is described in
[HIDDEN-ISSUER-CIRCUIT].
There is no grant exchange in this protocol. The Client obtains its
credential from the Anchor out of band, through whatever legacy
issuance that credential uses. The circuit is likewise distributed
out of band and identified by its hash.
4.2.1. Configuration
The Client needs, from Moderator configuration (Section 6):
Circuit Identifier circuit_id, the SHA-256 hash of the circuit both
parties use.
Accepted Issuer Set the credential-issuer certificates the Moderator
accepts, in a fixed published order.
Epoch the validity window redemptions must fall in.
4.2.2. Redemption
This protocol needs no type-specific challenge content: Challenge is
empty. The accepted issuer set, circuit, and epoch come from
configuration.
The Client evaluates the circuit over its credential to produce a
proof and a nullifier. The nullifier is derived, inside the circuit,
from a credential-bound secret and the current epoch, so one
credential yields exactly one valid nullifier per epoch.
Schlesinger, et al. Expires 7 January 2027 [Page 9]
Internet-Draft MoLE Protocols July 2026
struct {
opaque circuit_id[32];
opaque nullifier<V>;
opaque proof<V>;
} Presentation;
The public inputs to the proof are the accepted issuer set, the
epoch, the nullifier, and challenge_digest (Section 3.3). A proof is
valid only for its exact public inputs, so a presentation bound to a
different challenge fails verification. The Moderator verifies the
proof using the verifier of [LONGFELLOW], then applies the same epoch
and nullifier-freshness checks as IHAT redemption.
4.2.3. Differences from IHAT
While Longfellow does not require the Anchor to actively participate
in MoLE, it is preferred to guarantee and control scarcity.
Otherwise, the number of Endorsements that can be obtained by a given
Client is unbounded. Scarcity comes both from the participation of
the Anchor, and from the one-nullifier-per-epoch rule. Deployments
without an aware Anchor remain possible, but lose Anchor-controlled
scarcity.
The required circuit properties, in particular sound nullifier
derivation from a credential-bound secret, are stated here as
requirements on the circuit. [HIDDEN-ISSUER-CIRCUIT] is one
candidate that could be refined.
5. Credential Protocols
A credential protocol has two parts: Redeem & Issue, in which the
Client redeems an Endorsement and receives a Credential from the
Moderator, and presentation, in which the Client shows the Credential
and receives an update. Presentation and update happen in one
exchange, following [REVERSE-FLOW].
Schlesinger, et al. Expires 7 January 2027 [Page 10]
Internet-Draft MoLE Protocols July 2026
+--------+ +-----------+
| Client | | Moderator |
+---+----+ +-----+-----+
| |
|<------------ Challenge ----------------+
+-- Redemption + CredentialRequest ----->|
|<-------- CredentialResponse -----------+
Finalize |
| |
... |
| |
|<------------ Challenge ----------------+
+--- Presentation + UpdateRequest ------>|
|<------------ UpdateResponse -----------+
Finalize |
| |
Figure 2: Redeem & Issue, then presentation and update
Both parts ride on HTTP requests to the Moderator, since each is an
authorization. Redeem & Issue carries a CredentialRequest in the
Authorization header and receives the CredentialResponse in the Mole-
Credential response header. Presentation uses the same
authentication scheme, with the update returned in the same Mole-
Credential header under its update parameter. Carriage is defined in
[HTTP-TRANSPORT].
struct {
uint16 endorsement_type;
opaque endorsement_presentation<V>;
uint16 credential_type;
opaque issuance_request<V>;
} CredentialRequest;
struct {
uint16 credential_type;
opaque issuance_response<V>;
} CredentialResponse;
The endorsement_presentation field carries the Presentation structure
of the named endorsement type. With endorsement_type 0x0001 it is
empty, and the Moderator relies on its own trust establishment
(Section 3).
Every credential protocol defines five structures. Challenge is the
type-specific content of the Moderator's challenge, carried in its
challenge field ([HTTP-TRANSPORT]). IssuanceRequest and
IssuanceResponse fill the issuance_request and issuance_response
Schlesinger, et al. Expires 7 January 2027 [Page 11]
Internet-Draft MoLE Protocols July 2026
fields above. PresentationAndUpdate is carried in the
presentation_and_update field of a CredentialPresentation
([HTTP-TRANSPORT]). Update is returned in the update parameter of
the Mole-Credential header.
5.1. Anonymous Credit Tokens (ACT)
Credential type: 0x0001.
An ACT credential [ACT] is an anonymous state machine: the Moderator
can test a predicate against the Credential's hidden state and update
that state, without learning the state or linking presentations.
This is the credential protocol that provides every property required
by [ARCHITECTURE], including that updates provably apply to the
credential that was presented.
5.1.1. Configuration
The Moderator publishes its ACT public key and the predicate
description (Section 6).
5.1.2. Redeem & Issue
struct {
uint8 truncated_key_id;
opaque request<V>;
} IssuanceRequest;
struct {
opaque response<V>;
} IssuanceResponse;
The request and response fields are defined in [ACT]. The Client
finalizes the response into a Credential with an initial state chosen
by the Moderator's policy.
5.1.3. Presentation and Update
The Client presents the Credential against the challenged predicate,
spending it, and in the same message requests the replacement that
carries the updated state.
Schlesinger, et al. Expires 7 January 2027 [Page 12]
Internet-Draft MoLE Protocols July 2026
struct {
opaque challenge_digest[32];
opaque key_id[32];
opaque spend_proof<V>;
} PresentationAndUpdate;
struct {
opaque refund<V>;
} Update;
The spend_proof and refund fields are defined in [ACT]. The
Moderator verifies the spend proof and learns whether the
Credential's hidden state satisfies the challenged predicate. For
range-style predicates, this necessarily reveals the public bound
being tested, but not the hidden state value. The Client finalizes
the refund into its new Credential. ACT guarantees the refund
applies to the state that was presented.
TODO: the exact mapping between the spend and refund operations of
[ACT] and MoLE's predicate and update is not settled. In particular,
Challenge for this type must express the predicate and the charged
amount, and its contents are not yet defined.
The Challenge for this type therefore needs to identify the
predicate, including any public bound, and the update to apply.
5.2. Privacy Pass with a Reverse Flow
Credential type: 0x0002.
The Credential is a single privately verifiable Privacy Pass token.
Any token type registered in the Privacy Pass Token Types registry
([PRIVACYPASS-PROTOCOLS]) can be used. The Moderator's configuration
names one. The Credential encodes one bit: the Client either holds a
valid token or it does not. Presentation consumes the token. The
update, if granted, is a fresh token issued through the reverse flow
of [REVERSE-FLOW], with the Moderator acting as both initial and
reverse issuer.
The presented and reissued token MUST use the same token type and the
same Moderator public key. Anything else partitions Clients and
leaks state.
5.2.1. Redeem & Issue
IssuanceRequest is a TokenRequest and IssuanceResponse is a
TokenResponse, both as defined for the configured token type in
[PRIVACYPASS-PROTOCOLS]. The finalized token is the Credential.
Schlesinger, et al. Expires 7 January 2027 [Page 13]
Internet-Draft MoLE Protocols July 2026
5.2.2. Presentation and Update
Challenge is empty for this type. The challenge octets, and
therefore challenge_digest, are constant for a given Moderator
configuration.
struct {
opaque token<V>;
opaque token_request<V>; /* TokenRequest */
} PresentationAndUpdate;
struct {
opaque token_response<V>; /* TokenResponse */
} Update;
The token field carries a Token as defined in [PRIVACYPASS-AUTH].
Its challenge_digest field is fixed when the token is issued, one
exchange before it is presented, and MUST equal the Moderator's
constant challenge_digest (Section 3.3). This binds the token to the
Moderator, not to the exchange that presents it. Anti-replay
therefore does not come from challenge binding: it comes from the
token being single-use. The Moderator MUST reject a token whose
nonce it has already seen.
If the Moderator's policy allows continued access, it returns an
Update. If not, it returns an empty update and the Client is out of
credentials.
5.2.3. Limitations
TODO: define a device binding mechanism, issuing tokens bound to a
Client key so that presentation requires proof of possession. This
would restore the binding between update and presented credential.
Open problem.
5.3. Budget Privacy Pass
Credential type: 0x0003.
The Credential is a balance, represented as Privacy Pass tokens drawn
from N issuers operated by the same Moderator, where issuer i
denominates 2^i units. Tokens are issued in batches using
[PRIVACYPASS-BATCHED], and any token type registered in the Privacy
Pass Token Types registry that supports batched issuance can be used.
The Client presents whatever tokens it wants, and the sum of their
denominations is the amount spent. The Moderator returns change and
any policy adjustment as freshly issued tokens through the reverse
flow, summing to the intended new balance.
Schlesinger, et al. Expires 7 January 2027 [Page 14]
Internet-Draft MoLE Protocols July 2026
A presentation reveals that the Client can spend the challenged
amount. If the protocol presents exactly one token for that amount,
and balance management remains Client-local, this is the same
disclosure as an ACT predicate over that amount: the Moderator learns
the predicate result, not the Client's remaining balance.
Deployments that allow multiple tokens, variable denominations, or
observable change shapes need padding or another mitigation.
5.3.1. Redeem & Issue
IssuanceRequest is a BatchTokenRequest and IssuanceResponse is a
BatchTokenResponse ([PRIVACYPASS-BATCHED]), for tokens summing to the
initial balance set by the Moderator's policy.
5.3.2. Presentation and Update
The challenge indicates the amount to spend:
struct {
uint64 amount;
} Challenge;
The amount is an indicator, not a per-Client value. A Moderator MUST
use the same amount for every Client under a policy: varying it
partitions Clients. Deployments MAY publish the amount out of band
instead (Section 6), in which case the field repeats the published
value.
struct {
opaque tokens<V>; /* one or more Tokens */
opaque token_request<V>; /* BatchTokenRequest */
} PresentationAndUpdate;
struct {
opaque token_response<V>; /* BatchTokenResponse */
} Update;
Challenge binding comes from each Token structure, as in Section 5.2.
The Client MAY at any time exchange several small tokens for larger
ones at the Moderator's refund endpoint.
5.3.3. When to use it
Balances with many possible values need many tokens and padding
traffic to avoid leaking through request counts. If the state fits
an ACT credential, Section 5.1 is simpler and leaks less. This
protocol fits deployments that already run Privacy Pass issuers and
need only coarse balances.
Schlesinger, et al. Expires 7 January 2027 [Page 15]
Internet-Draft MoLE Protocols July 2026
6. Key Rotation and Discovery
TODO.
Anchors and Moderators each publish a configuration that Clients
fetch before running any flow. It contains their endpoints,
supported endorsement and credential types, public keys, and, for
Moderators, the accepted Anchor set for each policy. The order of
the accepted set is normative: IHAT OR proofs and Longfellow issuer
sets match elements by position, so all parties must see the same
order.
Endorsements live in epochs. The endorsement_context of IHAT and the
epoch of Longfellow name the epoch an Endorsement is granted in,
which is also the window the Moderator's nullifier store covers.
Epoch length is a privacy parameter: short epochs shrink the double-
spend store but partition Clients into smaller anonymity sets. See
[ARCHITECTURE] for the consistency requirements on configuration. A
Moderator that shows different configurations to different Clients
can partition them.
Open questions:
1. Format: a Privacy Pass style directory, or JWKS. Reusing JWKS
matters if deployments want existing key-management tooling,
despite feelings.
2. How and when Anchor and Moderator keys rotate.
3. Whether messages carry a key identifier, such as a truncated key
identifier as in Privacy Pass token requests, or a JWK
Thumbprint.
4. How Clients validate Moderator configuration without revealing
themselves, and how consistency is audited.
7. Privacy Considerations
TODO. The list to cover:
1. Anchor set verification: the Client must be able to verify the
number of Anchors in an accepted set, and that these Anchors are
real rather than fabricated by the Moderator. A set padded with
fake Anchors shrinks the effective anonymity set to the Clients
of the real ones.
2. Configuration partitioning: accepted-set contents and order as a
fingerprinting vector (with [ARCHITECTURE]).
Schlesinger, et al. Expires 7 January 2027 [Page 16]
Internet-Draft MoLE Protocols July 2026
3. Epoch width versus anonymity set size.
8. Security Considerations
All exchanges defined in this document and [HTTP-TRANSPORT] MUST be
carried over HTTPS.
TODO. The list to cover:
1. Nullifier store sizing and eviction: the store is per epoch, and
a Moderator that evicts early re-admits spent Endorsements.
2. Anchor key compromise: an attacker with an Anchor key in an
accepted set can mint Endorsements freely. Blast radius and
rotation response.
3. Reverse-flow update transfer: the two-credential attack of
Section 5.2, and why single-credential enforcement cannot be
verified.
4. Timing and error side channels during verification, especially
distinguishing "bad proof" from "spent nullifier".
9. IANA Considerations
This document sketches two candidate registries under a future "MoLE"
group. The values below are candidate values for discussion in this
-00 draft and are not stable assignments.
A registration MUST define the per-type structures its flow requires:
Challenge and Presentation for endorsement types (Section 4), and
Challenge, IssuanceRequest, IssuanceResponse, PresentationAndUpdate,
and Update for credential types (Section 5). Every message begins
with the registered uint16 type (Section 3). A registration MUST
also state how redemption or presentation binds challenge_digest
(Section 3.3).
9.1. MoLE Endorsement Types
+=================+===============================+===============+
| Value | Name | Reference |
+=================+===============================+===============+
| 0x0000 | Reserved | this document |
+-----------------+-------------------------------+---------------+
| 0x0001 | Moderator trust establishment | Section 3 |
+-----------------+-------------------------------+---------------+
| 0x0002 | IHAT | Section 4.1 |
+-----------------+-------------------------------+---------------+
Schlesinger, et al. Expires 7 January 2027 [Page 17]
Internet-Draft MoLE Protocols July 2026
| 0x0003 | Longfellow | Section 4.2 |
+-----------------+-------------------------------+---------------+
| 0xFF00 - 0xFFFF | Reserved for testing | this document |
+-----------------+-------------------------------+---------------+
Table 1: Candidate MoLE Endorsement Type Values
The registration template contains:
* Value: The two-byte endorsement type.
* Name: A short name for the protocol.
* Exchanges: The number of request/response exchanges with the
Anchor, or "none" if the grant is out of band.
* Publicly Verifiable: Whether the Endorsement can be verified
without Anchor secret key material.
* Reference: Where the protocol is defined.
The following initial registrations are candidates only.
9.1.1. IHAT
* Value: 0x0002
* Name: IHAT
* Exchanges: 2
* Publicly Verifiable: Yes
* Reference: Section 4.1
9.1.2. Longfellow
* Value: 0x0003
* Name: Longfellow
* Exchanges: none (out of band)
* Publicly Verifiable: Yes
* Reference: Section 4.2
Schlesinger, et al. Expires 7 January 2027 [Page 18]
Internet-Draft MoLE Protocols July 2026
9.2. MoLE Credential Types
+=================+===========================+===============+
| Value | Name | Reference |
+=================+===========================+===============+
| 0x0000 | Reserved | this document |
+-----------------+---------------------------+---------------+
| 0x0001 | ACT | Section 5.1 |
+-----------------+---------------------------+---------------+
| 0x0002 | Privacy Pass Reverse Flow | Section 5.2 |
+-----------------+---------------------------+---------------+
| 0x0003 | Budget Privacy Pass | Section 5.3 |
+-----------------+---------------------------+---------------+
| 0x0A0A, 0x1A1A, | Reserved for greasing | Section 3.2 |
| ..., 0xFAFA | | |
+-----------------+---------------------------+---------------+
| 0xFF00 - 0xFFFF | Reserved for testing | this document |
+-----------------+---------------------------+---------------+
Table 2: Candidate MoLE Credential Type Values
The registration template contains:
* Value: The two-byte credential type.
* Name: A short name for the protocol.
* Bound Update: Whether updates provably apply to the presented
credential.
* Reference: Where the protocol is defined.
9.2.1. ACT
* Value: 0x0001
* Name: ACT
* Bound Update: Yes
* Reference: Section 5.1
9.2.2. Privacy Pass Reverse Flow
* Value: 0x0002
* Name: Privacy Pass Reverse Flow
Schlesinger, et al. Expires 7 January 2027 [Page 19]
Internet-Draft MoLE Protocols July 2026
* Bound Update: No
* Reference: Section 5.2
9.2.3. Budget Privacy Pass
* Value: 0x0003
* Name: Budget Privacy Pass
* Bound Update: No
* Reference: Section 5.3
9.2.4. Greased Values
* Value: 0x0A0A, 0x1A1A, 0x2A2A, 0x3A3A, 0x4A4A, 0x5A5A, 0x6A6A,
0x7A7A, 0x8A8A, 0x9A9A, 0xAAAA, 0xBABA, 0xCACA, 0xDADA, 0xEAEA,
0xFAFA
* Name: RESERVED
* Bound Update: N/A
* Reference: Section 3.2
These values MUST NOT be assigned. Message bodies carrying them
contain random bytes (Section 3.2).
9.3. Media Types
+=======================================+===========+
| Media Type | Reference |
+=======================================+===========+
| application/mole-endorsement-request | Section 4 |
+---------------------------------------+-----------+
| application/mole-endorsement-response | Section 4 |
+---------------------------------------+-----------+
Table 3: MoLE Media Types
TODO: full registration templates, following the Privacy Pass
template.
10. References
10.1. Normative References
Schlesinger, et al. Expires 7 January 2027 [Page 20]
Internet-Draft MoLE Protocols July 2026
[ACT] Schlesinger, S. and J. Katz, "Anonymous Credit Tokens",
Work in Progress, Internet-Draft, draft-schlesinger-cfrg-
act-01, 13 February 2026,
<https://datatracker.ietf.org/doc/html/draft-schlesinger-
cfrg-act-01>.
[ARCHITECTURE]
Schlesinger, S., Jackson, D., and T. Meunier, "Moderation
of unLinkable Endorsements (MoLE) Architecture", Work in
Progress, Internet-Draft, draft-jms-mole-architecture-00,
6 July 2026, <https://datatracker.ietf.org/doc/html/draft-
jms-mole-architecture-00>.
[CRYPTO] "MoLE Cryptography", n.d., <https://moderation-of-
unlinkable-endorsements.github.io/internet-drafts/draft-
authors-mole-crypto.html>.
[HTTP-TRANSPORT]
Schlesinger, S., Jackson, D., and T. Meunier, "MoLE HTTP
Transport", Work in Progress, Internet-Draft, draft-jms-
mole-http-transport-00, 6 July 2026,
<https://datatracker.ietf.org/doc/html/draft-jms-mole-
http-transport-00>.
[LONGFELLOW]
Frigo, M. and A. shelat, "The Longfellow Zero-knowledge
Scheme", Work in Progress, Internet-Draft, draft-google-
cfrg-libzk-01, 2 September 2025,
<https://datatracker.ietf.org/doc/html/draft-google-cfrg-
libzk-01>.
[PRIVACYPASS-AUTH]
Pauly, T., Valdez, S., and C. A. Wood, "The Privacy Pass
HTTP Authentication Scheme", RFC 9577,
DOI 10.17487/RFC9577, June 2024,
<https://www.rfc-editor.org/rfc/rfc9577>.
[PRIVACYPASS-BATCHED]
Robert, R., Wood, C. A., and T. Meunier, "Batched Token
Issuance Protocol", Work in Progress, Internet-Draft,
draft-ietf-privacypass-batched-tokens-08, 4 May 2026,
<https://datatracker.ietf.org/doc/html/draft-ietf-
privacypass-batched-tokens-08>.
Schlesinger, et al. Expires 7 January 2027 [Page 21]
Internet-Draft MoLE Protocols July 2026
[PRIVACYPASS-PROTOCOLS]
Celi, S., Davidson, A., Valdez, S., and C. A. Wood,
"Privacy Pass Issuance Protocols", RFC 9578,
DOI 10.17487/RFC9578, June 2024,
<https://www.rfc-editor.org/rfc/rfc9578>.
[REVERSE-FLOW]
Meunier, T., "Privacy Pass Reverse Flow", Work in
Progress, Internet-Draft, draft-meunier-privacypass-
reverse-flow-06, 6 July 2026,
<https://datatracker.ietf.org/doc/html/draft-meunier-
privacypass-reverse-flow-06>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.
[SHA2] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms
(SHA and SHA-based HMAC and HKDF)", RFC 6234,
DOI 10.17487/RFC6234, May 2011,
<https://www.rfc-editor.org/rfc/rfc6234>.
[TLS13] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/rfc/rfc8446>.
10.2. Informative References
[HIDDEN-ISSUER-CIRCUIT]
"Hidden issuer circuit for longfellow-zk", n.d.,
<https://github.com/thibmeu/longfellow-zk/blob/hidden-
issuer-poc/lib/circuits/mdoc/HIDDEN_ISSUER.md>.
Appendix A. Example
A Client requests a resource protected by a Moderator that uses
credential type 0x0002 (Privacy Pass Reverse Flow) and accepts
endorsement type 0x0002 (IHAT).
Schlesinger, et al. Expires 7 January 2027 [Page 22]
Internet-Draft MoLE Protocols July 2026
+--------+ +--------+ +-----------+
| Client | | Anchor | | Moderator |
+---+----+ +---+----+ +-----+-----+
| | |
+------------------|---- request --->|
|<-----------------|--- challenge ---+
+--- exchange 1 -->| |
|<-- response 1 ---+ |
+--- exchange 2 -->| |
|<-- response 2 ---+ |
Finalize | |
+------------------|---- redeem ---->|
|<-----------------|---- credential -+
Finalize | |
+------------------|---- present --->|
|<-----------------|-- ok + update --+
| | |
Figure 3: Complete exchange
The Moderator challenges the Client:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Mole challenge="<credential-challenge>",
realm="moderator"
The Client holds no Credential for this Moderator, so it first
obtains an Endorsement. It runs the two IHAT exchanges against the
Anchor:
POST /mole/endorse HTTP/1.1
Host: anchor.example
Content-Type: application/mole-endorsement-request
EndorsementRequest { 0x0002, Prepare(...) }
The Anchor answers each POST with an application/mole-endorsement-
response body, and the Client finalizes the Endorsement.
The Client then runs Redeem & Issue. It repeats its request, this
time carrying a CredentialRequest that redeems the Endorsement bound
to the Moderator's challenge together with a Privacy Pass
TokenRequest:
GET /resource HTTP/1.1
Host: moderator.example
Authorization: Mole credential-request="<credential-request>"
Schlesinger, et al. Expires 7 January 2027 [Page 23]
Internet-Draft MoLE Protocols July 2026
The Moderator verifies the redemption, records its nullifier, and
returns a CredentialResponse carrying a TokenResponse in the Mole-
Credential header, alongside its unchanged challenge. The Client
finalizes it into a token and answers the challenge:
GET /resource HTTP/1.1
Host: moderator.example
Authorization: Mole presentation="<credential-presentation>"
The Moderator verifies the presentation and serves the resource. Its
response carries a Mole-Credential header whose update parameter
holds a fresh token, or an absent update if it chose to consume the
Credential.
Acknowledgments
TODO acknowledge.
Authors' Addresses
Samuel Schlesinger
Google LLC
Email: sgschlesinger@gmail.com
Dennis Jackson
Mozilla
Email: ietf@dennis-jackson.uk
Thibault Meunier
Cloudflare
Email: ot-ietf@thibault.uk
Schlesinger, et al. Expires 7 January 2027 [Page 24]