diff --git a/rs/execution_environment/src/execution_environment/tests.rs b/rs/execution_environment/src/execution_environment/tests.rs index e3d23eb774e..fa67aa3417c 100644 --- a/rs/execution_environment/src/execution_environment/tests.rs +++ b/rs/execution_environment/src/execution_environment/tests.rs @@ -2282,13 +2282,20 @@ fn get_reject_message(response: RequestOrResponse) -> String { } } -fn make_schnorr_key(name: &str) -> MasterPublicKeyId { +fn make_ed25519_key(name: &str) -> MasterPublicKeyId { MasterPublicKeyId::Schnorr(SchnorrKeyId { algorithm: SchnorrAlgorithm::Ed25519, name: name.to_string(), }) } +fn make_bip340_key(name: &str) -> MasterPublicKeyId { + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Bip340Secp256k1, + name: name.to_string(), + }) +} + fn make_vetkd_key(name: &str) -> MasterPublicKeyId { MasterPublicKeyId::VetKd(VetKdKeyId { curve: VetKdCurve::Bls12_381_G2, @@ -3111,60 +3118,66 @@ fn test_sign_with_schnorr_api_is_enabled() { // TODO(EXC-1629): upgrade to more of e2e test with mocking the response // from consensus and producing the response to the canister. - // Arrange. - let key_id = make_schnorr_key("correct_key"); - let own_subnet = subnet_test_id(1); - let nns_subnet = subnet_test_id(2); - let nns_canister = canister_test_id(0x10); - let mut test = ExecutionTestBuilder::new() - .with_own_subnet_id(own_subnet) - .with_nns_subnet_id(nns_subnet) - .with_caller(nns_subnet, nns_canister) - .with_chain_key(key_id.clone()) - .build(); - let canister_id = test.universal_canister().unwrap(); - // Check that the SubnetCallContextManager is empty. - assert_eq!( - test.state() - .metadata - .subnet_call_context_manager - .sign_with_threshold_contexts_count(&key_id), - 0 - ); + let test_cases = [ + make_ed25519_key("correct_ed25519_key"), + make_bip340_key("correct_bip340_key"), + ]; - // Act. - let method = Method::SignWithSchnorr; - let run = wasm() - .call_with_cycles( - ic00::IC_00, - method, - call_args() - .other_side(sign_with_threshold_key_payload(method, key_id.clone())) - .on_reject(wasm().reject_message().reject()), - Cycles::from(100_000_000_000u128), - ) - .build(); - let (_, ingress_status) = test.ingress_raw(canister_id, "update", run); + for key_id in &test_cases { + // Arrange. + let own_subnet = subnet_test_id(1); + let nns_subnet = subnet_test_id(2); + let nns_canister = canister_test_id(0x10); + let mut test = ExecutionTestBuilder::new() + .with_own_subnet_id(own_subnet) + .with_nns_subnet_id(nns_subnet) + .with_caller(nns_subnet, nns_canister) + .with_chain_key(key_id.clone()) + .build(); + let canister_id = test.universal_canister().unwrap(); + // Check that the SubnetCallContextManager is empty. + assert_eq!( + test.state() + .metadata + .subnet_call_context_manager + .sign_with_threshold_contexts_count(key_id), + 0 + ); - // Assert. - // Check that the request is accepted and processing. - assert_eq!( - ingress_status, - IngressStatus::Known { - receiver: canister_id.get(), - user_id: test.user_id(), - time: test.time(), - state: IngressState::Processing, - } - ); - // Check that the SubnetCallContextManager contains the request. - assert_eq!( - test.state() - .metadata - .subnet_call_context_manager - .sign_with_threshold_contexts_count(&key_id), - 1 - ); + // Act. + let method = Method::SignWithSchnorr; + let run = wasm() + .call_with_cycles( + ic00::IC_00, + method, + call_args() + .other_side(sign_with_threshold_key_payload(method, key_id.clone())) + .on_reject(wasm().reject_message().reject()), + Cycles::from(100_000_000_000u128), + ) + .build(); + let (_, ingress_status) = test.ingress_raw(canister_id, "update", run); + + // Assert. + // Check that the request is accepted and processing. + assert_eq!( + ingress_status, + IngressStatus::Known { + receiver: canister_id.get(), + user_id: test.user_id(), + time: test.time(), + state: IngressState::Processing, + } + ); + // Check that the SubnetCallContextManager contains the request. + assert_eq!( + test.state() + .metadata + .subnet_call_context_manager + .sign_with_threshold_contexts_count(key_id), + 1 + ); + } } #[test] diff --git a/rs/execution_environment/tests/threshold_signatures.rs b/rs/execution_environment/tests/threshold_signatures.rs index d916dc1d10a..b9ed178ad4b 100644 --- a/rs/execution_environment/tests/threshold_signatures.rs +++ b/rs/execution_environment/tests/threshold_signatures.rs @@ -3,7 +3,8 @@ use ic_base_types::PrincipalId; use ic_management_canister_types::{ self as ic00, CanisterInstallMode, DerivationPath, ECDSAPublicKeyResponse, EcdsaCurve, EcdsaKeyId, MasterPublicKeyId, Method, Payload as Ic00Payload, SchnorrAlgorithm, SchnorrKeyId, - SchnorrPublicKeyResponse, SignWithECDSAReply, SignWithSchnorrReply, + SchnorrPublicKeyResponse, SignWithBip341Aux, SignWithECDSAReply, SignWithSchnorrAux, + SignWithSchnorrReply, }; use ic_registry_subnet_type::SubnetType; use ic_state_machine_tests::{StateMachine, StateMachineBuilder, UserError}; @@ -33,13 +34,20 @@ fn make_ecdsa_key(name: &str) -> MasterPublicKeyId { }) } -fn make_schnorr_key(name: &str) -> MasterPublicKeyId { +fn make_ed25519_key(name: &str) -> MasterPublicKeyId { MasterPublicKeyId::Schnorr(SchnorrKeyId { algorithm: SchnorrAlgorithm::Ed25519, name: name.to_string(), }) } +fn make_bip340_key(name: &str) -> MasterPublicKeyId { + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Bip340Secp256k1, + name: name.to_string(), + }) +} + fn into_inner_ecdsa(key_id: MasterPublicKeyId) -> EcdsaKeyId { match key_id { MasterPublicKeyId::Ecdsa(key) => key, @@ -78,11 +86,25 @@ fn sign_with_threshold_key_payload(method: Method, key_id: MasterPublicKeyId) -> key_id: into_inner_ecdsa(key_id), } .encode(), - Method::SignWithSchnorr => ic00::SignWithSchnorrArgs { - message: vec![], - derivation_path: DerivationPath::new(vec![]), - key_id: into_inner_schnorr(key_id), - aux: None, + Method::SignWithSchnorr => { + let key_id = into_inner_schnorr(key_id); + + let aux = match key_id.algorithm { + SchnorrAlgorithm::Bip340Secp256k1 => { + let aux = SignWithBip341Aux { + merkle_root_hash: vec![0; 32].into(), + }; + Some(SignWithSchnorrAux::Bip341(aux)) + } + _ => None, + }; + + ic00::SignWithSchnorrArgs { + message: vec![], + derivation_path: DerivationPath::new(vec![]), + key_id, + aux, + } } .encode(), _ => panic!("unexpected method"), @@ -193,7 +215,11 @@ fn compute_initial_threshold_key_dealings_test_cases() -> Vec<(Method, MasterPub ), ( Method::ComputeInitialIDkgDealings, - make_schnorr_key("some_key"), + make_ed25519_key("some_key"), + ), + ( + Method::ComputeInitialIDkgDealings, + make_bip340_key("some_key"), ), ] } @@ -349,7 +375,13 @@ fn test_sign_with_threshold_key_fee_charged() { ), ( Method::SignWithSchnorr, - make_schnorr_key("some_key"), + make_ed25519_key("some_key"), + 1_000_000, + 2_000_000, + ), + ( + Method::SignWithSchnorr, + make_bip340_key("some_key"), 1_000_000, 2_000_000, ), @@ -416,7 +448,12 @@ fn test_sign_with_threshold_key_rejected_without_fee() { (Method::SignWithECDSA, make_ecdsa_key("some_key"), 2_000_000), ( Method::SignWithSchnorr, - make_schnorr_key("some_key"), + make_ed25519_key("some_key"), + 2_000_000, + ), + ( + Method::SignWithSchnorr, + make_bip340_key("some_key"), 2_000_000, ), ]; @@ -467,8 +504,13 @@ fn test_sign_with_threshold_key_unknown_key_rejected() { ), ( Method::SignWithSchnorr, - make_schnorr_key("correct_key"), - make_schnorr_key("wrong_key"), + make_ed25519_key("correct_key"), + make_ed25519_key("wrong_key"), + ), + ( + Method::SignWithSchnorr, + make_bip340_key("correct_key"), + make_bip340_key("wrong_key"), ), ]; for (method, correct_key, wrong_key) in test_cases { @@ -510,8 +552,14 @@ fn test_signing_disabled_vs_unknown_key_on_public_key_and_signing_requests() { ( Method::SchnorrPublicKey, Method::SignWithSchnorr, - make_schnorr_key("signing_disabled_key"), - make_schnorr_key("unknown_key"), + make_ed25519_key("signing_disabled_key"), + make_ed25519_key("unknown_key"), + ), + ( + Method::SchnorrPublicKey, + Method::SignWithSchnorr, + make_bip340_key("signing_disabled_key"), + make_bip340_key("unknown_key"), ), ]; for (public_key_method, sign_with_method, signing_disabled_key, unknown_key) in test_cases { @@ -591,8 +639,13 @@ fn test_threshold_key_public_key_req_with_unknown_key_rejected() { ), ( Method::SchnorrPublicKey, - make_schnorr_key("correct_key"), - make_schnorr_key("wrong_key"), + make_ed25519_key("correct_key"), + make_ed25519_key("wrong_key"), + ), + ( + Method::SchnorrPublicKey, + make_bip340_key("correct_key"), + make_bip340_key("wrong_key"), ), ]; for (method, correct_key, wrong_key) in test_cases { @@ -624,7 +677,8 @@ fn test_threshold_key_public_key_req_with_unknown_key_rejected() { fn test_sign_with_threshold_key_fee_ignored_for_nns() { let test_cases = vec![ (Method::SignWithECDSA, make_ecdsa_key("some_key")), - (Method::SignWithSchnorr, make_schnorr_key("some_key")), + (Method::SignWithSchnorr, make_ed25519_key("some_key")), + (Method::SignWithSchnorr, make_bip340_key("some_key")), ]; for (method, key_id) in test_cases { let fee = 1_000_000; @@ -672,7 +726,8 @@ fn test_sign_with_threshold_key_fee_ignored_for_nns() { fn test_sign_with_threshold_key_queue_fills_up() { let test_cases = vec![ (Method::SignWithECDSA, make_ecdsa_key("some_key"), 20), - (Method::SignWithSchnorr, make_schnorr_key("some_key"), 20), + (Method::SignWithSchnorr, make_ed25519_key("some_key"), 20), + (Method::SignWithSchnorr, make_bip340_key("some_key"), 20), ]; for (method, key_id, max_queue_size) in test_cases { let fee = 1_000_000;