diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 08e82133dd..0c0cc05b42 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -29,7 +29,7 @@ jobs: - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov - name: Collect coverage data - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info + run: cargo llvm-cov --features experimental,copy_key,unsecure_schemes --workspace --lcov --output-path lcov.info - name: Upload coverage data to codecov uses: codecov/codecov-action@v3 with: diff --git a/Cargo.lock b/Cargo.lock index c7e9130424..f676e619e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1604,7 +1604,7 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastcrypto" -version = "0.1.6" +version = "0.1.7" dependencies = [ "aes", "aes-gcm", @@ -1732,7 +1732,7 @@ dependencies = [ [[package]] name = "fastcrypto-zkp" -version = "0.1.1" +version = "0.1.2" dependencies = [ "ark-bls12-377", "ark-bls12-381", diff --git a/fastcrypto-zkp/Cargo.toml b/fastcrypto-zkp/Cargo.toml index faa467d9c4..fb95dfeabd 100644 --- a/fastcrypto-zkp/Cargo.toml +++ b/fastcrypto-zkp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fastcrypto-zkp" -version = "0.1.1" +version = "0.1.2" license = "Apache-2.0" authors = ["Mysten Labs "] edition = "2021" @@ -50,3 +50,6 @@ hex = "0.4.3" proptest = "1.1.0" num-bigint = { version = "0.4", default-features = false, features = ["rand"] } tokio = { version = "1.24.1", features = ["sync", "rt", "macros"] } + +[features] +e2e = [] \ No newline at end of file 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 new file mode 100644 index 0000000000..f4304ebdbb --- /dev/null +++ b/fastcrypto-zkp/src/bn254/unit_tests/zk_login_e2e_tests.rs @@ -0,0 +1,70 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::bn254::{ + utils::{gen_address_seed, get_proof, get_salt}, + zk_login::{JwkId, OIDCProvider, ZkLoginInputs, JWK}, + 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 im::HashMap as ImHashMap; +use num_bigint::BigUint; + +#[tokio::test] +async fn test_end_to_end_twitch() { + // Use a fixed Twitch token obtained with nonce hTPpgF7XAKbW37rEUS6pEVZqmoI + // Derived based on max_epoch = 10, kp generated from seed = [0; 32], and jwt_randomness 100681567828351849884072155819400689117. + // let parsed_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEifQ.eyJhdWQiOiJyczFiaDA2NWk5eWE0eWR2aWZpeGw0a3NzMHVocHQiLCJleHAiOjE2OTIyODQzMzQsImlhdCI6MTY5MjI4MzQzNCwiaXNzIjoiaHR0cHM6Ly9pZC50d2l0Y2gudHYvb2F1dGgyIiwic3ViIjoiOTA0NDQ4NjkyIiwiYXpwIjoicnMxYmgwNjVpOXlhNHlkdmlmaXhsNGtzczB1aHB0Iiwibm9uY2UiOiJoVFBwZ0Y3WEFLYlczN3JFVVM2cEVWWnFtb0kiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJqb3lxdnEifQ.M54Sgs6aDu5Mprs_CgXeRbgiErC7oehj-h9oEcBqZFDADwd09zs9hbfDPqUjaNBB-_I6G7kn9e-zwPov8PUecI68kr3oyiCMWhKD-3h1FEu13MZv71B6jhIDMu1_UgI-RSrOQMRvdI8eL3qqD-KsvJuJH1Sz0w56PnB0xupUg-eSvgnMBAo6iTa0t1grX9qGy7U00i_oqn9J4jVGVVEbMhUWROJMjowWdOogJ4_VNqm67JHd_rMZ3xtjLabP6Nk1Gx-VjUbYceNADWUr5xpJveRtvb1FJvd0HSN4mab51zuSUnavCQw2OXbyoH8j6uuQAAKVhG-_Ht1hCvReycGXKw"; + let parsed_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEifQ.eyJhdWQiOiJyczFiaDA2NWk5eWE0eWR2aWZpeGw0a3NzMHVocHQiLCJleHAiOjE2OTIyODQzMzQsImlhdCI6MTY5MjI4MzQzNCwiaXNzIjoiaHR0cHM6Ly9pZC50d2l0Y2gudHYvb2F1dGgyIiwic3ViIjoiOTA0NDQ4NjkyIiwiYXpwIjoicnMxYmgwNjVpOXlhNHlkdmlmaXhsNGtzczB1aHB0Iiwibm9uY2UiOiJoVFBwZ0Y3WEFLYlczN3JFVVM2cEVWWnFtb0kiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJqb3lxdnEifQ.M54Sgs6aDu5Mprs_CgXeRbgiErC7oehj-h9oEcBqZFDADwd09zs9hbfDPqUjaNBB-_I6G7kn9e-zwPov8PUecI68kr3oyiCMWhKD-3h1FEu13MZv71B6jhIDMu1_UgI-RSrOQMRvdI8eL3qqD-KsvJuJH1Sz0w56PnB0xupUg-eSvgnMBAo6iTa0t1grX9qGy7U00i_oqn9J4jVGVVEbMhUWROJMjowWdOogJ4_VNqm67JHd_rMZ3xtjLabP6Nk1Gx-VjUbYceNADWUr5xpJveRtvb1FJvd0HSN4mab51zuSUnavCQw2OXbyoH8j6uuQAAKVhG-_Ht1hCvReycGXKw"; + let max_epoch = 10; + let jwt_randomness = "100681567828351849884072155819400689117"; + + // Get salt based on the Twitch token. + let user_salt = get_salt(parsed_token).await.unwrap(); + + // Generate an ephermeral key pair. + let kp = Ed25519KeyPair::generate(&mut StdRng::from_seed([0; 32])); + let mut eph_pubkey = vec![0x00]; + eph_pubkey.extend(kp.public().as_ref()); + let kp_bigint = BigUint::from_bytes_be(&eph_pubkey).to_string(); + + // Get a proof from endpoint and serialize it. + let reader = get_proof( + parsed_token, + max_epoch, + jwt_randomness, + &kp_bigint, + &user_salt, + ) + .await + .unwrap(); + 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).unwrap(); + // 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(), + ), + 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(), + }, + ); + + // Verify it against final vk. + let res = verify_zk_login( + &zk_login_inputs, + max_epoch, + &eph_pubkey, + &map, + &ZkLoginEnv::Prod, + ); + assert!(res.is_ok()); +} 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 742a04572a..b952ba9826 100644 --- a/fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs +++ b/fastcrypto-zkp/src/bn254/unit_tests/zk_login_tests.rs @@ -5,8 +5,7 @@ use std::str::FromStr; use crate::bn254::poseidon::PoseidonWrapper; use crate::bn254::utils::{ - gen_address_seed, gen_address_seed_with_salt_hash, get_nonce, get_proof, get_salt, - get_zk_login_address, + gen_address_seed, gen_address_seed_with_salt_hash, get_nonce, get_zk_login_address, }; use crate::bn254::zk_login::{ convert_base, decode_base64_url, hash_ascii_str_to_field, hash_to_field, parse_jwks, to_field, @@ -24,7 +23,6 @@ use ark_std::rand::SeedableRng; use fastcrypto::ed25519::Ed25519KeyPair; use fastcrypto::encoding::{Encoding, Hex}; use fastcrypto::error::FastCryptoError; -use fastcrypto::jwt_utils::parse_and_validate_jwt; use fastcrypto::traits::KeyPair; use im::hashmap::HashMap as ImHashMap; use num_bigint::BigUint; @@ -472,63 +470,6 @@ fn test_gen_seed() { ); } -#[tokio::test] -async fn test_end_to_end_twitch() { - // Use a fixed Twitch token obtained with nonce hTPpgF7XAKbW37rEUS6pEVZqmoI - // Derived based on max_epoch = 10, kp generated from seed = [0; 32], and jwt_randomness 100681567828351849884072155819400689117. - let parsed_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEifQ.eyJhdWQiOiJyczFiaDA2NWk5eWE0eWR2aWZpeGw0a3NzMHVocHQiLCJleHAiOjE2OTIyODQzMzQsImlhdCI6MTY5MjI4MzQzNCwiaXNzIjoiaHR0cHM6Ly9pZC50d2l0Y2gudHYvb2F1dGgyIiwic3ViIjoiOTA0NDQ4NjkyIiwiYXpwIjoicnMxYmgwNjVpOXlhNHlkdmlmaXhsNGtzczB1aHB0Iiwibm9uY2UiOiJoVFBwZ0Y3WEFLYlczN3JFVVM2cEVWWnFtb0kiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJqb3lxdnEifQ.M54Sgs6aDu5Mprs_CgXeRbgiErC7oehj-h9oEcBqZFDADwd09zs9hbfDPqUjaNBB-_I6G7kn9e-zwPov8PUecI68kr3oyiCMWhKD-3h1FEu13MZv71B6jhIDMu1_UgI-RSrOQMRvdI8eL3qqD-KsvJuJH1Sz0w56PnB0xupUg-eSvgnMBAo6iTa0t1grX9qGy7U00i_oqn9J4jVGVVEbMhUWROJMjowWdOogJ4_VNqm67JHd_rMZ3xtjLabP6Nk1Gx-VjUbYceNADWUr5xpJveRtvb1FJvd0HSN4mab51zuSUnavCQw2OXbyoH8j6uuQAAKVhG-_Ht1hCvReycGXKw"; - let max_epoch = 10; - let jwt_randomness = "100681567828351849884072155819400689117"; - - // Get salt based on the Twitch token. - let user_salt = get_salt(parsed_token).await.unwrap(); - - // Generate an ephermeral key pair. - let kp = Ed25519KeyPair::generate(&mut StdRng::from_seed([0; 32])); - let mut eph_pubkey = vec![0x00]; - eph_pubkey.extend(kp.public().as_ref()); - let kp_bigint = BigUint::from_bytes_be(&eph_pubkey).to_string(); - - // Get a proof from endpoint and serialize it. - let reader = get_proof( - parsed_token, - max_epoch, - jwt_randomness, - &kp_bigint, - &user_salt, - ) - .await - .unwrap(); - 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).unwrap(); - // 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(), - ), - 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(), - }, - ); - - // Verify it against final vk. - let res = verify_zk_login( - &zk_login_inputs, - max_epoch, - &eph_pubkey, - &map, - &ZkLoginEnv::Prod, - ); - assert!(res.is_ok()); -} - #[test] fn test_verify_zk_login() { // Test vector from [test_verify_zk_login_google] diff --git a/fastcrypto-zkp/src/bn254/zk_login.rs b/fastcrypto-zkp/src/bn254/zk_login.rs index 019e74a082..679e436fd0 100644 --- a/fastcrypto-zkp/src/bn254/zk_login.rs +++ b/fastcrypto-zkp/src/bn254/zk_login.rs @@ -31,6 +31,11 @@ use std::str::FromStr; #[path = "unit_tests/zk_login_tests.rs"] mod zk_login_tests; +#[cfg(feature = "e2e")] +#[cfg(test)] +#[path = "unit_tests/zk_login_e2e_tests.rs"] +mod zk_login_e2e_tests; + const MAX_HEADER_LEN: u8 = 248; const PACK_WIDTH: u8 = 248; const ISS: &str = "iss"; diff --git a/fastcrypto/Cargo.toml b/fastcrypto/Cargo.toml index 5b114c72d2..53f186e66b 100644 --- a/fastcrypto/Cargo.toml +++ b/fastcrypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fastcrypto" -version = "0.1.6" +version = "0.1.7" license = "Apache-2.0" authors = ["Mysten Labs "] edition = "2021"