Skip to main content

world_id_proof/
lib.rs

1#![cfg_attr(not(test), warn(unused_crate_dependencies))]
2
3use eddsa_babyjubjub::EdDSAPrivateKey;
4use groth16_material::Groth16Error;
5
6use world_id_primitives::{
7    AuthenticatorPublicKeySet, TREE_DEPTH, merkle::MerkleInclusionProof,
8    oprf::WorldIdRequestAuthError,
9};
10use zeroize::{Zeroize, ZeroizeOnDrop};
11
12/// ZK artifact source abstractions.
13pub mod artifacts;
14
15/// Circuit input types for Circom/Groth16 circuits (query, nullifier, ownership proofs).
16pub mod circuit_inputs;
17
18pub mod compress;
19pub use compress::ProofCompression;
20pub(crate) mod oprf_query;
21pub use oprf_query::{FullOprfOutput, OprfEntrypoint};
22
23pub mod proof;
24pub use proof::*;
25
26use provekit_common::{InputMap, InputValue, NoirElement};
27
28use world_id_primitives::FieldElement;
29
30// TODO: Currently ownership proofs are not supported for WASM targets
31#[cfg(not(target_arch = "wasm32"))]
32pub mod ownership_proof;
33
34pub use provekit_common::{
35    NoirProof, Prover as OwnershipProver, Verifier as OwnershipVerifier, WhirR1CSProof,
36};
37
38/// Error type for OPRF operations and proof generation.
39#[derive(Debug, thiserror::Error)]
40pub enum ProofError {
41    /// Authentication error returned by the OPRF nodes (e.g. unknown RP, invalid proof).
42    #[error(transparent)]
43    RequestAuthError(#[from] WorldIdRequestAuthError),
44    /// Non-auth error originating from `oprf_client`.
45    #[error(transparent)]
46    OprfError(taceo_oprf::client::Error),
47    /// Errors originating from proof inputs
48    #[error(transparent)]
49    ProofInputError(#[from] errors::ProofInputError),
50    /// Errors originating from Groth16 proof generation or verification.
51    #[error(transparent)]
52    ZkError(#[from] Groth16Error),
53    /// Error loading ZK artifacts from a [`artifacts::ZkArtifactSource`].
54    #[error(transparent)]
55    ZkArtifact(#[from] artifacts::ZkArtifactError),
56    /// Error generating a Noir Proof with ProveKit
57    #[error("proof generation error: {0}")]
58    GenerationError(String),
59    /// Error verifying a Noir Proof with ProveKit. This usually means the proof is invalid.
60    #[error("proof verification error: {0}")]
61    Verification(String),
62    /// Catch-all for other internal errors.
63    #[error(transparent)]
64    InternalError(#[from] eyre::Report),
65}
66
67pub trait NoirCircuitInput {
68    fn into_witness(self) -> Result<InputMap, ProofError>;
69}
70
71pub trait NoirRepresentable {
72    fn into_noir_value(self) -> InputValue;
73}
74
75impl NoirRepresentable for FieldElement {
76    fn into_noir_value(self) -> InputValue {
77        InputValue::Field(NoirElement::from_repr(*self))
78    }
79}
80
81impl From<taceo_oprf::client::Error> for ProofError {
82    fn from(err: taceo_oprf::client::Error) -> Self {
83        if let taceo_oprf::client::Error::ThresholdServiceError(ref svc) = err
84            && svc.kind.is_auth()
85        {
86            return Self::RequestAuthError(WorldIdRequestAuthError::from(svc.error_code));
87        }
88        Self::OprfError(err)
89    }
90}
91
92/// Inputs from the Authenticator to generate a nullifier or blinding factor.
93#[derive(Zeroize, ZeroizeOnDrop)]
94pub struct AuthenticatorProofInput {
95    /// The set of all public keys for all the user's authenticators.
96    #[zeroize(skip)]
97    pub key_set: AuthenticatorPublicKeySet,
98    /// Inclusion proof in the World ID Registry.
99    #[zeroize(skip)]
100    pub inclusion_proof: MerkleInclusionProof<TREE_DEPTH>,
101    /// The off-chain signer key for the Authenticator.
102    private_key: EdDSAPrivateKey,
103    /// The index at which the authenticator key is located in the `key_set`.
104    pub key_index: u64,
105}
106
107impl AuthenticatorProofInput {
108    /// Creates a new authenticator proof input.
109    #[must_use]
110    pub const fn new(
111        key_set: AuthenticatorPublicKeySet,
112        inclusion_proof: MerkleInclusionProof<TREE_DEPTH>,
113        private_key: EdDSAPrivateKey,
114        key_index: u64,
115    ) -> Self {
116        Self {
117            key_set,
118            inclusion_proof,
119            private_key,
120            key_index,
121        }
122    }
123}