Skip to content

Commit 0ef7119

Browse files
committed
[zklogin] add support for v2 vk
1 parent ff39c4b commit 0ef7119

6 files changed

Lines changed: 322 additions & 31 deletions

File tree

fastcrypto-zkp/benches/zklogin.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mod zklogin_benches {
1717
use fastcrypto_zkp::bn254::zk_login::ZkLoginInputs;
1818
use fastcrypto_zkp::bn254::zk_login::JWK;
1919
use fastcrypto_zkp::bn254::zk_login::{JwkId, OIDCProvider};
20-
use fastcrypto_zkp::bn254::zk_login_api::ZkLoginEnv;
20+
use fastcrypto_zkp::bn254::zk_login_api::{CircuitVersion, ZkLoginEnv};
2121
use im::hashmap::HashMap as ImHashMap;
2222

2323
/// Benchmark the `fastcrypto_zkp::bn254::zk_login_api::verify_zk_login` function and it's main
@@ -77,12 +77,17 @@ mod zklogin_benches {
7777
c.bench_function("verify_zk_login/calculate_all_inputs_hash", move |b| {
7878
b.iter(|| {
7979
input_clone
80-
.calculate_all_inputs_hash(&eph_pubkey_clone, &modulus_clone, max_epoch)
80+
.calculate_all_inputs_hash(
81+
&eph_pubkey_clone,
82+
&modulus_clone,
83+
max_epoch,
84+
CircuitVersion::V1,
85+
)
8186
.unwrap()
8287
});
8388
});
8489
let input_hashes = input
85-
.calculate_all_inputs_hash(&eph_pubkey, &modulus, max_epoch)
90+
.calculate_all_inputs_hash(&eph_pubkey, &modulus, max_epoch, CircuitVersion::V1)
8691
.unwrap();
8792

8893
// Benchmark the `verify_zk_login_proof_with_fixed_vk` function called by `verify_zk_login`.
@@ -95,6 +100,7 @@ mod zklogin_benches {
95100
&ZkLoginEnv::Prod,
96101
&proof,
97102
&[input_hashes],
103+
CircuitVersion::V1,
98104
)
99105
})
100106
},
@@ -109,6 +115,7 @@ mod zklogin_benches {
109115
&eph_pubkey,
110116
&map,
111117
&ZkLoginEnv::Prod,
118+
CircuitVersion::V1,
112119
)
113120
})
114121
});

fastcrypto-zkp/src/bn254/unit_tests/zk_login_e2e_tests.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::bn254::zk_login::fetch_jwks;
99
use crate::bn254::{
1010
utils::{gen_address_seed, get_proof},
1111
zk_login::{JwkId, OIDCProvider, ZkLoginInputs, JWK},
12-
zk_login_api::{verify_zk_login, ZkLoginEnv},
12+
zk_login_api::{verify_zk_login, CircuitVersion, ZkLoginEnv},
1313
};
1414
use ark_std::rand::{rngs::StdRng, SeedableRng};
1515
use fastcrypto::jwt_utils::parse_and_validate_jwt;
@@ -46,6 +46,7 @@ async fn test_end_to_end_twitch() {
4646
&eph_pubkey,
4747
&map,
4848
&ZkLoginEnv::Test,
49+
CircuitVersion::V1,
4950
);
5051
assert!(res.is_ok());
5152

@@ -56,6 +57,7 @@ async fn test_end_to_end_twitch() {
5657
&eph_pubkey,
5758
&map,
5859
&ZkLoginEnv::Prod,
60+
CircuitVersion::V1,
5961
);
6062
assert!(res_prod.is_err());
6163
}
@@ -88,6 +90,7 @@ async fn test_end_to_end_kakao() {
8890
&eph_pubkey,
8991
&map,
9092
&ZkLoginEnv::Test,
93+
CircuitVersion::V1,
9194
);
9295
assert!(res.is_ok());
9396

@@ -98,6 +101,7 @@ async fn test_end_to_end_kakao() {
98101
&eph_pubkey,
99102
&map,
100103
&ZkLoginEnv::Prod,
104+
CircuitVersion::V1,
101105
);
102106
assert!(res_prod.is_err());
103107
}
@@ -129,6 +133,7 @@ async fn test_end_to_end_apple() {
129133
&eph_pubkey,
130134
&map,
131135
&ZkLoginEnv::Test,
136+
CircuitVersion::V1,
132137
);
133138
assert!(res.is_ok());
134139

@@ -139,6 +144,7 @@ async fn test_end_to_end_apple() {
139144
&eph_pubkey,
140145
&map,
141146
&ZkLoginEnv::Prod,
147+
CircuitVersion::V1,
142148
);
143149
assert!(res_prod.is_err());
144150
}
@@ -170,6 +176,7 @@ async fn test_end_to_end_slack() {
170176
&eph_pubkey,
171177
&map,
172178
&ZkLoginEnv::Test,
179+
CircuitVersion::V1,
173180
);
174181
assert!(res.is_ok());
175182

@@ -180,6 +187,7 @@ async fn test_end_to_end_slack() {
180187
&eph_pubkey,
181188
&map,
182189
&ZkLoginEnv::Prod,
190+
CircuitVersion::V1,
183191
);
184192
assert!(res_prod.is_err());
185193
}
@@ -229,6 +237,7 @@ async fn test_end_to_end_all_providers() {
229237
&eph_pubkey,
230238
&map,
231239
&ZkLoginEnv::Test,
240+
CircuitVersion::V1,
232241
);
233242
assert!(res.is_ok());
234243

@@ -239,6 +248,7 @@ async fn test_end_to_end_all_providers() {
239248
&eph_pubkey,
240249
&map,
241250
&ZkLoginEnv::Prod,
251+
CircuitVersion::V1,
242252
);
243253
assert!(res_prod.is_err());
244254
}
@@ -363,6 +373,7 @@ async fn test_end_to_end_test_issuer(test_input: TestInputStruct) {
363373
&eph_pk_bytes,
364374
&map,
365375
&ZkLoginEnv::Test,
376+
CircuitVersion::V1,
366377
);
367378
assert!(res.is_ok());
368379
}

fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use std::str::FromStr;
55

66
use crate::bn254::utils::{
7-
gen_address_seed, gen_address_seed_with_salt_hash, get_nonce, get_zk_login_address,
7+
gen_address_seed, gen_address_seed_with_salt_hash, get_nonce, get_proof, get_zk_login_address,
88
};
99
use crate::bn254::zk_login::big_int_array_to_bits;
1010
use crate::bn254::zk_login::bitarray_to_bytearray;
@@ -14,8 +14,9 @@ use crate::bn254::zk_login::{
1414
parse_jwks, trim, verify_extended_claim, Claim, JWTDetails, JwkId,
1515
};
1616
use crate::bn254::zk_login::{fetch_jwks, OIDCProvider};
17-
use crate::bn254::zk_login_api::ZkLoginEnv;
18-
use crate::bn254::zk_login_api::{verify_zk_login_id, verify_zk_login_iss, Bn254Fr};
17+
use crate::bn254::zk_login_api::{
18+
verify_zk_login_id, verify_zk_login_iss, Bn254Fr, CircuitVersion, ZkLoginEnv,
19+
};
1920
use crate::bn254::{
2021
zk_login::{ZkLoginInputs, JWK},
2122
zk_login_api::verify_zk_login,
@@ -27,7 +28,7 @@ use ark_std::rand::SeedableRng;
2728
use fastcrypto::ed25519::Ed25519KeyPair;
2829
use fastcrypto::encoding::{Encoding, Hex};
2930
use fastcrypto::error::FastCryptoError;
30-
use fastcrypto::jwt_utils::JWTHeader;
31+
use fastcrypto::jwt_utils::{parse_and_validate_jwt, JWTHeader};
3132
use fastcrypto::traits::KeyPair;
3233
use im::hashmap::HashMap as ImHashMap;
3334
use num_bigint::BigUint;
@@ -166,7 +167,14 @@ async fn test_verify_zk_login_google() {
166167
),
167168
content,
168169
);
169-
let res = verify_zk_login(&zk_login_inputs, 10, &eph_pubkey, &map, &ZkLoginEnv::Prod);
170+
let res = verify_zk_login(
171+
&zk_login_inputs,
172+
10,
173+
&eph_pubkey,
174+
&map,
175+
&ZkLoginEnv::Prod,
176+
CircuitVersion::V1,
177+
);
170178
assert!(res.is_ok());
171179
}
172180

@@ -673,6 +681,7 @@ fn test_alternative_iss_for_google() {
673681
&eph_pubkey_bytes,
674682
&all_jwk,
675683
&ZkLoginEnv::Test,
684+
CircuitVersion::V1,
676685
);
677686
assert!(res.is_ok());
678687

@@ -682,10 +691,87 @@ fn test_alternative_iss_for_google() {
682691
&eph_pubkey_bytes,
683692
&all_jwk,
684693
&ZkLoginEnv::Test,
694+
CircuitVersion::V1,
685695
);
686696
assert!(invalid_res.is_err());
687697
}
688698

699+
#[tokio::test]
700+
async fn test_zklogin_v2() {
701+
let max_epoch = 10;
702+
let jwt_randomness = "100681567828351849884072155819400689117";
703+
let user_salt = "129390038577185583942388216820280642146";
704+
705+
// Generate an ephemeral key pair
706+
let kp = Ed25519KeyPair::generate(&mut StdRng::from_seed([0; 32]));
707+
let mut eph_pubkey = vec![0x00];
708+
eph_pubkey.extend(kp.public().as_ref());
709+
let kp_bigint = BigUint::from_bytes_be(&eph_pubkey).to_string();
710+
711+
// Get nonce
712+
let nonce = get_nonce(kp.public().as_ref(), max_epoch, jwt_randomness).unwrap();
713+
714+
// Get JWT from 8192-bit key endpoint
715+
let client = reqwest::Client::new();
716+
let iss = OIDCProvider::TestIssuerKey8192.get_config().iss;
717+
let response = client
718+
.post(format!(
719+
"https://jwt-tester.mystenlabs.com/8192/jwt?nonce={}&iss={}&sub={}",
720+
nonce, iss, "test"
721+
))
722+
.header("Content-Type", "application/json")
723+
.header("Content-Length", "0")
724+
.send()
725+
.await
726+
.unwrap();
727+
let jwt_response: serde_json::Value = response.json().await.unwrap();
728+
let parsed_token = jwt_response["jwt"].as_str().unwrap().to_string();
729+
730+
// Get a proof from the V2 endpoint
731+
let reader = get_proof(
732+
&parsed_token,
733+
max_epoch,
734+
jwt_randomness,
735+
&kp_bigint,
736+
user_salt,
737+
"http://185.209.177.123:8080/v2",
738+
)
739+
.await
740+
.expect("get_proof failed");
741+
742+
// Get sub and aud
743+
let (sub, aud, _) =
744+
parse_and_validate_jwt(&parsed_token).expect("parse_and_validate_jwt failed");
745+
746+
// Get the address seed
747+
let address_seed =
748+
gen_address_seed(user_salt, "sub", &sub, &aud).expect("gen_address_seed failed");
749+
750+
let zk_login_inputs =
751+
ZkLoginInputs::from_reader(reader, &address_seed).expect("from_reader failed");
752+
753+
// Fetch the 8192-bit RSA JWK
754+
let jwks_vec = fetch_jwks(&OIDCProvider::TestIssuerKey8192, &client, false)
755+
.await
756+
.unwrap();
757+
758+
let mut all_jwk = ImHashMap::new();
759+
for (jwk_id, jwk) in jwks_vec {
760+
all_jwk.insert(jwk_id, jwk);
761+
}
762+
763+
// V2 proof should verify using TEST_VERIFYING_KEY_V2
764+
let res_v2 = verify_zk_login(
765+
&zk_login_inputs,
766+
max_epoch,
767+
&eph_pubkey,
768+
&all_jwk,
769+
&ZkLoginEnv::Test,
770+
CircuitVersion::V2,
771+
);
772+
assert!(res_v2.is_ok());
773+
}
774+
689775
#[test]
690776
fn test_base64_to_bitarray() {
691777
let input = "a";

fastcrypto-zkp/src/bn254/utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use std::str::FromStr;
1818
use super::zk_login::hash_ascii_str_to_field;
1919

2020
const ZK_LOGIN_AUTHENTICATOR_FLAG: u8 = 0x05;
21-
const MAX_KEY_CLAIM_NAME_LENGTH: u8 = 32;
22-
const MAX_KEY_CLAIM_VALUE_LENGTH: u8 = 115;
23-
const MAX_AUD_VALUE_LENGTH: u8 = 145;
21+
const MAX_KEY_CLAIM_NAME_LENGTH: u16 = 32;
22+
const MAX_KEY_CLAIM_VALUE_LENGTH: u16 = 115;
23+
const MAX_AUD_VALUE_LENGTH: u16 = 145;
2424

2525
/// Calculate the Sui address based on address seed and address params.
2626
pub fn get_zk_login_address(

0 commit comments

Comments
 (0)