Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

1. Abstract

This spec establishes the default cryptographic primitives used throughout the World ID Protocol (the “Protocol”) such as the default elliptic curve, field, signature scheme and hashing. It includes particularly important constraints and validations which are security-critical.

2. Motivation

The Protocol is heavily reliant on different cryptographic primitives to uphold privacy and security. The correct definition and implementation of such primitives is essential for the Protocol operation. Furthermore, the spec documentation permits multiple implementations to exist in an interoperable way.

3. Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

3.1 Field

Unless otherwise noted, all circuits MUST be arithmetised over $F_q$, the scalar field of BN254, which is also the base field of BabyJubJub. All arithmetic MUST be done over $F_q$, except where a scalar of the BabyJubJub group is required, in which case arithmetic MUST be done over $F_r$, BabyJubJub’s own scalar field.

  • $F_q$ (Fq) is the prime field with modulus

    $q = 21888242871839275222246405745257275088548364400416034343698204186575808495617$

  • $F_r$ (Fr) is the prime field with modulus $r$, the order of BabyJubJub’s large prime-order subgroup (see Curve):

    $r = 2736030358979909402780800718157159386076813972158567259200215660948447373041$

Throughout the Protocol and this spec, the arkworks crates naming convention is generally used. This non-normative table is included for reference for the avoidance of doubt.

AttributeWorld ID Protocolark-babyjubjubOPRF paperEIP-2494
BN254 scalar field, i.e. BabyJubJub’s base field$F_q$Fq$\mathbb{F}_p$$\mathbb{F}_r$
Modulus of the Base Field$q$Fq::MODULUS$p$$r$
BabyJubJub’s scalar field$F_r$Fr$\mathbb{F}_q$
Prime subgroup order (modulus of Scalar Field)$r$Fr::MODULUS$q$$l$
Curve order$n$$n$$n$
Cofactor$h$COFACTOR$h$$h$

3.2 Curve

BabyJubJub is defined in EIP-2494, which specifies three isomorphic forms, the Protocol uses the twisted Edwards form $E$ over $F_q$ given by

$$168700,x^2 + y^2 = 1 + 168696,x^2 y^2$$

All group operations, including key generation, signatures and scalar multiplication, MUST use this form. In particular the reduced twisted Edwards form, used by the ark-ed-on-bn254 crate, is a different curve and MUST NOT be substituted; ark-babyjubjub implements the form above.

$E$ has order

$$n = 21888242871839275222246405745257275088614511777268538073601725287587578984328$$

which factors as $n = h \cdot r$ with cofactor $h = 8$.

The base point of the Protocol is $G$ (ark_babyjubjub::EdwardsConfig::GENERATOR), of order $r$:

$$G = \left(5299619240641551281634865583518297030282874472190772894086521144482721001553,\ 16950150798460657717958625567821834550301663161624707787222815936182638968203\right)$$

3.3 Hashing

Unless otherwise noted, hashing is done via a Poseidon2 permutation over $F_q$. $P_t$ denotes the Poseidon2 permutation on $F_q^t$ with the $x^5$ S-box and the round counts below; it is a permutation, not a hash. The hash constructions built from it are defined in the subsections that follow.

$t$$R_F$ (external rounds)$R_P$ (internal rounds)
2856
3856
4856
8857
16857

Round constants and the external/internal matrices MUST be those produced for BN254 at the given $t$ by the reference Poseidon2 parameter generation script. Widths not listed above MUST NOT be used.

Any use of Poseidon2 MUST follow the mode and specifications of this section (“Hashing”) unless otherwise noted (e.g. Merkle Inclusion Proof).

3.3.1 Domain separators

A domain separator ds is the $F_q$ element derived from an ASCII label by big-endian octet-string-to-integer conversion, reduced mod $q$. Labels MUST be at most 31 bytes, so that distinct labels cannot collide under the reduction.

Each label MUST be bound to exactly one (construction, $t$, $k$) triple. For example, EdDSA Signature is allocated to the challenge hash at $t = 8$, $k = 5$, giving

$$\texttt{ds}_{\texttt{EdDSA Signature}} = 360302137480307891234917541314130533$$

3.3.2 Fixed-arity hash $H_t$

$H_t$ is the hash used wherever the number of inputs is known in advance. For a domain separator ds and inputs $m_1, \dots, m_k$ with $k \le t - 1$:

$$H_t(\texttt{ds}; m_1, \dots, m_k) := P_t([\texttt{ds}, m_1, \dots, m_k, 0, \dots, 0])[1]$$

That is, ds MUST occupy the capacity element at state index 0, the inputs occupy state indices 1..k, any remaining state elements are zero, and the digest is state element 1 of the permutation output.

$k$ MUST be constant for a given ds. The zero padding is not length-encoded, so $H_t(\texttt{ds}; m_1)$ and $H_t(\texttt{ds}; m_1, 0)$ are the same digest; binding $k$ to ds is what prevents cross-arity collisions. A construction whose input count varies at runtime MUST NOT use $H_t$.

Caution

For emphasis, failing to follow the requirement on a constant $k$, or failing to place a fixed ds at state index 0 is catastrophic. A varying $k$ gives trivial collisions and second pre-images. An input-controlled state index 0 allows an attacker to invert the permutation and produce pre-images for any digest.

3.3.3 Variable-length hash $H_\text{var}$

$H_\text{var}$ is the hash used for byte strings whose length is not fixed, where $H_t$ cannot be applied. It is a sponge over $P_{16}$: rate 15 across state indices 0..14, capacity at index 15, squeezing from index 0. Note this is the opposite convention to $H_t$, which places the capacity at index 0; $H_\text{var}$ places it last to follow SAFE.

The input is split into 31-byte chunks, each converted to an integer in big-endian order (the final chunk is not padded); the chunks are absorbed 15 at a time, applying $P_{16}$ after each group. The capacity is initialized with a SHA3-256 tag over the domain separator label and the input and output lengths, following SAFE. Because the length is bound into the capacity, inputs of different lengths cannot collide by padding, the weakness $H_t$ avoids by fixing $k$ instead.

3.4 Hash to Curve

Some constructions, in particular the OPRF evaluation of the OPRF paper, require a map $H_1: F_q \mapsto E$ that takes a field element to a curve point whose discrete logarithm with respect to $G$ is unknown. The Protocol follows RFC 9380 (“Hashing to Elliptic Curves”) instantiated for BabyJubJub, with the RFC’s expand_message step replaced by Poseidon2.

The default is $\mathrm{EncodeToCurve}$, RFC 9380’s encode_to_curve. Its output lies in the prime-order subgroup and has unknown discrete logarithm, but is not uniformly distributed in that subgroup: Elligator 2 reaches only about half of the curve points. This is sufficient wherever the requirement is an unknown discrete logarithm rather than uniformity, which covers every present use in the Protocol.

$\mathrm{EncodeToCurve}$ composes four steps, each defined below:

$$\mathrm{EncodeToCurve}(x) := \mathrm{ClearCofactor}\bigl(\mathrm{RationalMap}\bigl(\mathrm{Elligator2}\bigl(\mathrm{HashToField}(x)\bigr)\bigr)\bigr)$$

3.4.1 Notation

$\texttt{sgn0}$ is RFC 9380 §4.1 sgn0: the least significant bit of the canonical integer representative of its argument. $\texttt{inv0}$ is RFC 9380 §4 inv0: $\texttt{inv0}(0) = 0$ and $\texttt{inv0}(y) = y^{-1}$ otherwise. $\texttt{isSquare}$ is RFC 9380 §4 is_square and is true for zero. $\texttt{sqrt}$ returns an arbitrary one of the two roots; the sign is fixed explicitly in step 19 of Elligator 2, so implementations MUST NOT rely on $\texttt{sqrt}$ selecting a canonical root. $\texttt{CMOV}(f, g, c)$ returns $g$ if the condition $c$ holds and $f$ otherwise.

$E_M$ is the Montgomery form of BabyJubJub from EIP-2494, birationally equivalent to $E$:

$$K,t^2 = s^3 + J,s^2 + s, \qquad J = \frac{2(a+d)}{a-d} = 168698, \qquad K = \frac{4}{a-d} = 1$$

Since $K = 1$, the RFC’s constants reduce to $c_1 = J/K = 168698$ and $c_2 = 1/K^2 = 1$, and the final scalings by $K$ are no-ops. Implementations MAY drop them.

3.4.2 Hash to field

The label OPRF_HashToField_BabyJubJub is allocated to this construction at $t = 3$, $k = 1$. Writing $\texttt{ds}_\text{H2F}$ for the resulting domain separator,

$$\texttt{ds}_\text{H2F} = 32627786498498119128812045057993354633158048678109587794777765218$$

$$\mathrm{HashToField}(x) := H_3(\texttt{ds}_\text{H2F};\ x)$$

RFC 9380 §5 obtains a field element by expanding to $\lceil (\log_2 q + k)/8 \rceil$ bytes and reducing mod $q$, to bound the distance from uniform. Poseidon2 is a permutation over $F_q$, so $H_3$ already outputs an $F_q$ element with no modular bias, and the oversampling step is omitted.

3.4.3 Map to curve (Elligator 2)

$\mathrm{Elligator2}: F_q \mapsto E_M$ is RFC 9380 §6.7.1 with $Z = 5$, the value returned by the RFC’s find_z_ell2 for $F_q$ (RFC 9380 App. H.3). $Z$ is a non-square in $F_q$.

Given $u$, return $(s, t)$:

$$ \begin{aligned} &1..2.\ \ &&\texttt{tv1} = Z \cdot u^2 \ &3..4. &&\texttt{tv1} = \texttt{CMOV}(\texttt{tv1},\ 0,\ \texttt{tv1} = -1) \ &5..7. &&x_1 = -c_1 \cdot \texttt{inv0}(\texttt{tv1} + 1) \ &8..11. &&g_{x_1} = \bigl((x_1 + c_1),x_1 + c_2\bigr),x_1 \ &12. &&x_2 = -x_1 - c_1 \ &13. &&g_{x_2} = \texttt{tv1} \cdot g_{x_1} \ &14. &&e_2 = \texttt{isSquare}(g_{x_1}) \ &15..16. &&x = \texttt{CMOV}(x_2,\ x_1,\ e_2), \quad y^2 = \texttt{CMOV}(g_{x_2},\ g_{x_1},\ e_2) \ &17..19. &&y = \texttt{sqrt}(y^2), \quad y = \texttt{CMOV}(y,\ -y,\ e_2 \oplus \texttt{sgn0}(y)) \ &20..22. &&(s, t) = (x \cdot K,\ y \cdot K) \end{aligned} $$

Step 3 handles $\texttt{tv1} = -1$, for which $x_1$ is undefined; steps 14–16 select the branch that yields a square.

3.4.4 Rational map

$\mathrm{RationalMap}: E_M \mapsto E$ is RFC 9380 App. D.1. Given $(s, t)$, return $(v, w)$:

$$\texttt{tv} = \texttt{inv0}\bigl((s+1),t\bigr), \qquad v = \texttt{tv} \cdot (s+1) \cdot s, \qquad w = \texttt{CMOV}\bigl(\texttt{tv} \cdot t \cdot (s-1),\ 1,\ \texttt{tv} = 0\bigr)$$

The $\texttt{tv} = 0$ branch maps the exceptional points of the rational map to the identity $(0, 1)$ of $E$, so the map is total.

3.4.5 Clear cofactor

$$\mathrm{ClearCofactor}(Q) := h \cdot Q = 8 \cdot Q$$

Implementations SHOULD compute this as three doublings. The result lies in the prime-order subgroup, and the output of $\mathrm{EncodeToCurve}$ MAY therefore be consumed by templates that require a subgroup element without a further subgroup check.

Note that $\mathrm{ClearCofactor}$ can return the identity — for the $\mathrm{RationalMap}$ exceptional points above, and for any $Q$ of order dividing 8. Callers for which the identity is not an acceptable $H_1$ output MUST reject it explicitly.

3.5 Signatures

The default signature scheme for the World ID Protocol is an Edwards-curve Digital Signature Algorithm (EdDSA) over the twisted Edwards form $E$ of BabyJubJub, referred to as BabyJubJub-EdDSA-Poseidon2. It is the scheme given in the OPRF paper.

It follows the structure of RFC-8032 but is not an RFC 8032 ciphersuite: RFC 8032 defines only Ed25519 and Ed448, each with a fixed curve and a fixed hash function, and this scheme replaces both.

  1. BabyJubJub-EdDSA-Poseidon2 uses:
    1. $F_q$ as its finite field;
    2. $E$ as its elliptic curve;
    3. the base point $G$ as defined in Curve, of order $r$;
    4. Poseidon2 as its challenge hash, as defined in Hashing;
    5. BLAKE3 in XOF mode for the derivation of the secret scalar $sk$ and for deterministic nonce derivation. Implementations MUST NOT substitute Poseidon2 here, nor SHA-512 as RFC 8032 would prescribe. Implementors SHOULD follow the recommendations in RFC 8032 for key generation.
  2. Message. Messages are elements of $F_q$. A message not natively encodable in $F_q$ MUST first be lowered to $F_q$ with a construction from Hashing.
  3. Challenge. $e = H_8(\texttt{ds}_{\texttt{EdDSA Signature}}; R_x, R_y, pk_x, pk_y, M)$, where $pk$ is the signer’s public key. $e$ MAY be used as a full-field scalar without reduction, since reduction mod $r$ is a no-op on the prime-order subgroup in which $pk$ is required to lie.
  4. Signature. The signature is $\sigma = (R, s)$. $R$ is $r’ \cdot G$, where $r’$ is RECOMMENDED to be derived by hashing the deterministic nonce concatenated by the message as in RFC 8032, and $s = r’ + e * sk$.
  5. Public Key. The public key $pk$ is derived as $sk \cdot G$.

3.5.1 Verification

A signature $\sigma = (R, s)$ on a message $M$ under a public key $pk$ is valid iff all of the following hold.

  1. Canonical encoding. $pk$ and $R$ MUST decode from canonical field elements, per Public Key Representation.
  2. Canonical Scalar. All $s$ scalars MUST fulfill $s \in {0, \dots, r-1}$ to prevent signature malleability (i.e. a reduced scalar).
  3. $pk$ in the prime-order subgroup. $pk$ MUST satisfy the curve equation, MUST lie in the prime-order subgroup, and MUST NOT be the identity. This also rejects the small-order points.
  4. $R$ on curve. $R$ MUST be a point satisfying the BabyJubJub curve equation because addition is only complete for on-curve points. The point is NOT REQUIRED to lie in the prime-order subgroup for security, although conforming clients MUST produce points that lie in the prime-order subgroup.
  5. Cofactored verification equation. The signature MUST meet the cofactored verification equation $h\left(sG - R - e \cdot pk\right) = \mathcal{O}$, with $h = 8$. See Chalkias, K. et al.. Cofactorless verification MUST NOT be used; the two accept different sets of signatures.

3.5.2 Encoding

A signature is encoded as 64 bytes: $R$ in the compressed point encoding of Public Key Representation, followed by $s$ as a canonical little-endian $F_r$ element.

3.6 Discrete Logarithm Equality Proof

A discrete logarithm equality (DLogEq) proof is a Chaum–Pedersen sigma protocol, made non-interactive by the Fiat–Shamir transform with Poseidon2 as the challenge hash. It is the scheme given in the OPRF paper.

It proves knowledge of a scalar $x \in F_r$ such that

$$A = x \cdot D \quad\text{and}\quad C = x \cdot B$$

for public points $A, B, C, D \in E$, without revealing $x$. This is what gives the OPRF public verifiability: the OPRF node publishes $A = x \cdot D$ as its public key and proves that the same $x$ produced the evaluation $C = x \cdot B$ on the client’s blinded query $B$.

$D$ is a parameter of the scheme, not fixed by it. Every present use in the Protocol instantiates $D = G$, and an implementation MAY hard-code it, but the challenge hash MUST bind $D$ regardless, so that a prover cannot move the statement to a different base.

3.6.1 Proving

Given the witness $x$ and the base $B$, the prover:

  1. samples a nonce $\rho \in F_r$ uniformly at random;
  2. computes the commitments $R_1 = \rho \cdot D$ and $R_2 = \rho \cdot B$;
  3. computes the challenge $e$ as defined in Challenge;
  4. computes the response $s = \rho + e \cdot x \in F_r$.

The proof is $\pi = (e, s)$. $\rho$ MUST be freshly sampled per proof and MUST NOT be reused or derived from public data: two proofs over distinct statements that share a $\rho$ reveal $x$.

3.6.2 Challenge

The label DLOG Equality Proof is allocated to this construction at $t = 16$ with $k = 12$ inputs, giving

$$\texttt{ds}_{\texttt{DLOG Equality Proof}} = 1523098184080632582082867317389990410064981862$$

$$e = H_{16}(\texttt{ds}{\texttt{DLOG Equality Proof}};\ A_x, A_y,\ B_x, B_y,\ C_x, C_y,\ D_x, D_y,\ R{1,x}, R_{1,y},\ R_{2,x}, R_{2,y})$$

The operand order is normative: the four statement points as $A, B, C, D$, then the two commitments as $R_1, R_2$, each point contributing $x$ then $y$.

$e$ is an element of $F_q$. As in Signatures, it MAY be used as a full-field scalar without reduction, since reduction mod $r$ is a no-op on the prime-order subgroup in which all four points are required to lie.

3.6.3 Verification

A proof $\pi = (e, s)$ for the statement $(A, B, C, D)$ is valid iff all of the following hold.

  1. Canonical Scalar. $s \in {0, \dots, r-1}$, as in Signatures.
  2. Statement points in the prime-order subgroup. Each of $A$, $B$, $C$, $D$ MUST satisfy the curve equation, MUST lie in the prime-order subgroup, and MUST NOT be the identity.
  3. Recomputed commitments. $R_1 = s \cdot D - e \cdot A$ and $R_2 = s \cdot B - e \cdot C$.
  4. Non-degenerate commitments. Neither $R_1$ nor $R_2$ is the identity.
  5. Challenge. $e$ equals the challenge recomputed over $(A, B, C, D, R_1, R_2)$ per Challenge, compared as $F_q$ elements.

A verifier MAY discharge check 2 for a given point outside the proof system, and a circuit implementing this verification MAY therefore omit it for a point that is a public input of the enclosing proof. In that case the check becomes an obligation on the enclosing verifier and MUST be documented as such at the circuit boundary.

4. Public Key Representation

The PublicKey type is introduced to represent public keys of used elliptic curves. Two representations are defined and MUST NOT be conflated:

  1. In-circuit: an affine point, i.e. a structure with two Field elements $(x, y)$. Both coordinates MUST be carried explicitly; a circuit MUST NOT decompress a point.
  2. Wire: a compressed point of 32 bytes, holding $y$ as a canonical little-endian $F_q$ element with the sign of $x$ in the most significant bit of the final byte. The sign bit is set when $x > -x$, comparing canonical integer representatives. Note: This is not equivalent to sgn0.

Decompression recovers $x$ from $y$ via the curve equation and selects the root indicated by the sign bit. Deserialization MUST reject a non-canonical $y$, i.e. one that is not less than $q$. The identity point of the used BabyJubJub curve is (0,1) and is represented using the above rules.

This compressed encoding is not the iden3 BabyJubJub packing, and the two are not interchangeable.

5. Merkle Inclusion Proof

The Protocol uses Merkle trees to store membership and prove inclusion. The most important use of it is to store World ID account membership in the WorldIDRegistry. An account’s position in the tree is its leaf index.

5.1 Parameters

ParameterValue
Arity2
Depth30
Node compression$\mathrm{Compress}$, below
Empty leaf$0$

Leaf index 0 is reserved and MUST NOT be assigned.

5.2 Node compression

Nodes MUST be combined with the Davies–Meyer compression function

$$\mathrm{Compress}(x_L, x_R) := P_2([x_L, x_R])[0] + x_L$$

$t = 2$ leaves no state element free for a capacity, so $\mathrm{Compress}$ carries no domain separator and is the one exception to Domain separators. $\mathrm{Compress}$ MUST NOT be used outside a fixed-depth Merkle tree; see Security.

5.3 Inclusion proof

An inclusion proof for a leaf at index $i$ consists of $i$ together with the 30 sibling nodes $s_0, \dots, s_{29}$, ordered from the leaf level upwards. The root is recomputed as

$$v_0 = \mathrm{leaf}, \qquad v_{j+1} = \begin{cases} \mathrm{Compress}(v_j,\ s_j) & \text{if bit } j \text{ of } i \text{ is } 0 \ \mathrm{Compress}(s_j,\ v_j) & \text{otherwise} \end{cases}$$

where bit $j$ is the $j$-th least significant bit of $i$. The proof is valid if and only if $v_{30}$ equals the tree root. Verifiers MUST apply exactly 30 compressions and ensure the depth of the Merkle tree is 30 and $\forall i$, $0 < i < 2^{30}$ MUST hold.

6. Security

  1. Poseidon2 in compression mode. For a security argument of using Poseidon2 with state size 2 as a 2-1 compression mode, we refer to both section 3.1 of the Poseidon2 paper as well as the treatment of the construction in section 4.2 of the Griffin paper.
  2. Security Target. The Protocol defines a target security of 128 bits. BabyJubJub is the binding constraint, with $r \approx 2^{251}$. Poseidon2 and BLAKE3 are both parameterized for 128 bits.
  3. Assumptions. The discrete logarithm problem is hard in the order-$r$ subgroup of $E$; Poseidon2 over $F_q$, at the widths in Hashing, is collision- and preimage-resistant and behaves as a random oracle under Fiat–Shamir; BLAKE3 is a secure pseudorandom function and extendable-output function.

7. Backwards Compatibility

This spec is introduced after the initial release of the World ID 4.0 protocol, it is documenting design decisions previously defined in the 4.0 Specs and from the OPRF Whitepaper, so it’s not breaking backwards compatibility. From adoption onwards, the definitions in this spec become binding for the Query Proof and Nullifier Proof used in the World ID Protocol.

Appendix A1. Test Vectors

Field elements are decimal integers. Byte strings are hexadecimal; wrapped lines are concatenated. For ascending inputs of length $n$, byte $i$ is $i \bmod 251$.

A1.1 Domain separators

label = EdDSA Signature
ds = 360302137480307891234917541314130533
label = OPRF_HashToField_BabyJubJub
ds = 32627786498498119128812045057993354633158048678109587794777765218
label = DLOG Equality Proof
ds = 1523098184080632582082867317389990410064981862
label = CLAIMS_HASH_V1
ds = 1364962988938129392107510493566513

A1.2 Poseidon2 permutations

Each width uses the input state $[0, 1, \dots, t-1]$. All output elements are listed in state order.

t = 2
output[0] = 13120422956170837922441672802975889424559262309139960702680326932494325745547
output[1] = 5923567162677888564808904842769941181302763723060647224839027357562627386465
t = 3
output[0] = 5297208644449048816064511434384511824916970985131888684874823260532015509555
output[1] = 21816030159894113985964609355246484851575571273661473159848781012394295965040
output[2] = 13940986381491601233448981668101586453321811870310341844570924906201623195336
t = 4
output[0] = 786823568102245344938517132468097745676732687098822989626730198331658606391
output[1] = 16105493617470833344375945651585194737369509580406730765188791202038211593826
output[2] = 2169165722086073256768101917994796590773204847633762971322389403847680713675
output[3] = 20837792685223053096472825292260687493226094382304778455120670180090619921530
t = 8
output[0] = 13163567864211573827878829467860137302577760599598440387954761704438999762399
output[1] = 20455256474176316209572707628365862887207812418465031548192789068192434065861
output[2] = 21622031586696647398529562584873094656572287904668581566093346191656615936784
output[3] = 18320622048765136384409419776996464874987888500923344182439589703061890523284
output[4] = 19915468795157938233689963601267136400922725821760118753901600546477081024243
output[5] = 12383970660639123649548441396659012498414420037083153473614822644813849243474
output[6] = 9133088157465982496917058916696585316057943251337470087079495488316110895778
output[7] = 5020935059501715015422969097649999023750915432550677386523662686145648636517
t = 16
output[0] = 7129053404014098913941583447102076532611276040718594073862066403012892177215
output[1] = 5458683216916715697310099658604278457911373519210593239261146303695981710820
output[2] = 11764907654416682971926471140388165312909351793032868507449176373009888376893
output[3] = 17363012907147515824232626923071954964539976031233523938322583063167173991942
output[4] = 16754602647566413012759386310550362661092317428428132757066277153406453157400
output[5] = 10442131742273378767812305849732860137449534508695657144865044457198204305243
output[6] = 13315916208806700309353847107954103794241355430909228633658159683794835480566
output[7] = 14675611827802190925530581036356245293764500457751312643178429199155385431971
output[8] = 3800671750689110886099899395588427301982955036566905831860793275457528754896
output[9] = 863058427093450397617252284543198432424871511785791089866952153042503171268
output[10] = 16110421480974327191214802248220528120081914075253666769021797524181818259452
output[11] = 3050248777345249982082587219460801555485024010345812479213241978893548171998
output[12] = 8005144369031495385854140476761376792991595443174132540148616210767138457404
output[13] = 193712991007063517677674367979478243863141973963118958643316643360558925992
output[14] = 6765341258738133397733055933640609905610288576122407133007925535267189590216
output[15] = 6411743912316957490668095751870764077217660758836562678571866082387292213586

A1.3 Hash to field

This also tests $H_3$ with one input and one zero-padding element.

label = OPRF_HashToField_BabyJubJub
input = 1
output = 10409509318069101293316722480711595867625349071847922195261332397736272636435

A1.4 Variable-length hash

The label is CLAIMS_HASH_V1. Inputs are ascending bytes. Lengths 31 and 32 cover the chunk boundary; lengths 465 and 466 cover the permutation boundary. Empty input is invalid.

length = 31
digest = 12658306072862357948815044357476041793480954961275831694284480429814652585452
length = 32
digest = 7105501883046959224351664232028428089815911608118705425730076057190813037341
length = 465
digest = 13435504409435728907439603956434602577345452839959452028063546759536561347478
length = 466
digest = 15525893232164838192982873493581731321396161293199355856124601873305423262450

A1.5 Merkle tree

Compress(0, 0) = 15621590199821056450610068202457788725601603091791048810523422053872049975191
Compress(1, 2) = 6588139247708940112588203339651261153905233202198520634825199962343944922547

Define the empty-subtree roots by $z_0 = 0$ and $z_{j+1} = \mathrm{Compress}(z_j, z_j)$. Then $z_{30}$ is the empty tree root. The inclusion vector uses $s_j = z_j$ as the sibling path.

z_2 = 15180302612178352054084191513289999058431498575847349863917170755410077436260
z_30 = 15633048765234690365876053958277790002681834789256406938121001738966131111330
leaf = 42
index = 1
root = 21449849969959258301263701183300082902700436494585373070244441970359881620262

With the same root and sibling path, leaf 43 is invalid.

A1.6 Point encoding

$G$ is defined in Curve. The encodings of $G$ and $-G$ exercise both values of the sign bit.

G = 8b7d2d877a253c4b7733e1b91f05e0fcedf96bd11c2e572549b2a0f703727925
-G = 8b7d2d877a253c4b7733e1b91f05e0fcedf96bd11c2e572549b2a0f7037279a5
identity = 0100000000000000000000000000000000000000000000000000000000000000

A1.7 Signature

The deterministic signing procedure for this vector is:

  1. Expand the 32-byte seed with BLAKE3 XOF to 64 bytes.
  2. Copy the first 32 bytes to a; set a[0] &= 0xf8 and a[31] = (a[31] & 0x7f) | 0x40. Interpret a as a little-endian integer and reduce modulo $r$ to obtain $sk$.
  3. Interpret the last 32 bytes as a little-endian integer and reduce modulo $r$ to obtain the nonce secret.
  4. Encode the nonce secret and message as 32-byte little-endian integers, concatenate them in that order, and expand with BLAKE3 XOF to 64 bytes. Interpret the result as a little-endian integer and reduce modulo $r$ to obtain $r’$.
  5. Compute $pk = skG$, $R = r’G$, the challenge $e$, and $s = (r’ + e \cdot sk) \bmod r$.
seed = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
message = 42
pk.x = 5743127613665812714027674485677763488557233128677239431720756512332055304469
pk.y = 6713952740716875958406247477052754272136198788949552789678520356076812341435
pk = bb9015f1309156fdfddcda5e5922f1ae565f6e5b2e78d4e35f884e036cf6d70e
R.x = 4471796480099078564607791866308147318722757043758328908648489482326053658209
R.y = 16743942090139358314901240752948685648557595749372215854958283055038688657910
s = 1707871037059365895665483114747551425359126542652147321192782334073340268810
signature = f601e481eec3c9fac20942eed731b5c815194fd1416a3f0c7948ffdf41bc0425
            0a91c15ded66fde2ecec499b86fd56a7aad62d409391584a9c126b8de99ec603
e = 14790550837438996768258768677587167620081417436968300740169708289833632123084

The signature verifies for message 42 and fails for message 43. The challenge $e$ also satisfies the cofactored verification equation in Signatures.

The following verification-only vector has $pk = G$ and $R = G + (0, -1)$. It MUST be accepted by the cofactored equation; the cofactorless equation rejects it. Signers MUST still produce $R$ in the prime-order subgroup.

message = 42
e = 14107477924306369449585376693150860508714550631015857449267997894818346434634
s = 427326129406822435681373102365063578330480770223021153266919590076109569430

A1.8 EncodeToCurve

input = 2
output.x = 20419487629862769727627645368371427138888560013459229812372534124769971005828
output.y = 7631771008065059170045692780763031490103103796767657363493053446444837523289
input = 42
output.x = 1368536874988764403285491466492470225763829673979223271328990939656695174872
output.y = 5918944744409897789209151589310931911112404737084812644826989226820698253694

Inputs 2 and 42 exercise the square and non-square branches of Elligator 2, respectively. Both outputs are non-identity points in the prime-order subgroup.

A1.9 DLogEq proof

$D = G$ and $B = \mathrm{EncodeToCurve}(42)$ from the vector above. The fixed nonce is for this test only.

witness = 12345
nonce = 67890
A.x = 19099552327547260981542886231210125691902505931204088720746463491300185142606
A.y = 13276557205153692030187527501273228448057533426731746626187331221465573305487
C.x = 1704386023042037258303736539892861539707201163487540094949081990693465165451
C.y = 8768369809996482248064559070370438612828016885307150244744623529899299197157
R1.x = 7560514331452906482367540963526316341247740678202978210835422163029445477658
R1.y = 11610694160704858701950599566691828874575930603037515361903555914794501850944
R2.x = 3490405731880058419043956475882448859018810273867088182397477099060627470353
R2.y = 11594420891490965176904143623534974685648090668464922826887222168496451873187
e = 16671088874615503773909688665365363469394641783242006990890243365077833605068
s = 388554659608811743276554153883008978905828355147065499832325343644454488330

The proof $(e, s)$ verifies for $(A, B, C, D)$. Swapping $A$ and $C$ is invalid.