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    TREE_DEPTH, authenticator::AuthenticatorPublicKeySet, merkle::MerkleInclusionProof,
8    oprf::WorldIdRequestAuthError,
9};
10use zeroize::{Zeroize, ZeroizeOnDrop};
11
12pub(crate) mod oprf_query;
13pub use oprf_query::{FullOprfOutput, OprfEntrypoint};
14
15pub mod proof;
16pub use proof::*;
17
18#[cfg(feature = "provekit")]
19use provekit_common::{InputMap, InputValue, NoirElement};
20
21#[cfg(feature = "provekit")]
22use world_id_primitives::FieldElement;
23
24#[cfg(feature = "provekit")]
25pub mod ownership_proof;
26
27/// Error type for OPRF operations and proof generation.
28#[derive(Debug, thiserror::Error)]
29pub enum ProofError {
30    /// Authentication error returned by the OPRF nodes (e.g. unknown RP, invalid proof).
31    #[error(transparent)]
32    RequestAuthError(#[from] WorldIdRequestAuthError),
33    /// Non-auth error originating from `oprf_client`.
34    #[error(transparent)]
35    OprfError(taceo_oprf::client::Error),
36    /// Errors originating from proof inputs
37    #[error(transparent)]
38    ProofInputError(#[from] errors::ProofInputError),
39    /// Errors originating from Groth16 proof generation or verification.
40    #[error(transparent)]
41    ZkError(#[from] Groth16Error),
42    /// Error generating a Noir Proof with ProveKit
43    #[error("generation error: {0}")]
44    GenerationError(String),
45    /// Catch-all for other internal errors.
46    #[error(transparent)]
47    InternalError(#[from] eyre::Report),
48}
49
50#[cfg(feature = "provekit")]
51pub trait NoirCircuitInput {
52    fn into_witness(self) -> Result<InputMap, ProofError>;
53}
54
55#[cfg(feature = "provekit")]
56pub trait NoirRepresentable {
57    fn into_noir_value(self) -> InputValue;
58}
59
60#[cfg(feature = "provekit")]
61impl NoirRepresentable for FieldElement {
62    fn into_noir_value(self) -> InputValue {
63        InputValue::Field(NoirElement::from_repr(*self))
64    }
65}
66
67impl From<taceo_oprf::client::Error> for ProofError {
68    fn from(err: taceo_oprf::client::Error) -> Self {
69        if let taceo_oprf::client::Error::ThresholdServiceError(ref svc) = err {
70            if svc.kind.is_auth() {
71                return Self::RequestAuthError(WorldIdRequestAuthError::from(svc.error_code));
72            }
73        }
74        Self::OprfError(err)
75    }
76}
77
78/// Inputs from the Authenticator to generate a nullifier or blinding factor.
79#[derive(Zeroize, ZeroizeOnDrop)]
80pub struct AuthenticatorProofInput {
81    /// The set of all public keys for all the user's authenticators.
82    #[zeroize(skip)]
83    key_set: AuthenticatorPublicKeySet,
84    /// Inclusion proof in the World ID Registry.
85    #[zeroize(skip)]
86    inclusion_proof: MerkleInclusionProof<TREE_DEPTH>,
87    /// The off-chain signer key for the Authenticator.
88    private_key: EdDSAPrivateKey,
89    /// The index at which the authenticator key is located in the `key_set`.
90    key_index: u64,
91}
92
93impl AuthenticatorProofInput {
94    /// Creates a new authenticator proof input.
95    #[must_use]
96    pub const fn new(
97        key_set: AuthenticatorPublicKeySet,
98        inclusion_proof: MerkleInclusionProof<TREE_DEPTH>,
99        private_key: EdDSAPrivateKey,
100        key_index: u64,
101    ) -> Self {
102        Self {
103            key_set,
104            inclusion_proof,
105            private_key,
106            key_index,
107        }
108    }
109}