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