From 1e7d704d06705734e0f0998349c77284b6d52867 Mon Sep 17 00:00:00 2001 From: Joy Wang <108701016+joyqvq@users.noreply.github.com> Date: Sun, 19 May 2024 22:06:02 -0400 Subject: [PATCH] add config for new providers (#737) * feat: add new providers to zklogin * updates --- Cargo.lock | 1 + fastcrypto-zkp/Cargo.toml | 1 + .../bn254/unit_tests/zk_login_e2e_tests.rs | 86 +++++++++++--- .../src/bn254/unit_tests/zk_login_tests.rs | 21 ++-- fastcrypto-zkp/src/bn254/utils.rs | 6 +- fastcrypto-zkp/src/bn254/zk_login.rs | 108 +++++++++++++++++- .../src/bn254/zklogin_test_vectors.json | 20 ++++ 7 files changed, 212 insertions(+), 31 deletions(-) create mode 100644 fastcrypto-zkp/src/bn254/zklogin_test_vectors.json diff --git a/Cargo.lock b/Cargo.lock index fdd61b421a..e91ee1aa48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1522,6 +1522,7 @@ dependencies = [ "once_cell", "poseidon-ark", "proptest", + "regex", "reqwest", "schemars", "serde", diff --git a/fastcrypto-zkp/Cargo.toml b/fastcrypto-zkp/Cargo.toml index 59e7450800..d25810deb9 100644 --- a/fastcrypto-zkp/Cargo.toml +++ b/fastcrypto-zkp/Cargo.toml @@ -45,6 +45,7 @@ ff = { version = "0.13.0", features = ["derive"] } typenum = "1.13.0" lazy_static = "1.4.0" itertools = "0.12.0" +regex = "1.7.1" [dev-dependencies] ark-bls12-377 = "0.4.0" diff --git a/fastcrypto-zkp/src/bn254/unit_tests/zk_login_e2e_tests.rs b/fastcrypto-zkp/src/bn254/unit_tests/zk_login_e2e_tests.rs index 6d15325e70..1d87e18b30 100644 --- a/fastcrypto-zkp/src/bn254/unit_tests/zk_login_e2e_tests.rs +++ b/fastcrypto-zkp/src/bn254/unit_tests/zk_login_e2e_tests.rs @@ -12,11 +12,14 @@ use crate::bn254::{ zk_login_api::{verify_zk_login, ZkLoginEnv}, }; use ark_std::rand::{rngs::StdRng, SeedableRng}; -use fastcrypto::{ed25519::Ed25519KeyPair, jwt_utils::parse_and_validate_jwt, traits::KeyPair}; +use fastcrypto::jwt_utils::parse_and_validate_jwt; +use fastcrypto::{ed25519::Ed25519KeyPair, traits::KeyPair}; use im::HashMap as ImHashMap; use num_bigint::BigUint; +use serde::{Deserialize, Serialize}; use test_strategy::proptest; use test_strategy::Arbitrary; + const PROVER_DEV_SERVER_URL: &str = "https://prover-dev.mystenlabs.com/v1"; #[tokio::test] @@ -28,16 +31,12 @@ async fn test_end_to_end_twitch() { // Make a map of jwk ids to jwks just for Twitch. let mut map = ImHashMap::new(); map.insert( - JwkId::new( - OIDCProvider::Twitch.get_config().iss, - "1".to_string(), - ), + JwkId::new(zk_login_inputs.get_iss().to_string(),"1".to_string()), JWK { kty: "RSA".to_string(), e: "AQAB".to_string(), n: "6lq9MQ-q6hcxr7kOUp-tHlHtdcDsVLwVIw13iXUCvuDOeCi0VSuxCCUY6UmMjy53dX00ih2E4Y4UvlrmmurK0eG26b-HMNNAvCGsVXHU3RcRhVoHDaOwHwU72j7bpHn9XbP3Q3jebX6KIfNbei2MiR0Wyb8RZHE-aZhRYO8_-k9G2GycTpvc-2GBsP8VHLUKKfAs2B6sW3q3ymU6M0L-cFXkZ9fHkn9ejs-sqZPhMJxtBPBxoUIUQFTgv4VXTSv914f_YkNw-EjuwbgwXMvpyr06EyfImxHoxsZkFYB-qBYHtaMxTnFsZBr6fn8Ha2JqT1hoP7Z5r5wxDu3GQhKkHw".to_string(), - alg: "RS256".to_string(), - }, + alg: "RS256".to_string(),}, ); // Verify it against test vk ok. @@ -72,15 +71,14 @@ async fn test_end_to_end_kakao() { let mut map = ImHashMap::new(); map.insert( JwkId::new( - OIDCProvider::Kakao.get_config().iss, + zk_login_inputs.get_iss().to_string(), "9f252dadd5f233f93d2fa528d12fea".to_string(), ), JWK { kty: "RSA".to_string(), e: "AQAB".to_string(), n: "qGWf6RVzV2pM8YqJ6by5exoixIlTvdXDfYj2v7E6xkoYmesAjp_1IYL7rzhpUYqIkWX0P4wOwAsg-Ud8PcMHggfwUNPOcqgSk1hAIHr63zSlG8xatQb17q9LrWny2HWkUVEU30PxxHsLcuzmfhbRx8kOrNfJEirIuqSyWF_OBHeEgBgYjydd_c8vPo7IiH-pijZn4ZouPsEg7wtdIX3-0ZcXXDbFkaDaqClfqmVCLNBhg3DKYDQOoyWXrpFKUXUFuk2FTCqWaQJ0GniO4p_ppkYIf4zhlwUYfXZEhm8cBo6H2EgukntDbTgnoha8kNunTPekxWTDhE5wGAt6YpT4Yw".to_string(), - alg: "RS256".to_string(), - }, + alg: "RS256".to_string(),}, ); // Verify it against test vk ok. @@ -114,15 +112,14 @@ async fn test_end_to_end_apple() { let mut map = ImHashMap::new(); map.insert( JwkId::new( - OIDCProvider::Apple.get_config().iss, + zk_login_inputs.get_iss().to_string(), "W6WcOKB".to_string(), ), JWK { kty: "RSA".to_string(), e: "AQAB".to_string(), n: "2Zc5d0-zkZ5AKmtYTvxHc3vRc41YfbklflxG9SWsg5qXUxvfgpktGAcxXLFAd9Uglzow9ezvmTGce5d3DhAYKwHAEPT9hbaMDj7DfmEwuNO8UahfnBkBXsCoUaL3QITF5_DAPsZroTqs7tkQQZ7qPkQXCSu2aosgOJmaoKQgwcOdjD0D49ne2B_dkxBcNCcJT9pTSWJ8NfGycjWAQsvC8CGstH8oKwhC5raDcc2IGXMOQC7Qr75d6J5Q24CePHj_JD7zjbwYy9KNH8wyr829eO_G4OEUW50FAN6HKtvjhJIguMl_1BLZ93z2KJyxExiNTZBUBQbbgCNBfzTv7JrxMw".to_string(), - alg: "RS256".to_string(), - }, + alg: "RS256".to_string(),}, ); // Verify it against test vk ok. @@ -156,15 +153,14 @@ async fn test_end_to_end_slack() { let mut map = ImHashMap::new(); map.insert( JwkId::new( - OIDCProvider::Slack.get_config().iss, + zk_login_inputs.get_iss().to_string(), "mB2MAyKSn555isd0EbdhKx6nkyAi9xLq8rvCEb_nOyY".to_string(), ), JWK { kty: "RSA".to_string(), e: "AQAB".to_string(), n: "zQqzXfb677bpMKw0idKC5WkVLyqk04PWMsWYJDKqMUUuu_PmzdsvXBfHU7tcZiNoHDuVvGDqjqnkLPEzjXnaZY0DDDHvJKS0JI8fkxIfV1kNy3DkpQMMhgAwnftUiSXgb5clypOmotAEm59gHPYjK9JHBWoHS14NYEYZv9NVy0EkjauyYDSTz589aiKU5lA-cePG93JnqLw8A82kfTlrJ1IIJo2isyBGANr0YzR-d3b_5EvP7ivU7Ph2v5JcEUHeiLSRzIzP3PuyVFrPH659Deh-UAsDFOyJbIcimg9ITnk5_45sb_Xcd_UN6h5I7TGOAFaJN4oi4aaGD4elNi_K1Q".to_string(), - alg: "RS256".to_string(), - }, + alg: "RS256".to_string(),}, ); // Verify it against test vk ok. @@ -188,6 +184,57 @@ async fn test_end_to_end_slack() { assert!(res_prod.is_err()); } +#[derive(Deserialize)] +struct TestData { + jwt: String, + kid: String, + n: String, + provider: String, +} + +#[tokio::test] +async fn test_end_to_end_all_providers() { + // All JWT generated against nonce hTPpgF7XAKbW37rEUS6pEVZqmoI. This is derived based on max_epoch = 10, kp generated from seed = [0; 32], and jwt_randomness 100681567828351849884072155819400689117. + let file = + std::fs::File::open("src/bn254/zklogin_test_vectors.json").expect("Unable to open file"); + let test_datum: Vec = serde_json::from_reader(file).unwrap(); + for test_data in test_datum { + println!("Testing provider: {:?}", test_data.provider); + // Make a map of jwk ids to jwks just for Apple. + let (max_epoch, eph_pubkey, zk_login_inputs) = get_test_inputs(&test_data.jwt).await; + let mut map = ImHashMap::new(); + map.insert( + JwkId::new(zk_login_inputs.get_iss().to_string(), test_data.kid), + JWK { + kty: "RSA".to_string(), + e: "AQAB".to_string(), + n: test_data.n, + alg: "RS256".to_string(), + }, + ); + + // Verify it against test vk ok. + let res = verify_zk_login( + &zk_login_inputs, + max_epoch, + &eph_pubkey, + &map, + &ZkLoginEnv::Test, + ); + assert!(res.is_ok()); + + // Verify it against prod vk fails. + let res_prod = verify_zk_login( + &zk_login_inputs, + max_epoch, + &eph_pubkey, + &map, + &ZkLoginEnv::Prod, + ); + assert!(res_prod.is_err()); + } +} + async fn get_test_inputs(parsed_token: &str) -> (u64, Vec, ZkLoginInputs) { let max_epoch = 10; let jwt_randomness = "100681567828351849884072155819400689117"; @@ -216,10 +263,15 @@ async fn get_test_inputs(parsed_token: &str) -> (u64, Vec, ZkLoginInputs) { let (sub, aud) = parse_and_validate_jwt(parsed_token).unwrap(); // Get the address seed. let address_seed = gen_address_seed(user_salt, "sub", &sub, &aud).unwrap(); - let zk_login_inputs = ZkLoginInputs::from_reader(reader, &address_seed.to_string()).unwrap(); + let zk_login_inputs = ZkLoginInputs::from_reader(reader, &address_seed).unwrap(); (max_epoch, eph_pubkey, zk_login_inputs) } +#[derive(Debug, Serialize, Deserialize)] +struct TestIssuerJWTResponse { + jwt: String, +} + #[derive(Arbitrary, Debug)] struct TestInputStruct { // the epoch that last till 10000 years assuming epoch duration is ~24 hours. diff --git a/fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs b/fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs index ab91d2c988..f7b51b0165 100644 --- a/fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs +++ b/fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs @@ -137,8 +137,7 @@ async fn test_verify_zk_login_google() { kty: "RSA".to_string(), e: "AQAB".to_string(), n: "oUriU8GqbRw-avcMn95DGW1cpZR1IoM6L7krfrWvLSSCcSX6Ig117o25Yk7QWBiJpaPV0FbP7Y5-DmThZ3SaF0AXW-3BsKPEXfFfeKVc6vBqk3t5mKlNEowjdvNTSzoOXO5UIHwsXaxiJlbMRalaFEUm-2CKgmXl1ss_yGh1OHkfnBiGsfQUndKoHiZuDzBMGw8Sf67am_Ok-4FShK0NuR3-q33aB_3Z7obC71dejSLWFOEcKUVCaw6DGVuLog3x506h1QQ1r0FXKOQxnmqrRgpoHqGSouuG35oZve1vgCU4vLZ6EAgBAbC0KL35I7_0wUDSMpiAvf7iZxzJVbspkQ".to_string(), - alg: "RS256".to_string(), - }; + alg: "RS256".to_string(),}; map.insert( JwkId::new( @@ -439,12 +438,15 @@ async fn test_get_jwks() { OIDCProvider::Slack, OIDCProvider::Kakao, OIDCProvider::Apple, + OIDCProvider::Microsoft, + OIDCProvider::AwsTenant(("us-east-1".to_string(), "us-east-1_LPSLCkC3A".to_string())), + OIDCProvider::KarrierOne, + OIDCProvider::Credenza3, ] { let res = fetch_jwks(&p, &client).await; assert!(res.is_ok()); res.unwrap().iter().for_each(|e| { assert_eq!(e.0.iss, p.get_config().iss); - assert_eq!(e.1.alg, "RS256".to_string()); }); } } @@ -459,7 +461,7 @@ fn test_get_nonce() { } #[test] -fn test_get_provider() { +fn test_get_provider_to_from_iss_to_from_str() { for p in [ OIDCProvider::Google, OIDCProvider::Twitch, @@ -467,11 +469,17 @@ fn test_get_provider() { OIDCProvider::Slack, OIDCProvider::Kakao, OIDCProvider::Apple, + OIDCProvider::Microsoft, + OIDCProvider::AwsTenant(("us-east-1".to_string(), "us-east-1_LPSLCkC3A".to_string())), OIDCProvider::TestIssuer, ] { + // to/from iss assert_eq!(p, OIDCProvider::from_iss(&p.get_config().iss).unwrap()); + // to/from string + assert_eq!(p, OIDCProvider::from_str(&p.to_string()).unwrap()); } - assert!(OIDCProvider::from_iss("Amazon").is_err()); + assert!(OIDCProvider::from_iss("random").is_err()); + assert!(OIDCProvider::from_str("random").is_err()); } #[test] @@ -611,8 +619,7 @@ fn test_alternative_iss_for_google() { kty: "RSA".to_string(), e: "AQAB".to_string(), n: "whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw".to_string(), - alg: "RS256".to_string(), - }, + alg: "RS256".to_string(),}, ); let res = verify_zk_login( diff --git a/fastcrypto-zkp/src/bn254/utils.rs b/fastcrypto-zkp/src/bn254/utils.rs index ec50d9d1ce..564ba72e8b 100644 --- a/fastcrypto-zkp/src/bn254/utils.rs +++ b/fastcrypto-zkp/src/bn254/utils.rs @@ -80,7 +80,11 @@ pub fn get_oidc_url( OIDCProvider::Kakao => format!("https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={}&redirect_uri={}&nonce={}", client_id, redirect_url, nonce), OIDCProvider::Apple => format!("https://appleid.apple.com/auth/authorize?client_id={}&redirect_uri={}&scope=email&response_mode=form_post&response_type=code%20id_token&nonce={}", client_id, redirect_url, nonce), OIDCProvider::Slack => format!("https://slack.com/openid/connect/authorize?response_type=code&client_id={}&redirect_uri={}&nonce={}&scope=openid", client_id, redirect_url, nonce), - OIDCProvider::TestIssuer => return Err(FastCryptoError::InvalidInput) + OIDCProvider::Microsoft => format!("https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={}&scope=openid&response_type=id_token&redirect_uri={}&nonce={}", client_id, redirect_url, nonce), + OIDCProvider::KarrierOne => format!("https://openid.karrier.one/Account/PhoneLogin?ReturnUrl=/connect/authorize?nonce={}&redirect_uri={}&response_type=id_token&scope=openid&client_id={}", nonce, redirect_url, client_id), + OIDCProvider::Credenza3 => format!("https://accounts.credenza3.com/oauth2/authorize?client_id={}&response_type=token&scope=openid+profile+email+phone&redirect_uri={}&nonce={}&state=state", client_id, redirect_url, nonce), + OIDCProvider::AwsTenant((region, tenant_id)) => format!("https://{}.auth.{}.amazoncognito.com/login?response_type=token&client_id={}&redirect_uri={}&nonce={}", tenant_id, region, client_id, redirect_url, nonce), + OIDCProvider::TestIssuer => return Err(FastCryptoError::InvalidInput), // Test issuer does not issue JWTs interactively, this is not valid to call. }) } diff --git a/fastcrypto-zkp/src/bn254/zk_login.rs b/fastcrypto-zkp/src/bn254/zk_login.rs index 6c22eb0dc4..9882a992cb 100644 --- a/fastcrypto-zkp/src/bn254/zk_login.rs +++ b/fastcrypto-zkp/src/bn254/zk_login.rs @@ -19,6 +19,7 @@ pub use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use fastcrypto::error::FastCryptoError; use itertools::Itertools; use num_bigint::BigUint; +use regex::Regex; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::cmp::Ordering::{Equal, Greater, Less}; @@ -52,6 +53,13 @@ pub struct JwkId { impl JwkId { /// Create a new JwkId. pub fn new(iss: String, kid: String) -> Self { + // if a Microsoft iss is found, remove the tenant id from it + if match_micrsoft_iss_substring(&iss) { + return Self { + iss: "https://login.microsoftonline.com/v2.0".to_string(), + kid, + }; + } Self { iss, kid } } } @@ -91,6 +99,15 @@ pub enum OIDCProvider { /// See https://slack.com/.well-known/openid-configuration Slack, /// This is a test issuer maintained by Mysten that will return a JWT non-interactively. + /// See https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration + Microsoft, + /// Example: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_LPSLCkC3A/.well-known/jwks.json + AwsTenant((String, String)), + /// https://openid.karrier.one/.well-known/openid-configuration + KarrierOne, + /// https://accounts.credenza3.com/openid-configuration + Credenza3, + /// This is a test issuer that will return a JWT non-interactively. TestIssuer, } @@ -106,7 +123,22 @@ impl FromStr for OIDCProvider { "Apple" => Ok(Self::Apple), "Slack" => Ok(Self::Slack), "TestIssuer" => Ok(Self::TestIssuer), - _ => Err(FastCryptoError::InvalidInput), + "Microsoft" => Ok(Self::Microsoft), + "KarrierOne" => Ok(Self::KarrierOne), + "Credenza3" => Ok(Self::Credenza3), + _ => { + let re = Regex::new( + r"AwsTenant-region:(?P[^.]+)-tenant_id:(?P[^/]+)", + ) + .unwrap(); + if let Some(captures) = re.captures(s) { + let region = captures.name("region").unwrap().as_str(); + let tenant_id = captures.name("tenant_id").unwrap().as_str(); + Ok(Self::AwsTenant((region.to_owned(), tenant_id.to_owned()))) + } else { + Err(FastCryptoError::InvalidInput) + } + } } } } @@ -121,6 +153,12 @@ impl ToString for OIDCProvider { Self::Apple => "Apple".to_string(), Self::Slack => "Slack".to_string(), Self::TestIssuer => "TestIssuer".to_string(), + Self::Microsoft => "Microsoft".to_string(), + Self::KarrierOne => "KarrierOne".to_string(), + Self::Credenza3 => "Credenza3".to_string(), + Self::AwsTenant((region, tenant_id)) => { + format!("AwsTenant-region:{}-tenant_id:{}", region, tenant_id) + } } } } @@ -152,6 +190,25 @@ impl OIDCProvider { OIDCProvider::Slack => { ProviderConfig::new("https://slack.com", "https://slack.com/openid/connect/keys") } + OIDCProvider::Microsoft => ProviderConfig::new( + "https://login.microsoftonline.com/v2.0", + "https://login.microsoftonline.com/common/discovery/v2.0/keys", + ), + OIDCProvider::AwsTenant((region, tenant_id)) => ProviderConfig::new( + &format!("https://cognito-idp.{}.amazonaws.com/{}", region, tenant_id), + &format!( + "https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json", + region, tenant_id + ), + ), + OIDCProvider::KarrierOne => ProviderConfig::new( + "https://openid.karrier.one/", + "https://openid.karrier.one/.well-known/jwks", + ), + OIDCProvider::Credenza3 => ProviderConfig::new( + "https://accounts.credenza3.com", + "https://accounts.credenza3.com/jwks", + ), OIDCProvider::TestIssuer => ProviderConfig::new( "https://oauth.sui.io", "https://jwt-tester.mystenlabs.com/.well-known/jwks.json", @@ -169,11 +226,40 @@ impl OIDCProvider { "https://appleid.apple.com" => Ok(Self::Apple), "https://slack.com" => Ok(Self::Slack), "https://oauth.sui.io" => Ok(Self::TestIssuer), - _ => Err(FastCryptoError::InvalidInput), + "https://openid.karrier.one/" => Ok(Self::KarrierOne), + "https://accounts.credenza3.com" => Ok(Self::Credenza3), + iss if match_micrsoft_iss_substring(iss) => Ok(Self::Microsoft), + _ => match parse_aws_iss_substring(iss) { + Ok((region, tenant_id)) => { + Ok(Self::AwsTenant((region.to_string(), tenant_id.to_string()))) + } + Err(_) => Err(FastCryptoError::InvalidInput), + }, } } } +/// Check if the iss string is formatted as Microsoft's pattern. +fn match_micrsoft_iss_substring(iss: &str) -> bool { + iss.starts_with("https://login.microsoftonline.com/") && iss.ends_with("/v2.0") +} + +/// Parse the region and tenant_id from the iss string for AWS. +fn parse_aws_iss_substring(url: &str) -> Result<(&str, &str), FastCryptoError> { + let re = + Regex::new(r"https://cognito-idp\.(?P[^.]+)\.amazonaws\.com/(?P[^/]+)") + .unwrap(); + + if let Some(captures) = re.captures(url) { + // Extract the region and tenant_id from the captures + let region = captures.name("region").unwrap().as_str(); + let tenant_id = captures.name("tenant_id").unwrap().as_str(); + + Ok((region, tenant_id)) + } else { + Err(FastCryptoError::InvalidInput) + } +} /// Struct that contains info for a JWK. A list of them for different kids can /// be retrieved from the JWK endpoint (e.g. ). /// The JWK is used to verify the JWT token. @@ -198,21 +284,32 @@ pub struct JWKReader { my_use: Option, kid: String, kty: String, - alg: String, + #[serde(skip_serializing_if = "Option::is_none")] + alg: Option, + #[serde(skip_serializing_if = "Option::is_none")] + x5c: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + x5t: Option, + #[serde(skip_serializing_if = "Option::is_none")] + issuer: Option, } impl JWK { /// Parse JWK from the reader struct. pub fn from_reader(reader: JWKReader) -> FastCryptoResult { let trimmed_e = trim(reader.e); - if reader.alg != "RS256" || reader.kty != "RSA" || trimmed_e != "AQAB" { + // Microsoft does not contain alg field in JWK, so here we only check if it equals to RS256 only if alg field is present. + if (reader.alg.is_some() && reader.alg != Some("RS256".to_string())) + || reader.kty != "RSA" + || trimmed_e != "AQAB" + { return Err(FastCryptoError::InvalidInput); } Ok(Self { kty: reader.kty, e: trimmed_e, n: trim(reader.n), - alg: reader.alg, + alg: "RS256".to_string(), }) } } @@ -261,7 +358,6 @@ pub fn parse_jwks( for k in keys { let parsed: JWKReader = serde_json::from_value(k.clone()) .map_err(|_| FastCryptoError::GeneralError("Parse error".to_string()))?; - ret.push(( JwkId::new(provider.get_config().iss, parsed.kid.clone()), JWK::from_reader(parsed)?, diff --git a/fastcrypto-zkp/src/bn254/zklogin_test_vectors.json b/fastcrypto-zkp/src/bn254/zklogin_test_vectors.json new file mode 100644 index 0000000000..796772f72b --- /dev/null +++ b/fastcrypto-zkp/src/bn254/zklogin_test_vectors.json @@ -0,0 +1,20 @@ +[ + { + "jwt": "eyJ0eXAiOiJqd3QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFfeGNBejhnalRWZm5pdnZSZjZXSEF6MDBpeUZodHNlcl9BVnVWeF8wRmMifQ.eyJpYXQiOjE3MTU3MjUyNzcsImV4cCI6MTcxNTcyNTg3NywiYXVkIjoiNjU5NTRlYzVkMDNkYmEwMTk4YWMzNDNhIiwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5jcmVkZW56YTMuY29tIiwic3ViIjoiNjY0M2UzZGNkYTA0MTliZTg1NWMxMzU4Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBwaG9uZSBibG9ja2NoYWluLmV2bSBibG9ja2NoYWluLmV2bS53cml0ZSIsInRva2VuX3R5cGUiOiJCZWFyZXIiLCJ0b2tlbl91c2UiOiJpZCIsIm5vbmNlIjoiaFRQcGdGN1hBS2JXMzdyRVVTNnBFVlpxbW9JIiwibG9naW5fdHlwZSI6ImNyZWRlbnRpYWxzIiwiZW1haWwiOiJqb3lAbXlzdGVubGFicy5jb20ifQ.e70Kj00oV6vlQfK7_n4ca0P4UH0Fk8kJ3nGtHsgWtH1OAlpKPP51QNcAaig8TSN0UnJhakiXEB5KJ_lc6XsQ84s4NxBVnlLfwCxBQJ5NCkyqIRw5k4oVyeJIodj61JOo6wqMvsZhfb86MZRYPQv7-369tDRLnezZn0DrQYOD5NAwDzj2YKeuWTxRDlcUDeNjyPVzh3Um1eFUFjWOFzHDqtes3O7-9kvzDKiGnewzb8-7aKZFkie2ggcPgnLapz1SnqflzQB_YL3g_57eKUogPMHCENklG1bbhdKxemczFQXzrFqs1Wl4X-_XOXB_Z59b7SFswqPqk1APdBoYGxkALA", + "kid": "Q_xcAz8gjTVfnivvRf6WHAz00iyFhtser_AVuVx_0Fc", + "n": "qlPW7v3-QzyfBvsDO0FK67HaunFgflRsjKdsVHgJs53ZTbaC1x0mDBkrqiwpZQAdMPDP-jMLzyq_0T3BDjA0v5wrvFjvQdIFHp9kVNS6UaiDRDSxRXOhJWGt23HafTnMWjYQJfUrEHgbMcke7qsRRewV3fcQHy0d7khMJ5SgSPWo7c42WybRP9eF5EyWkDwZppZQH_XYdlo3ucG-j4JvV6Mz85hJkxhszn303V12q-CckqZ-HT3drenpCKLZoZ5yvZwlKVIgmwCothT5lRqwj-U1jZaoTPn8su4HCF2ujv80DZNKBVHGOcenNNfwbVTdnHF5G0z_BCP2rgFmhPm0BQ", + "provider": "Credenza3" + }, + { + "jwt": "eyJraWQiOiJrRjRGZU40emQ2Vk5ZREFkeERGYTRcL3FqcWpNS29vbnJ5WVp1S1RONzZkRT0iLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiMGE3VUl1cEhDNVBvVUFCTG5wWW5QQSIsInN1YiI6ImI0NzgxNDM4LWIwNjEtNzA5ZS1iNzRkLWQ4NDU5Yzg0M2NhNCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9MUFNMQ2tDM0EiLCJjb2duaXRvOnVzZXJuYW1lIjoiYjQ3ODE0MzgtYjA2MS03MDllLWI3NGQtZDg0NTljODQzY2E0Iiwibm9uY2UiOiJoVFBwZ0Y3WEFLYlczN3JFVVM2cEVWWnFtb0kiLCJhdWQiOiI2YzU2dDdyZTZla2dtdjIzbzd0bzhyMHNpYyIsImV2ZW50X2lkIjoiODc2YzA1MjQtYjdlZS00MzMyLWJiYzYtYjk4Yjc2ZDU3Y2Y4IiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE3MTU3ODY0NjksImV4cCI6MTcxNTc5MDA2OSwiaWF0IjoxNzE1Nzg2NDY5LCJqdGkiOiJiYzY3NjAzMC1iNzBhLTQ2ZDYtYTQzZC02MWJmZTQzZThkODIiLCJlbWFpbCI6ImpveUBteXN0ZW5sYWJzLmNvbSJ9.gjhJuvaRwfwISg5N6H1-RBj-kQUm7Ynn9w1Dc4qY88GzvFg_GWL2yNpZlUPf4vk2puWII11fPlUWOMBRD-KshPMg7NlH_LX34YJe0i7Xdjr4LGlGlB1LONFDjEry4m9fGQ9bLoOnZRZQde20HyHPHkyLA6XJcZr2xQ-Rmox2_uhG90qRHm6Diarx8FqFP15wk--9_40hHS8iwgPivwi3hIMTOxrfLEpf6eTBkEbb5RW5VaHuYT-mCtDkIeJ7rGgmZhehXw8FyPeeJ3yhe_6ZIYrzgLv96VcsG7lgB5TManJtH_Ee0f7YPems2L0UxELsyUIJQtdD8oD6lWHUmrZ0IQ", + "kid": "kF4FeN4zd6VNYDAdxDFa4/qjqjMKoonryYZuKTN76dE=", + "n": "uzJzyPjXUGrXwlTjEIxyvULbEdRloHI4wE794wukpIR8zPd13Rx1uH00BqGCCsjuzoooPoFByY4T8GSsS7ESgHzkLGBNyo6e0mYa8SkgaABdpwkWx7lvOjhhuZEWvbnfiM55lEVwI_Fqh7461zX0xnZreoOAMGTVUVMzHE-X36pxtw3BnG6pH_AY-2rFTrWZAu9VzbeXloaoqJzvZYVxbrY7jpPDIWV7NcXv_i3uMW9858pRrfdc3Omk76G4yyxJAImRnn76ZHJs1Atz4t-whvhk_KSLBFFd02AXSSzZ1CCS1LHDWPY8qQN8Hbql74sZKRfKNuJRVu9zfNf0EGleYQ", + "provider": "AWS Test Tenant" + }, + { + "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlkyckpZUGU4YlBNY0pfa0F4cWg1M3kyY3V2SSJ9.eyJ2ZXIiOiIyLjAiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vOTE4ODA0MGQtNmM2Ny00YzViLWIxMTItMzZhMzA0YjY2ZGFkL3YyLjAiLCJzdWIiOiJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTjdHb3g3RkVldDFfUkhvNk5FUnBzIiwiYXVkIjoiMmUzZTg3Y2ItYmYyNC00Mzk5LWFiOTgtNDgzNDNkNDU3MTI0IiwiZXhwIjoxNzE1ODczNTYyLCJpYXQiOjE3MTU3ODY4NjIsIm5iZiI6MTcxNTc4Njg2MiwidGlkIjoiOTE4ODA0MGQtNmM2Ny00YzViLWIxMTItMzZhMzA0YjY2ZGFkIiwibm9uY2UiOiJoVFBwZ0Y3WEFLYlczN3JFVVM2cEVWWnFtb0kiLCJhaW8iOiJEc1AzIXlQWjNseTVDcTdvVzFCMExWWDJwNzBRM1JlSnFsbjRxcEdDdXdpcm1KYzJqITBockt3SVJRQktYdDk5VDJjc0ZpZjRXQSFneGt1YkV6WFU0RnQ0TGpUVEtHWGpRZnNoWkgzRXpxQ2dZODlsU1B6NU0wZHlpcm8qRzNlNnBoQ096ciFGbDJ4cnZwNzlNcmpJTVV5NU1WYTIyeGR5NUVhdGJIOHRreWQ2RTI3SCFBRSpzWTkqQmNsb2xUMWdQdyQkIn0.Ku2__I8wNpCMnb0Qv8F5igK8zXLBq7hHZjzWKWum58-RlLPDVuGuMgOFUrqbWN9m65q015_Ja7sYM0vyTZ-Ril19PwyYr4YIg1OMggyljpSLdIJ052jF8s66Zi7qDm3tQeSNBpFlh4khDbHU0wWA3CrLpaR3YUOCSli_lS3YktCr1iN0EpXwlcsafMBrj5Ja3ZURGXNGpb8KtdsfyGerUHpt_g2E8OF7TXry7QoltseON55rMX96O-t3sUPCqgLZQLjjUi2fBSF7-DO3YhsgfvbTVnfe247wEA2UN-zDQVhrK9QvNdd6PKvhWNPPYtDc-tJu7cTwfziaek3gu7qqVQ", + "kid": "Y2rJYPe8bPMcJ_kAxqh53y2cuvI", + "n": "nJsdt_lD4TNVgXYM4iczy64ylLDbuxTgPgr-ml_EOxda2EGwFapaC3I0jjNIafsNAChWNqLNnhzsoVzdF6K8rVMq0Zqq0xtIr9VVedET1KU78_cfK6jlbh_TXKkMVdjHYV5yPDnWfY0dE--CQGWKCT87_ycXJiq9zSMauja_kUrHtGn_SL1TWI0o7QQHGEL4uLBA4Dal169BtA0S8O-EqnXEvDrcqqvJkxCSEe-s91NvapFc827y1WKnBBTxvEA_nFfD2chdgDxcxg7kzlNFSzmbiW8175gGCroTzR3Uyw0fWpN40mbef7WQlV-24evYM9iASpnpTSUp9IfJ4zItJQ", + "provider": "Microsoft" + } +] \ No newline at end of file