iota_sdk_crypto/zklogin/
mod.rs1use std::collections::HashMap;
6
7use iota_types::{Jwk, JwkId, UserSignature, ZkLoginAuthenticator};
8use poseidon::POSEIDON;
9use signature::Verifier;
10
11use crate::SignatureError;
12
13mod poseidon;
14mod verify;
15
16#[cfg(test)]
17mod tests;
18
19#[derive(Debug, Clone, PartialEq, Default)]
20pub struct ZkloginVerifier {
21 proof_verifying_key: verify::VerifyingKey,
22 jwks: HashMap<JwkId, Jwk>,
23}
24
25impl ZkloginVerifier {
26 fn new(proof_verifying_key: verify::VerifyingKey) -> Self {
27 Self {
28 proof_verifying_key,
29 jwks: Default::default(),
30 }
31 }
32
33 pub fn new_mainnet() -> Self {
34 Self::new(verify::VerifyingKey::new_mainnet())
35 }
36
37 pub fn new_dev() -> Self {
40 Self::new(verify::VerifyingKey::new_dev())
41 }
42
43 pub fn jwks(&self) -> &HashMap<JwkId, Jwk> {
44 &self.jwks
45 }
46
47 pub fn jwks_mut(&mut self) -> &mut HashMap<JwkId, Jwk> {
48 &mut self.jwks
49 }
50}
51
52impl Verifier<ZkLoginAuthenticator> for ZkloginVerifier {
53 fn verify(
54 &self,
55 message: &[u8],
56 signature: &ZkLoginAuthenticator,
57 ) -> Result<(), SignatureError> {
58 let jwk_id = signature.inputs.jwk_id();
60 let jwk = self.jwks.get(jwk_id).ok_or_else(|| {
61 SignatureError::from_source(format!(
62 "unable to find corresponding jwk with id '{jwk_id:?}' for provided authenticator",
63 ))
64 })?;
65
66 crate::simple::SimpleVerifier.verify(message, &signature.signature)?;
68
69 self.proof_verifying_key.verify_zklogin(
71 jwk,
72 &signature.inputs,
73 &signature.signature,
74 signature.max_epoch,
75 )
76 }
77}
78
79impl Verifier<UserSignature> for ZkloginVerifier {
80 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
81 let UserSignature::ZkLogin(zklogin_authenticator) = signature else {
82 return Err(SignatureError::from_source("not a zklogin signature"));
83 };
84
85 self.verify(message, zklogin_authenticator.as_ref())
86 }
87}