From f9f785142ced7427ba420fe1374e3cf189645385 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Mon, 11 May 2026 16:39:25 +0200 Subject: [PATCH 01/29] chore: incremental --- core-client/src/lib.rs | 9 +- core/grpc/proto/kms.v1.proto | 6 +- core/grpc/src/identifiers.rs | 8 ++ core/service/src/backup/custodian.rs | 27 ++++-- core/service/src/backup/operator.rs | 95 ++++++------------- core/service/src/backup/tests.rs | 5 +- core/service/src/bin/kms-custodian.rs | 8 -- .../centralized/custodian_backup_tests.rs | 2 - .../tests/threshold/custodian_backup_tests.rs | 6 +- core/service/src/engine/backup_operator.rs | 85 +++++++++++++++-- core/service/src/engine/context_manager.rs | 2 +- .../src/vault/storage/crypto_material/base.rs | 26 +++++ docs/guides/backup.md | 4 +- docs/guides/core_client.md | 30 +++--- 14 files changed, 184 insertions(+), 129 deletions(-) diff --git a/core-client/src/lib.rs b/core-client/src/lib.rs index cc0e25fe20..fa7645a8b9 100644 --- a/core-client/src/lib.rs +++ b/core-client/src/lib.rs @@ -2195,20 +2195,13 @@ pub async fn execute_cmd( do_custodian_recovery_init(&core_endpoints_req, *overwrite_ephemeral_key).await?; assert_eq!(res.len(), operator_recovery_resp_paths.len()); - let backup_id = res[0].backup_id(); - // no ordering of results and paths here for (cur_res, cur_path) in res.into_iter().zip(operator_recovery_resp_paths) { - assert_eq!( - backup_id, - cur_res.backup_id(), - "All recovery responses must belong to the same backup ID" - ); safe_write_element_versioned(cur_path, &cur_res).await?; } vec![( - Some(backup_id), + None, "custodian recovery init queried and recovery request stored".to_string(), )] } diff --git a/core/grpc/proto/kms.v1.proto b/core/grpc/proto/kms.v1.proto index bb1336cc68..c9166d1882 100644 --- a/core/grpc/proto/kms.v1.proto +++ b/core/grpc/proto/kms.v1.proto @@ -663,7 +663,7 @@ message CustodianRecoveryInitRequest { message CustodianRecoveryOutput { OperatorBackupOutput backup_output = 1; // The 1-indexed role of the custodian - uint64 custodian_role = 2; + uint64 custodian_role = 2; // TODO these should likely have been signcrypted bytes operator_verification_key = 3; RequestId mpc_context_id = 4; } @@ -697,10 +697,6 @@ message RecoveryRequest { bytes ephem_op_enc_key = 1; /// The ciphertexts that are the backup. Indexed by the custodian role. map cts = 2; - /// The request ID under which the backup was created. - RequestId backup_id = 3; - /// Verification key of the operator. - bytes operator_verification_key = 4; } // Response containing available key material information diff --git a/core/grpc/src/identifiers.rs b/core/grpc/src/identifiers.rs index d0c501cf1d..a08e77419d 100644 --- a/core/grpc/src/identifiers.rs +++ b/core/grpc/src/identifiers.rs @@ -383,6 +383,14 @@ macro_rules! impl_identifiers { } } + impl<'a> From<&'a $type> for v1::RequestId { + fn from(id: &'a $type) -> Self { + v1::RequestId { + request_id: id.to_string(), + } + } + } + // Additional reverse conversion implementations impl From<$type> for String { fn from(id: $type) -> Self { diff --git a/core/service/src/backup/custodian.rs b/core/service/src/backup/custodian.rs index 8ca2b026c7..adc0c08cb8 100644 --- a/core/service/src/backup/custodian.rs +++ b/core/service/src/backup/custodian.rs @@ -10,10 +10,10 @@ use crate::cryptography::{ use crate::engine::validation::{RequestIdParsingErr, parse_optional_grpc_request_id}; use crate::{consts::SAFE_SER_SIZE_LIMIT, cryptography::signatures::PublicSigKey}; use hashing::DomainSep; -use kms_grpc::RequestId; use kms_grpc::kms::v1::{ CustodianContext, CustodianRecoveryOutput, CustodianSetupMessage, OperatorBackupOutput, }; +use kms_grpc::{ContextId, RequestId}; use rand::{CryptoRng, Rng}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -43,7 +43,7 @@ pub struct InternalCustodianRecoveryOutput { pub signcryption: UnifiedSigncryption, pub custodian_role: Role, pub operator_verification_key: PublicSigKey, - pub mpc_context_id: RequestId, + pub mpc_context_id: ContextId, } impl Named for InternalCustodianRecoveryOutput { @@ -313,10 +313,8 @@ impl Custodian { &self, rng: &mut R, backup: &InnerOperatorBackupOutput, - mpc_context_id: RequestId, operator_verification_key: &PublicSigKey, operator_ephem_enc_key: &UnifiedPublicEncKey, - backup_id: RequestId, ) -> Result { tracing::debug!( "Verifying and re-encrypting backup for operator: {}", @@ -333,7 +331,7 @@ impl Custodian { .unsigncrypt(&DSEP_BACKUP_CUSTODIAN, &backup.signcryption) .map_err(|e| { tracing::warn!( - "Unsigncryption failed for backup {backup_id} for operator {}: {e}", + "Unsigncryption failed for operator {}: {e}", operator_verification_key.address(), ); BackupError::CustodianRecoveryError @@ -342,9 +340,24 @@ impl Custodian { "Decrypted ciphertext for operator: {}", operator_verification_key.address() ); + if !backup_material.backup_id.is_valid() { + tracing::error!( + "Invalid backup_id {} in the decrypted backup material for operator with address: {}", + backup_material.backup_id, + operator_verification_key.address() + ); + return Err(BackupError::CustodianRecoveryError); + } + if !backup_material.mpc_context_id.is_valid() { + tracing::error!( + "Invalid MPC context ID {} in the decrypted backup material for operator with address: {}", + backup_material.mpc_context_id, + operator_verification_key.address() + ); + return Err(BackupError::CustodianRecoveryError); + } // check the decrypted result if !backup_material.matches_expected_metadata( - backup_id, &self.signing_key.verf_key(), self.role, &operator_verification_key.verf_key_id(), @@ -372,7 +385,7 @@ impl Custodian { signcryption, custodian_role: self.role, operator_verification_key: operator_verification_key.clone(), - mpc_context_id, + mpc_context_id: backup_material.mpc_context_id, }) } diff --git a/core/service/src/backup/operator.rs b/core/service/src/backup/operator.rs index 5c64ab44d0..173fbcc5fc 100644 --- a/core/service/src/backup/operator.rs +++ b/core/service/src/backup/operator.rs @@ -3,6 +3,7 @@ use super::{ error::{BackupError, SetupSkipReason}, secretsharing, }; +use crate::backup::custodian::{InternalCustodianContext, InternalCustodianRecoveryOutput}; use crate::{ anyhow_error_and_log, consts::SAFE_SER_SIZE_LIMIT, @@ -12,16 +13,12 @@ use crate::{ Signcrypt, UnifiedSigncryption, UnifiedSigncryptionKey, UnifiedUnsigncryptionKey, Unsigncrypt, }, - engine::{base::safe_serialize_hash_element_versioned, validation::RequestIdParsingErr}, + engine::base::safe_serialize_hash_element_versioned, }; use crate::{ backup::custodian::DSEP_BACKUP_CUSTODIAN, cryptography::signatures::{internal_sign, internal_verify_sig}, }; -use crate::{ - backup::custodian::{InternalCustodianContext, InternalCustodianRecoveryOutput}, - engine::validation::parse_optional_grpc_request_id, -}; use algebra::{ galois_rings::degree_4::ResiduePolyF4Z64, sharing::{shamir::ShamirSharings, share::Share}, @@ -65,8 +62,6 @@ impl Named for InternalRecoveryRequest { pub struct InternalRecoveryRequest { ephem_op_enc_key: UnifiedPublicEncKey, cts: BTreeMap, - backup_id: RequestId, - operator_verification_key: PublicSigKey, } impl InternalRecoveryRequest { @@ -74,20 +69,11 @@ impl InternalRecoveryRequest { pub fn new( ephem_op_enc_key: UnifiedPublicEncKey, cts: BTreeMap, - backup_id: RequestId, - operator_verification_key: PublicSigKey, ) -> anyhow::Result { let res = InternalRecoveryRequest { ephem_op_enc_key, cts, - backup_id, - operator_verification_key, }; - if !backup_id.is_valid() { - return Err(anyhow_error_and_log( - "InternalRecoveryRequest has an invalid backup ID", - )); - } Ok(res) } @@ -97,10 +83,6 @@ impl InternalRecoveryRequest { custodian_role: Role, unsigncrypt_key: &UnifiedUnsigncryptionKey, ) -> anyhow::Result { - if !self.backup_id.is_valid() { - tracing::warn!("InternalRecoveryRequest has an invalid backup ID"); - return Ok(false); - } let output = match self.cts.get(&custodian_role) { Some(output) => output, None => { @@ -129,24 +111,11 @@ impl InternalRecoveryRequest { pub fn signcryptions(&self) -> HashMap { self.cts.iter().map(|(role, ct)| (*role, ct)).collect() } - - pub fn backup_id(&self) -> RequestId { - self.backup_id - } - - pub fn operator_verification_key(&self) -> &PublicSigKey { - &self.operator_verification_key - } } impl Display for InternalRecoveryRequest { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "InternalRecoveryRequest with:\n backup id: {}\n operator : {}", - self.backup_id, - self.operator_verification_key.address(), - ) + write!(f, "InternalRecoveryRequest",) } } @@ -165,15 +134,9 @@ impl TryFrom for InternalRecoveryRequest { let inner_ct: InnerOperatorBackupOutput = cur_backup_out.try_into()?; cts.insert(role, inner_ct); } - let backup_id: RequestId = - parse_optional_grpc_request_id(&value.backup_id, RequestIdParsingErr::BackupRecovery)?; - let operator_verification_key: PublicSigKey = - bc2wrap::deserialize_safe(&value.operator_verification_key)?; Ok(Self { ephem_op_enc_key, cts, - backup_id, - operator_verification_key, }) } } @@ -292,7 +255,6 @@ impl RecoveryValidationMaterial { commitments: BTreeMap>, custodian_context: InternalCustodianContext, sk: &PrivateSigKey, - mpc_context: ContextId, ) -> anyhow::Result { if custodian_context.custodian_nodes.len() != cts.len() { return Err(anyhow::anyhow!( @@ -314,7 +276,6 @@ impl RecoveryValidationMaterial { cts, commitments, custodian_context, - mpc_context, }; let serialized_payload = bc2wrap::serialize(&payload).map_err(|e| { anyhow_error_and_log(format!("Could not serialize inner recovery request: {e:?}")) @@ -398,8 +359,6 @@ pub struct RecoveryValidationMaterialPayload { pub commitments: BTreeMap>, /// The custodian context used during backup pub custodian_context: InternalCustodianContext, - /// The MPC context used when constructing the backup (i.e. identifying the verification key of the operator) - pub mpc_context: ContextId, } impl Named for RecoveryValidationMaterialPayload { const NAME: &'static str = "backup::RecoveryValidationMaterialPayload"; @@ -410,7 +369,6 @@ fn checked_decryption_deserialize( unsign_key: &UnifiedUnsigncryptionKey, signcryption: &UnifiedSigncryption, commitment: &[u8], - backup_id: RequestId, custodian_role: Role, ) -> Result>, BackupError> { let backup_material: BackupMaterial = unsign_key @@ -420,9 +378,24 @@ fn checked_decryption_deserialize( "Failed to unsigncrypt backup share for custodian role {custodian_role}: {e}", )) })?; + if !backup_material.backup_id.is_valid() { + tracing::error!( + "Invalid backup_id {} in the decrypted backup material for operator with address: {}", + backup_material.backup_id, + backup_material.operator_pk.address() + ); + return Err(BackupError::CustodianRecoveryError); + } + if !backup_material.mpc_context_id.is_valid() { + tracing::error!( + "Invalid MPC context ID {} in the decrypted backup material for operator with address: {}", + backup_material.mpc_context_id, + backup_material.operator_pk.address() + ); + return Err(BackupError::CustodianRecoveryError); + } // check metadata if !backup_material.matches_expected_metadata( - backup_id, unsign_key.sender_verf_key, custodian_role, unsign_key.receiver_id, @@ -453,7 +426,10 @@ pub enum BackupMaterialVersioned { #[derive(Clone, Debug, Serialize, Deserialize, Versionize)] #[versionize(BackupMaterialVersioned)] pub struct BackupMaterial { - pub backup_id: RequestId, + /// The custodian context ID + pub backup_id: RequestId, // TODO should be contextID + /// MPC context ID + pub mpc_context_id: ContextId, // todo ensure validation // receiver pub custodian_pk: PublicSigKey, pub custodian_role: Role, @@ -465,19 +441,10 @@ pub struct BackupMaterial { impl BackupMaterial { pub fn matches_expected_metadata( &self, - backup_id: RequestId, custodian_verf_key: &PublicSigKey, custodian_role: Role, operator_pk_id: &[u8], ) -> bool { - if self.backup_id != backup_id { - tracing::error!( - "backup_id mismatch: expected {} but got {}", - self.backup_id, - backup_id - ); - return false; - } if self.custodian_role != custodian_role { tracing::error!( "custodian_role mismatch: expected {} but got {}", @@ -567,6 +534,7 @@ impl Operator { rng: &mut R, secret: &[u8], backup_id: RequestId, + mpc_context_id: ContextId, ) -> Result { let sk = match &self.signing_key { None => { @@ -639,6 +607,7 @@ impl Operator { }; let backup_material = BackupMaterial { backup_id, + mpc_context_id, custodian_pk: custodian_verf_key.clone(), custodian_role: role_j, operator_pk: self.verification_key.clone(), @@ -694,7 +663,6 @@ impl Operator { &self, custodian_recovery_output: &[InternalCustodianRecoveryOutput], recovery_material: &RecoveryValidationMaterial, - backup_id: RequestId, ephm_dec_key: &UnifiedPrivateEncKey, // Note that this is the ephemeral decryption key, NOT the actual backup decryption key ephm_enc_key: &UnifiedPublicEncKey, ) -> Result, BackupError> { @@ -727,7 +695,6 @@ impl Operator { &unsign_key, &custodian_output.signcryption, commitment, - backup_id, custodian_output.custodian_role, ) }) @@ -875,7 +842,6 @@ mod tests { use super::*; use crate::{ backup::{custodian::CustodianSetupMessagePayload, operator::RecoveryValidationMaterial}, - consts::DEFAULT_MPC_CONTEXT, cryptography::{ encryption::{Encryption, PkeScheme, PkeSchemeType}, signatures::{SigningSchemeType, gen_sig_keys}, @@ -941,14 +907,9 @@ mod tests { }; let internal_custodian_context = InternalCustodianContext::new(custodian_context, enc_key).unwrap(); - let rvm = RecoveryValidationMaterial::new( - cts, - commitments, - internal_custodian_context, - &sig_key, - *DEFAULT_MPC_CONTEXT, - ) - .unwrap(); + let rvm = + RecoveryValidationMaterial::new(cts, commitments, internal_custodian_context, &sig_key) + .unwrap(); assert!(rvm.validate(&verf_key)); } diff --git a/core/service/src/backup/tests.rs b/core/service/src/backup/tests.rs index 05595ab1a2..2ac74ba26a 100644 --- a/core/service/src/backup/tests.rs +++ b/core/service/src/backup/tests.rs @@ -94,6 +94,7 @@ fn custodian_reencrypt() { let operator_count = 4usize; let secret_len = 32usize; let backup_id = RequestId::from_bytes([8u8; crate::consts::ID_LENGTH]); + let mpc_context_id = *DEFAULT_MPC_CONTEXT; let mut rng = OsRng; @@ -142,13 +143,13 @@ fn custodian_reencrypt() { .zip_eq(&secrets) .map(|(operator, secret)| { operator - .secret_share_and_signcrypt(&mut rng, secret, backup_id) + .secret_share_and_signcrypt(&mut rng, secret, backup_id, mpc_context_id) .unwrap() }) .collect::>(); let verification_key = operators[0].verification_key(); - let mpc_context_id = RequestId::from_bytes([7u8; crate::consts::ID_LENGTH]); + let mut enc = Encryption::new(PkeSchemeType::MlKem512, &mut rng); let (_ephemeral_dec_key, ephemeral_enc_key) = enc.keygen().unwrap(); diff --git a/core/service/src/bin/kms-custodian.rs b/core/service/src/bin/kms-custodian.rs index 90d0fbd55f..5622d696ed 100644 --- a/core/service/src/bin/kms-custodian.rs +++ b/core/service/src/bin/kms-custodian.rs @@ -1,7 +1,6 @@ use aes_prng::AesRng; use clap::Parser; use hashing::{DomainSep, hash_element}; -use kms_grpc::ContextId; use kms_lib::backup::SEED_PHRASE_DESC; use kms_lib::engine::context::SoftwareVersion; use kms_lib::{ @@ -163,11 +162,6 @@ async fn main() -> Result<(), anyhow::Error> { "Decrypting ciphertexts for custodian role: {}", params.custodian_role ); - let mpc_context_id_str = params.mpc_context_id; - let mpc_context_id = ContextId::try_from(&mpc_context_id_str).map_err(|e| anyhow::anyhow!( - "Invalid MPC context ID: {}. Expected a hex string representing the MPC context ID: {e}.", - mpc_context_id_str - ))?; let operator_verf_key: PublicSigKey = safe_read_element_versioned(¶ms.operator_verf_key).await?; let recovery_request: InternalRecoveryRequest = @@ -191,10 +185,8 @@ async fn main() -> Result<(), anyhow::Error> { let res = custodian.verify_reencrypt( &mut rng, custodian_backup, - mpc_context_id.into(), &operator_verf_key, recovery_request.backup_enc_key(), - recovery_request.backup_id(), )?; tracing::info!("Verified reencryption successfully"); safe_write_element_versioned(¶ms.output_path, &res).await?; diff --git a/core/service/src/client/tests/centralized/custodian_backup_tests.rs b/core/service/src/client/tests/centralized/custodian_backup_tests.rs index 69f70af86a..4f047648e5 100644 --- a/core/service/src/client/tests/centralized/custodian_backup_tests.rs +++ b/core/service/src/client/tests/centralized/custodian_backup_tests.rs @@ -541,10 +541,8 @@ async fn emulate_custodian( .verify_reencrypt( rng, &cur_cus_reenc.to_owned().try_into().unwrap(), - kms_grpc::RequestId::from_bytes([7u8; 32]), &verf_key, &cur_enc_key, - backup_id.clone().try_into().unwrap(), ) .unwrap(); // Add the result from this custodian to the map of results to the correct operator diff --git a/core/service/src/client/tests/threshold/custodian_backup_tests.rs b/core/service/src/client/tests/threshold/custodian_backup_tests.rs index 9734fb4081..27226f3323 100644 --- a/core/service/src/client/tests/threshold/custodian_backup_tests.rs +++ b/core/service/src/client/tests/threshold/custodian_backup_tests.rs @@ -1068,8 +1068,6 @@ async fn emulate_custodian( let custodian: Custodian = custodian_from_seed_phrase(cur_mnemonic, Role::indexed_from_zero(cur_idx)).unwrap(); for (i, cur_recovery_req) in &recovery_requests { - let cur_verf_key: PublicSigKey = - bc2wrap::deserialize_safe(&cur_recovery_req.operator_verification_key).unwrap(); let cur_cus_reenc = cur_recovery_req.cts.get(&((cur_idx + 1) as u64)).unwrap(); let cur_enc_key = safe_deserialize( std::io::Cursor::new(&cur_recovery_req.ephem_op_enc_key), @@ -1080,12 +1078,12 @@ async fn emulate_custodian( .verify_reencrypt( rng, &cur_cus_reenc.to_owned().try_into().unwrap(), - kms_grpc::RequestId::from_bytes([7u8; 32]), &cur_verf_key, &cur_enc_key, - backup_id.clone().try_into().unwrap(), ) .unwrap(); + let cur_verf_key: PublicSigKey = + bc2wrap::deserialize_safe(&cur_out.operator_verification_key).unwrap(); // Add the result from this custodian to the map of results to the correct operator match outputs_for_operators.entry((*i, cur_verf_key.address())) { std::collections::hash_map::Entry::Occupied(occupied_entry) => { diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index cdc4ec03c2..6836a4f1b2 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -38,6 +38,7 @@ use crate::{ }; use algebra::galois_rings::degree_4::{ResiduePolyF4Z64, ResiduePolyF4Z128}; use itertools::Itertools; +use kms_grpc::ContextId; use kms_grpc::kms::v1::{CustodianRecoveryInitRequest, CustodianRecoveryOutput}; use kms_grpc::{ RequestId, @@ -123,8 +124,6 @@ where let recovery_request = RecoveryRequest { ephem_op_enc_key: serialized_pub_key, cts: grpc_cts, - backup_id: Some(backup_id.into()), - operator_verification_key: bc2wrap::serialize(&self.base_kms.verf_key())?, }; tracing::info!( "Generated outer recovery request for backup_id/context_id={}", @@ -137,13 +136,18 @@ where )) } + /// Validate the recovery request from the custodian, and if valid return the parsed recovery outputs from the custodians along with the recovery material and context ID. + /// Validation ensures that there is a sufficient amount of recovery outputs from the custodians, and that each of them is correctly signed by the custodian and intended for the current operator. + /// + /// Returns a tuple of (custodian_context_id, mpc_context_id, recovery_material, parsed_custodian_rec) pub(crate) async fn validate_custodian_backup_recovery_request( &self, ephemeral_dec_key: &UnifiedPrivateEncKey, ephemeral_enc_key: &UnifiedPublicEncKey, req: CustodianRecoveryRequest, ) -> anyhow::Result<( - RequestId, + ContextId, + ContextId, RecoveryValidationMaterial, HashMap, )> { @@ -180,8 +184,28 @@ where )); } + // Observe we have already validated that every mpc context ID is equal, and that there is at least t+1 entries + let pivot_cus_res = *parsed_custodian_rec.keys().next().unwrap(); + for cur_cus_res in parsed_custodian_rec.values() { + if cur_cus_res.mpc_context_id != parsed_custodian_rec[&pivot_cus_res].mpc_context_id { + return Err(anyhow::anyhow!( + "MPC context ID mismatch among recovery outputs" + )); + } + } + + if !parsed_custodian_rec[&pivot_cus_res] + .mpc_context_id + .is_valid() + { + return Err(anyhow::anyhow!( + "Invalid MPC context ID in recovery outputs" + )); + } + Ok(( custodian_context_id, + parsed_custodian_rec[&pivot_cus_res].mpc_context_id, // We have already validated they are all equal recovery_material, parsed_custodian_rec, )) @@ -351,7 +375,7 @@ where } }; let inner = request.into_inner(); - let (context_id, recovery_material, parsed_custodian_rec) = self + let (custodian_context_id, mpc_context_id, recovery_material, parsed_custodian_rec) = self .validate_custodian_backup_recovery_request( &ephemeral_dec_key, &ephemeral_enc_key, @@ -366,6 +390,52 @@ where tonic::Code::InvalidArgument, ) })?; + // Validate that the contexts are still valid + if !self + .crypto_storage + .custodian_context_exists(&custodian_context_id) + .await + .map_err(|e| { + MetricedError::new( + OP_CUSTODIAN_BACKUP_RECOVERY, + None, + anyhow::anyhow!("Failed to check existence of custodian context: {e}"), + tonic::Code::Internal, + ) + })? + { + return Err(MetricedError::new( + OP_CUSTODIAN_BACKUP_RECOVERY, + None, + anyhow::anyhow!( + "The custodian context associated with the provided context ID does not exist, thus is not valid" + ), + tonic::Code::InvalidArgument, + )); + } + if !self + .crypto_storage + .custodian_context_exists(&mpc_context_id) + .await + .map_err(|e| { + MetricedError::new( + OP_CUSTODIAN_BACKUP_RECOVERY, + None, + anyhow::anyhow!("Failed to check existence of MPC context: {e}"), + tonic::Code::Internal, + ) + })? + { + return Err(MetricedError::new( + OP_CUSTODIAN_BACKUP_RECOVERY, + None, + anyhow::anyhow!( + "The MPC context associated with the provided context ID does not exist, thus is not valid" + ), + tonic::Code::InvalidArgument, + )); + } + match self.crypto_storage.backup_vault { Some(ref backup_vault) => { let mut backup_vault: tokio::sync::MutexGuard<'_, Vault> = @@ -397,7 +467,6 @@ where .verify_and_recover( &custodian_outputs, &recovery_material, - context_id, &ephemeral_dec_key, &ephemeral_enc_key, ) @@ -519,7 +588,7 @@ where /// Load and validate the recovery validation material associated with the provided context ID async fn load_recovery_validation_material( public_storage: &Mutex, - custodian_context_id: &RequestId, + custodian_context_id: &ContextId, verf_key: &Arc, ) -> anyhow::Result where @@ -528,11 +597,11 @@ where let public_storage_guard = public_storage.lock().await; let recovery_material: RecoveryValidationMaterial = public_storage_guard .read_data( - custodian_context_id, + &(*custodian_context_id).into(), &PubDataType::RecoveryMaterial.to_string(), ) .await?; - if &recovery_material.custodian_context().context_id != custodian_context_id { + if recovery_material.custodian_context().context_id != (*custodian_context_id).into() { anyhow::bail!("The custodian context associated with the provided context ID is invalid",); } if !recovery_material.validate(verf_key) { diff --git a/core/service/src/engine/context_manager.rs b/core/service/src/engine/context_manager.rs index e0d50a6498..3f86434602 100644 --- a/core/service/src/engine/context_manager.rs +++ b/core/service/src/engine/context_manager.rs @@ -962,6 +962,7 @@ async fn gen_recovery_validation( rng, &serialized_priv_key, custodian_context.context_id, + mpc_context_id, )?; let ct_map = signcrypt_result.ct_shares; let commitments = signcrypt_result.commitments; @@ -970,7 +971,6 @@ async fn gen_recovery_validation( commitments, custodian_context.to_owned(), sig_key, - mpc_context_id, )?; tracing::info!( "Generated inner recovery request for backup_id/context_id={}", diff --git a/core/service/src/vault/storage/crypto_material/base.rs b/core/service/src/vault/storage/crypto_material/base.rs index 8376a37adc..68c4f57dd2 100644 --- a/core/service/src/vault/storage/crypto_material/base.rs +++ b/core/service/src/vault/storage/crypto_material/base.rs @@ -285,6 +285,32 @@ where .await } + pub async fn custodian_context_exists( + &self, + cus_context_id: &ContextId, + ) -> Result { + self.data_exists( + &RequestId::from(*cus_context_id), + &[PubDataType::RecoveryMaterial], + &[], + ) + .await + .map_err(|_e| StorageError::Reading) + } + + pub async fn mpc_context_exists( + &self, + mpc_context_id: &ContextId, + ) -> Result { + self.data_exists( + &RequestId::from(*mpc_context_id), + &[], + &[PrivDataType::ContextInfo], + ) + .await + .map_err(|_e| StorageError::Reading) + } + /// Handle the storage of data after generation, and update the meta store accordingly. /// This methods assumes that `req_id` has already been added to the meta store and will fail if not. /// diff --git a/docs/guides/backup.md b/docs/guides/backup.md index ef3f876a94..2cea80e584 100644 --- a/docs/guides/backup.md +++ b/docs/guides/backup.md @@ -56,13 +56,13 @@ Observe that the `randomness` supplied is used along with entropy of the current IMPORTANT: IT IS NOT POSSIBLE FOR THE CUSTODIAN TO VALIDATE THE AUTHENTICITY OF A REQUEST! HENCE IT IS PARAMOUNT THAT IT IS VALIDATED OUT-OF-BOUNDS, E.G. THROUGH A DIGEST ON A BLOCKCHAIN. Run the CLI tool with the `decrypt` command in order decrypt a backup, and then reencrypt it under a supplied operator keyset. More specifically: ```{bash} -$ cargo run --bin kms-custodian decrypt --seed-phrase --randomness --custodian-role <1-indexed role of the custodian> --recovery-request-path --operator-verf-key --mpc-context-id --output-path +$ cargo run --bin kms-custodian decrypt --seed-phrase --randomness --custodian-role <1-indexed role of the custodian> --recovery-request-path --operator-verf-key --output-path ``` Observe that the `randomness` supplied is used along with entropy of the current system to do re-encryption, and thus the command is *not* idempotent. For example: ```{bash} -$ cargo run --bin kms-custodian decrypt --seed-phrase "stick essence exhaust bunker meat orchard wolf timber tackle gesture video cheap" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-1 +$ cargo run --bin kms-custodian decrypt --seed-phrase "stick essence exhaust bunker meat orchard wolf timber tackle gesture video cheap" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-1 ``` IMPORTANT: IT IS NOT POSSIBLE FOR THE CUSTODIAN TO VALIDATE THE AUTHENTICITY OF A REQUEST! HENCE IT IS PARAMOUNT THAT IT IS VALIDATED OUT-OF-BOUNDS, E.G. THROUGH A DIGEST ON A BLOCKCHAIN. diff --git a/docs/guides/core_client.md b/docs/guides/core_client.md index 187733b506..6568a168f9 100644 --- a/docs/guides/core_client.md +++ b/docs/guides/core_client.md @@ -309,20 +309,20 @@ To further make this a manual test, make sure a [key is generated](#Key-generati IMPORTANT: DO NOT CHANGE THE NAME OF THE VERIFICATION KEY! THAT IS, THE KEY FILE MUST KEEP THE NAME WHEN FETCHING IT FROM THE OPERATOR! Then execute the following command in root of the KMS project, replacing the seed_phrases with the appropriate ones learned from step 1: ```{bash} - cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-1 - cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/2 --operator-verf-key core-client/tests/data/keys/PUB-p2/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-2-1 - cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/3 --operator-verf-key core-client/tests/data/keys/PUB-p3/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-3-1 - cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/4 --operator-verf-key core-client/tests/data/keys/PUB-p4/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-4-1 - - cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-2 - cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/2 --operator-verf-key core-client/tests/data/keys/PUB-p2/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-2-2 - cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/3 --operator-verf-key core-client/tests/data/keys/PUB-p3/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-3-2 - cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/4 --operator-verf-key core-client/tests/data/keys/PUB-p4/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-4-2 - - cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-3 - cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/2 --operator-verf-key core-client/tests/data/keys/PUB-p2/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-2-3 - cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/3 --operator-verf-key core-client/tests/data/keys/PUB-p3/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-3-3 - cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/4 --operator-verf-key core-client/tests/data/keys/PUB-p4/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-4-3 + cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-1 + cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/2 --operator-verf-key core-client/tests/data/keys/PUB-p2/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-2-1 + cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/3 --operator-verf-key core-client/tests/data/keys/PUB-p3/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-3-1 + cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/4 --operator-verf-key core-client/tests/data/keys/PUB-p4/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-4-1 + + cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-2 + cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/2 --operator-verf-key core-client/tests/data/keys/PUB-p2/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-2-2 + cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/3 --operator-verf-key core-client/tests/data/keys/PUB-p3/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-3-2 + cargo run --bin kms-custodian decrypt --seed-phrase "swallow around patrol toe bottom very pulse habit boy couch guide vendor" --randomness 123 --custodian-role 2 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/4 --operator-verf-key core-client/tests/data/keys/PUB-p4/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-4-2 + + cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-3 + cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/2 --operator-verf-key core-client/tests/data/keys/PUB-p2/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-2-3 + cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/3 --operator-verf-key core-client/tests/data/keys/PUB-p3/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-3-3 + cargo run --bin kms-custodian decrypt --seed-phrase "two often advance excite shiver speed vessel melt panther fiction giraffe voyage" --randomness 123 --custodian-role 3 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/4 --operator-verf-key core-client/tests/data/keys/PUB-p4/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-4-3 ``` 5. KMS nodes recover the backup decryption key. Execute the following from `core-client` replacing the ID following `-i` with the appropriate ID learned in step 3. @@ -642,7 +642,7 @@ $ cargo run -- -f destroy-mpc-epoch --epoch-id Date: Tue, 12 May 2026 10:08:15 +0200 Subject: [PATCH 02/29] refactor: more changes to streamline variables --- core-client/src/backup.rs | 71 +++++------ core-client/src/lib.rs | 1 - core/grpc/proto/kms.v1.proto | 11 +- core/service/src/backup/custodian.rs | 29 +---- core/service/src/backup/error.rs | 1 - core/service/src/backup/operator.rs | 50 ++++++-- core/service/src/backup/tests.rs | 36 +----- .../centralized/custodian_backup_tests.rs | 6 +- .../tests/threshold/custodian_backup_tests.rs | 83 +++++++++++-- core/service/src/engine/backup_operator.rs | 117 ++++++------------ core/service/src/engine/context_manager.rs | 3 +- core/service/tests/integration_test.rs | 18 +-- 12 files changed, 209 insertions(+), 217 deletions(-) diff --git a/core-client/src/backup.rs b/core-client/src/backup.rs index c1b59fbe21..7c6c882723 100644 --- a/core-client/src/backup.rs +++ b/core-client/src/backup.rs @@ -10,17 +10,14 @@ use kms_grpc::{ }, kms_service::v1::core_service_endpoint_client::CoreServiceEndpointClient, }; -use kms_lib::{ - backup::{ - custodian::{InternalCustodianRecoveryOutput, InternalCustodianSetupMessage}, - operator::InternalRecoveryRequest, - }, - cryptography::internal_crypto_types::LegacySerialization, +use kms_lib::backup::{ + custodian::{InternalCustodianRecoveryOutput, InternalCustodianSetupMessage}, + operator::InternalRecoveryRequest, }; use tokio::task::JoinSet; use tonic::transport::Channel; -use crate::{CoreClientConfig, CoreConf, s3_operations::fetch_kms_verification_keys}; +use crate::CoreConf; pub(crate) async fn do_get_operator_pub_keys( core_endpoints: &HashMap>, @@ -131,54 +128,42 @@ pub(crate) async fn do_custodian_recovery_init( Ok(res.into_iter().map(|(_, v)| v).collect()) } +/// Send every custodian recovery output to every operator. +/// +/// We no longer carry an `operator_verification_key` hint on the wire or in the on-disk +/// `InternalCustodianRecoveryOutput`. Each operator's `filter_custodian_data` will skip outputs not +/// addressed to it: they fail `validate_signcryption` because the signcryption's `receiver_id` was +/// bound to a specific operator at backup time. Bandwidth is `N × M` outputs (operators × custodians), +/// which is sub-megabyte even at the upper end of typical KMS sizes. pub(crate) async fn do_custodian_backup_recovery( core_endpoints: &HashMap>, - sim_conf: &CoreClientConfig, custodian_context_id: RequestId, custodian_recovery_outputs: Vec, ) -> anyhow::Result<()> { - let pivot_mpc_context_id = custodian_recovery_outputs - .first() - .ok_or_else(|| anyhow::anyhow!("At least one custodian recovery output is required"))? - .mpc_context_id; - if custodian_recovery_outputs - .iter() - .any(|output| output.mpc_context_id != pivot_mpc_context_id) - { - anyhow::bail!("All custodian recovery outputs must have the same MPC context ID"); + if custodian_recovery_outputs.is_empty() { + anyhow::bail!("At least one custodian recovery output is required"); } - // fetch the public keys of operators - let verf_keys = fetch_kms_verification_keys(sim_conf).await?; + let proto_outputs: Vec = custodian_recovery_outputs + .into_iter() + .map(|out| CustodianRecoveryOutput { + backup_output: Some(OperatorBackupOutput { + signcryption: out.signcryption.payload, + pke_type: out.signcryption.pke_type as i32, + signing_type: out.signcryption.signing_type as i32, + }), + custodian_role: out.custodian_role.one_based() as u64, + }) + .collect(); + let mut req_tasks = JoinSet::new(); - // we should change the key in the [core_endpoints] hashmap to be the verification key - for (core_conf, ce) in core_endpoints.iter() { + for ce in core_endpoints.values() { let mut cur_client = ce.clone(); - // We assume the core client endpoints are ordered by the server identity - let mut cur_recoveries = Vec::new(); - for cur_recover in custodian_recovery_outputs.iter() { - // Find the recoveries designated for the correct server - let verf_key = &verf_keys[&core_conf.party_id]; - - if &cur_recover.operator_verification_key == verf_key { - cur_recoveries.push(CustodianRecoveryOutput { - backup_output: Some(OperatorBackupOutput { - signcryption: cur_recover.signcryption.payload.clone(), - pke_type: cur_recover.signcryption.pke_type as i32, - signing_type: cur_recover.signcryption.signing_type as i32, - }), - custodian_role: cur_recover.custodian_role.one_based() as u64, - operator_verification_key: cur_recover - .operator_verification_key - .to_legacy_bytes()?, - mpc_context_id: Some(pivot_mpc_context_id.into()), - }); - } - } + let outputs = proto_outputs.clone(); req_tasks.spawn(async move { cur_client .custodian_backup_recovery(tonic::Request::new(CustodianRecoveryRequest { custodian_context_id: Some(custodian_context_id.into()), - custodian_recovery_outputs: cur_recoveries, + custodian_recovery_outputs: outputs, })) .await }); diff --git a/core-client/src/lib.rs b/core-client/src/lib.rs index fa7645a8b9..ed37d4e41c 100644 --- a/core-client/src/lib.rs +++ b/core-client/src/lib.rs @@ -2218,7 +2218,6 @@ pub async fn execute_cmd( } do_custodian_backup_recovery( &core_endpoints_req, - &cc_conf, *custodian_context_id, custodian_outputs, ) diff --git a/core/grpc/proto/kms.v1.proto b/core/grpc/proto/kms.v1.proto index c9166d1882..307b4c29d9 100644 --- a/core/grpc/proto/kms.v1.proto +++ b/core/grpc/proto/kms.v1.proto @@ -659,13 +659,14 @@ message CustodianRecoveryInitRequest { bool overwrite_ephemeral_key = 1; } -// The data constructed by a single custodian to help a single operator recover their private master decryption key +// The data constructed by a single custodian to help a single operator recover their private master decryption key. +// +// `custodian_role` is kept in the clear here purely as a lookup hint — the custodian role is also part of the `BackupMaterial` +// payload which is what is validated. message CustodianRecoveryOutput { OperatorBackupOutput backup_output = 1; - // The 1-indexed role of the custodian - uint64 custodian_role = 2; // TODO these should likely have been signcrypted - bytes operator_verification_key = 3; - RequestId mpc_context_id = 4; + // The 1-indexed role of the custodian (lookup hint; authenticated copy lives in the signcrypted BackupMaterial) + uint64 custodian_role = 2; } // The recovery request which contains the needed recovery data from all the custodians, diff --git a/core/service/src/backup/custodian.rs b/core/service/src/backup/custodian.rs index adc0c08cb8..698e793ce8 100644 --- a/core/service/src/backup/custodian.rs +++ b/core/service/src/backup/custodian.rs @@ -13,7 +13,7 @@ use hashing::DomainSep; use kms_grpc::kms::v1::{ CustodianContext, CustodianRecoveryOutput, CustodianSetupMessage, OperatorBackupOutput, }; -use kms_grpc::{ContextId, RequestId}; +use kms_grpc::RequestId; use rand::{CryptoRng, Rng}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -37,13 +37,16 @@ pub enum InternalCustodianRecoveryOutputVersioned { } /// This is the message that a custodian sends to an operator after starting recovery. +/// +/// All operator-facing context — operator long-term verification key, custodian role binding, MPC +/// context, custodian context — lives inside the signcrypted `BackupMaterial` payload carried by +/// `signcryption`. The plaintext `custodian_role` here is a lookup hint only: the operator uses it +/// to pick which custodian's verification key to plug into the unsigncryption. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Versionize)] #[versionize(InternalCustodianRecoveryOutputVersioned)] pub struct InternalCustodianRecoveryOutput { pub signcryption: UnifiedSigncryption, pub custodian_role: Role, - pub operator_verification_key: PublicSigKey, - pub mpc_context_id: ContextId, } impl Named for InternalCustodianRecoveryOutput { @@ -59,22 +62,9 @@ impl TryFrom for InternalCustodianRecoveryOutput { "Invalid custodian role in CustodianRecoveryOutput" )); } - // TODO(zama-ai/kms-internal/issues/2836) - // we may change how the verification key is serialized - let verification_key: PublicSigKey = - bc2wrap::deserialize_safe(&value.operator_verification_key).map_err(|e| { - anyhow::anyhow!("Failed to deserialize operator verification key: {}", e) - })?; let backup_output = &value.backup_output.ok_or_else(|| { anyhow::anyhow!("backup output not part of the custodian recovery output") })?; - let mpc_context_id = value - .mpc_context_id - .ok_or_else(|| { - anyhow::anyhow!("MPC context ID not part of the custodian recovery output") - })? - .try_into() - .map_err(|e| anyhow::anyhow!("Failed to parse MPC context ID: {}", e))?; Ok(InternalCustodianRecoveryOutput { signcryption: UnifiedSigncryption::new( backup_output.signcryption.clone(), @@ -82,8 +72,6 @@ impl TryFrom for InternalCustodianRecoveryOutput { backup_output.signing_type().into(), ), custodian_role: Role::indexed_from_one(value.custodian_role as usize), - operator_verification_key: verification_key, - mpc_context_id, }) } } @@ -92,7 +80,6 @@ impl TryFrom for CustodianRecoveryOutput { type Error = anyhow::Error; fn try_from(value: InternalCustodianRecoveryOutput) -> Result { - let verification_key_buf = bc2wrap::serialize(&value.operator_verification_key)?; Ok(CustodianRecoveryOutput { backup_output: Some(OperatorBackupOutput { signcryption: value.signcryption.payload, @@ -100,8 +87,6 @@ impl TryFrom for CustodianRecoveryOutput { signing_type: value.signcryption.signing_type as i32, }), custodian_role: value.custodian_role.one_based() as u64, - operator_verification_key: verification_key_buf, - mpc_context_id: Some(value.mpc_context_id.into()), }) } } @@ -384,8 +369,6 @@ impl Custodian { Ok(InternalCustodianRecoveryOutput { signcryption, custodian_role: self.role, - operator_verification_key: operator_verification_key.clone(), - mpc_context_id: backup_material.mpc_context_id, }) } diff --git a/core/service/src/backup/error.rs b/core/service/src/backup/error.rs index 65bc49df52..6a2537ae8b 100644 --- a/core/service/src/backup/error.rs +++ b/core/service/src/backup/error.rs @@ -14,7 +14,6 @@ pub enum SetupSkipReason { /// Why a single custodian recovery output was skipped during filtering. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RecoverySkipReason { - WrongOperator, InvalidRole, MissingVerificationKey, MissingSigncryption, diff --git a/core/service/src/backup/operator.rs b/core/service/src/backup/operator.rs index 173fbcc5fc..46da08976b 100644 --- a/core/service/src/backup/operator.rs +++ b/core/service/src/backup/operator.rs @@ -255,6 +255,7 @@ impl RecoveryValidationMaterial { commitments: BTreeMap>, custodian_context: InternalCustodianContext, sk: &PrivateSigKey, + mpc_context: ContextId, ) -> anyhow::Result { if custodian_context.custodian_nodes.len() != cts.len() { return Err(anyhow::anyhow!( @@ -276,6 +277,7 @@ impl RecoveryValidationMaterial { cts, commitments, custodian_context, + mpc_context, }; let serialized_payload = bc2wrap::serialize(&payload).map_err(|e| { anyhow_error_and_log(format!("Could not serialize inner recovery request: {e:?}")) @@ -312,6 +314,10 @@ impl RecoveryValidationMaterial { &self.payload.custodian_context } + pub fn mpc_context(&self) -> ContextId { + self.payload.mpc_context + } + /// Validated the signature on the recovery validation material. /// This is useful after deserializing from untrusted storage such as public storage pub fn validate(&self, verf_key: &PublicSigKey) -> bool { @@ -359,6 +365,8 @@ pub struct RecoveryValidationMaterialPayload { pub commitments: BTreeMap>, /// The custodian context used during backup pub custodian_context: InternalCustodianContext, + /// The MPC context used when constructing the backup (i.e. identifying the verification key of the operator) + pub mpc_context: ContextId, } impl Named for RecoveryValidationMaterialPayload { const NAME: &'static str = "backup::RecoveryValidationMaterialPayload"; @@ -370,6 +378,8 @@ fn checked_decryption_deserialize( signcryption: &UnifiedSigncryption, commitment: &[u8], custodian_role: Role, + expected_backup_id: RequestId, + expected_mpc_context_id: ContextId, ) -> Result>, BackupError> { let backup_material: BackupMaterial = unsign_key .unsigncrypt(&DSEP_BACKUP_RECOVERY, signcryption) @@ -394,6 +404,22 @@ fn checked_decryption_deserialize( ); return Err(BackupError::CustodianRecoveryError); } + if backup_material.backup_id != expected_backup_id { + tracing::error!( + "backup_id mismatch in backup material: expected {} but got {}", + expected_backup_id, + backup_material.backup_id + ); + return Err(BackupError::CustodianRecoveryError); + } + if backup_material.mpc_context_id != expected_mpc_context_id { + tracing::error!( + "mpc_context_id mismatch in backup material: expected {} but got {}", + expected_mpc_context_id, + backup_material.mpc_context_id + ); + return Err(BackupError::CustodianRecoveryError); + } // check metadata if !backup_material.matches_expected_metadata( unsign_key.sender_verf_key, @@ -426,10 +452,10 @@ pub enum BackupMaterialVersioned { #[derive(Clone, Debug, Serialize, Deserialize, Versionize)] #[versionize(BackupMaterialVersioned)] pub struct BackupMaterial { - /// The custodian context ID - pub backup_id: RequestId, // TODO should be contextID - /// MPC context ID - pub mpc_context_id: ContextId, // todo ensure validation + /// The custodian context this backup is associated with. + pub backup_id: RequestId, + /// The MPC context this backup was produced under. + pub mpc_context_id: ContextId, // receiver pub custodian_pk: PublicSigKey, pub custodian_role: Role, @@ -666,6 +692,8 @@ impl Operator { ephm_dec_key: &UnifiedPrivateEncKey, // Note that this is the ephemeral decryption key, NOT the actual backup decryption key ephm_enc_key: &UnifiedPublicEncKey, ) -> Result, BackupError> { + let expected_backup_id = recovery_material.custodian_context().context_id; + let expected_mpc_context_id = recovery_material.mpc_context(); // the output is ordered by custodian ID, from 0 to n-1 // first check the signature and decrypt // decrypted_buf[j][i] where j = jth custodian, i = ith block @@ -696,6 +724,8 @@ impl Operator { &custodian_output.signcryption, commitment, custodian_output.custodian_role, + expected_backup_id, + expected_mpc_context_id, ) }) .collect::, _>>()?; @@ -842,6 +872,7 @@ mod tests { use super::*; use crate::{ backup::{custodian::CustodianSetupMessagePayload, operator::RecoveryValidationMaterial}, + consts::DEFAULT_MPC_CONTEXT, cryptography::{ encryption::{Encryption, PkeScheme, PkeSchemeType}, signatures::{SigningSchemeType, gen_sig_keys}, @@ -907,9 +938,14 @@ mod tests { }; let internal_custodian_context = InternalCustodianContext::new(custodian_context, enc_key).unwrap(); - let rvm = - RecoveryValidationMaterial::new(cts, commitments, internal_custodian_context, &sig_key) - .unwrap(); + let rvm = RecoveryValidationMaterial::new( + cts, + commitments, + internal_custodian_context, + &sig_key, + *DEFAULT_MPC_CONTEXT, + ) + .unwrap(); assert!(rvm.validate(&verf_key)); } diff --git a/core/service/src/backup/tests.rs b/core/service/src/backup/tests.rs index 2ac74ba26a..e30c3551b0 100644 --- a/core/service/src/backup/tests.rs +++ b/core/service/src/backup/tests.rs @@ -165,10 +165,8 @@ fn custodian_reencrypt() { .verify_reencrypt( &mut rng, bad_results[0].ct_shares.get(&operator_role).unwrap(), - mpc_context_id, verification_key, &ephemeral_enc_key, - backup_id, ) .unwrap_err(); assert!(matches!(err, BackupError::CustodianRecoveryError)); @@ -186,27 +184,8 @@ fn custodian_reencrypt() { .verify_reencrypt( &mut rng, bad_results[0].ct_shares.get(&operator_role).unwrap(), - mpc_context_id, - verification_key, - &ephemeral_enc_key, - backup_id, - ) - .unwrap_err(); - assert!(matches!(err, BackupError::CustodianRecoveryError)); - } - - // use the wrong backup_id - { - let operator_role = Role::indexed_from_zero(0); - let bad_backup_id = RequestId::from_bytes([7u8; crate::consts::ID_LENGTH]); - let err = custodians[0] - .verify_reencrypt( - &mut rng, - signcrypt_results[0].ct_shares.get(&operator_role).unwrap(), - mpc_context_id, verification_key, &ephemeral_enc_key, - bad_backup_id, ) .unwrap_err(); assert!(matches!(err, BackupError::CustodianRecoveryError)); @@ -219,10 +198,8 @@ fn custodian_reencrypt() { .verify_reencrypt( &mut rng, signcrypt_results[0].ct_shares.get(&operator_role).unwrap(), - mpc_context_id, verification_key, &ephemeral_enc_key, - backup_id, ) .unwrap(); } @@ -252,7 +229,6 @@ fn full_flow( let ops_addresses = operators.keys(); let backups = custodian_recover( &mut rng, - &backup_id, &mnemonics, &payload_for_custodians, custodian_threshold, @@ -304,7 +280,6 @@ fn full_flow_drop_msg() { assert!(mnemonics_dropped.len() > custodian_threshold); let backups = custodian_recover( &mut rng, - &backup_id, &mnemonics_dropped, &payload_for_custodians, custodian_threshold, @@ -385,6 +360,7 @@ fn full_flow_malicious_custodian_init() { &mut rng, &bc2wrap::serialize(&backup_priv_key).unwrap(), backup_id, + *DEFAULT_MPC_CONTEXT, ) .unwrap(); assert!( @@ -424,7 +400,6 @@ fn full_flow_malicious_custodian_second() { .to_string()); let backups = custodian_recover( &mut rng, - &backup_id, &mnemonics_malicious, &payload_for_custodians, custodian_threshold, @@ -465,7 +440,6 @@ fn full_flow_malicious_custodian_second() { .to_string()); let backups = custodian_recover( &mut rng, - &backup_id, &mnemonics_malicious_dropped, &payload_for_custodians, custodian_threshold, @@ -528,7 +502,6 @@ fn full_flow_malicious_operator() { let backups = custodian_recover( &mut rng, - &backup_id, &mnemonics, &payload_for_custodians_malicious, custodian_threshold, @@ -603,6 +576,7 @@ fn operator_handle_init( rng, &bc2wrap::serialize(&backup_dec_key).unwrap(), *backup_id, + *DEFAULT_MPC_CONTEXT, ) .unwrap(); let cur_op_output = signcrypt_result.ct_shares; @@ -657,7 +631,6 @@ type OperatorsMap = BTreeMap< fn custodian_recover( rng: &mut AesRng, - backup_id: &RequestId, mnemonics: &BTreeMap, // keyed by custodian role backups: &CustodianBackupsMap, // Operator role to verf key, ephemeral key and backup ct map custodian_threshold: usize, @@ -671,10 +644,8 @@ fn custodian_recover( match custodian.verify_reencrypt( rng, cur_backup.get(cur_cus_role).unwrap(), - RequestId::from_bytes([7u8; crate::consts::ID_LENGTH]), verification_key, ephemeral_enc_key, - *backup_id, ) { Ok(cur_res) => cur_operator_res.insert(*cur_cus_role, cur_res), Err(_) => { @@ -693,7 +664,7 @@ fn custodian_recover( fn operator_recover( reencryptions: &BTreeMap, BTreeMap>, operators: &OperatorsMap, - backup_id: &RequestId, + _backup_id: &RequestId, ) -> BTreeMap, Vec> { let mut res = BTreeMap::new(); for (cur_op_addr, (cur_op, cur_com, cur_emphemeral_dec, cur_ephemeral_enc)) in operators { @@ -702,7 +673,6 @@ fn operator_recover( match cur_op.verify_and_recover( &reencs_vec, cur_com, - *backup_id, cur_emphemeral_dec, cur_ephemeral_enc, ) { diff --git a/core/service/src/client/tests/centralized/custodian_backup_tests.rs b/core/service/src/client/tests/centralized/custodian_backup_tests.rs index 4f047648e5..b77b42e29e 100644 --- a/core/service/src/client/tests/centralized/custodian_backup_tests.rs +++ b/core/service/src/client/tests/centralized/custodian_backup_tests.rs @@ -261,6 +261,7 @@ async fn decrypt_after_recovery(amount_custodians: usize, threshold: u32) { let cus_rec_req = emulate_custodian( &mut rng, recovery_req_resp, + env.req_new_cus, env.mnemonics.clone(), env.test_path(), ) @@ -356,6 +357,7 @@ async fn decrypt_after_recovery_negative(amount_custodians: usize, threshold: u3 let mut cus_rec_req = emulate_custodian( &mut rng, recovery_req_resp, + env.req_new_cus, env.mnemonics.clone(), env.test_path(), ) @@ -515,10 +517,10 @@ async fn test_mpc_context_backup_central() { async fn emulate_custodian( rng: &mut AesRng, recovery_request: RecoveryRequest, + custodian_context_id: RequestId, mnemonics: Vec, test_path: Option<&Path>, ) -> CustodianRecoveryRequest { - let backup_id = recovery_request.backup_id.clone().unwrap(); let mut cus_outputs = Vec::new(); for (cur_idx, cur_mnemonic) in mnemonics.iter().enumerate() { let custodian: Custodian = @@ -549,7 +551,7 @@ async fn emulate_custodian( cus_outputs.push(cur_out.try_into().unwrap()); } CustodianRecoveryRequest { - custodian_context_id: Some(backup_id.clone()), + custodian_context_id: Some(custodian_context_id.into()), custodian_recovery_outputs: cus_outputs, } } diff --git a/core/service/src/client/tests/threshold/custodian_backup_tests.rs b/core/service/src/client/tests/threshold/custodian_backup_tests.rs index 27226f3323..d5be245626 100644 --- a/core/service/src/client/tests/threshold/custodian_backup_tests.rs +++ b/core/service/src/client/tests/threshold/custodian_backup_tests.rs @@ -125,6 +125,10 @@ impl ThresholdBackupTestEnv { &PRIVATE_STORAGE_PREFIX_THRESHOLD_ALL[0..Self::AMOUNT_PARTIES] } + fn pub_prefixes(&self) -> &[Option] { + &PUBLIC_STORAGE_PREFIX_THRESHOLD_ALL[0..Self::AMOUNT_PARTIES] + } + fn kms_clients(&self) -> &HashMap> { self.kms_clients.as_ref().unwrap() } @@ -273,6 +277,10 @@ async fn backup_after_crs(amount_custodians: usize, threshold: u32) { env.shutdown().await; + // Capture operator verification keys before purging + let operator_verf_keys = operator_verf_key_map(env.test_path(), env.pub_prefixes()).await; + let custodian_context_id = env.req_new_cus; + // Purge the private storage to test the backup recovery purge_priv(env.test_path(), env.priv_prefixes()).await; @@ -285,7 +293,15 @@ async fn backup_after_crs(amount_custodians: usize, threshold: u32) { purge_priv(env.test_path(), env.priv_prefixes()).await; // Execute the backup restoring - run_full_custodian_recovery(&kms_clients, env.mnemonics.clone(), n, None).await; + run_full_custodian_recovery( + &kms_clients, + &operator_verf_keys, + custodian_context_id, + env.mnemonics.clone(), + n, + None, + ) + .await; // Verify CRS metadata was recovered correctly for (i, storage_prefix) in env.priv_prefixes().iter().enumerate() { @@ -354,6 +370,8 @@ async fn decrypt_after_recovery(amount_custodians: usize, threshold: u32) { // Read the private signing keys for reference let sig_keys = read_signing_keys(env.test_path(), env.priv_prefixes()).await; + let operator_verf_keys = operator_verf_key_map(env.test_path(), env.pub_prefixes()).await; + let custodian_context_id = env.req_new_cus; // Purge the private storage to test the backup purge_priv(env.test_path(), env.priv_prefixes()).await; @@ -366,7 +384,15 @@ async fn decrypt_after_recovery(amount_custodians: usize, threshold: u32) { purge_priv(env.test_path(), env.priv_prefixes()).await; // Execute the backup restoring - run_full_custodian_recovery(&kms_clients, env.mnemonics.clone(), n, None).await; + run_full_custodian_recovery( + &kms_clients, + &operator_verf_keys, + custodian_context_id, + env.mnemonics.clone(), + n, + None, + ) + .await; // Check that the key material is back let recovered_keys = read_signing_keys(env.test_path(), env.priv_prefixes()).await; @@ -451,6 +477,8 @@ async fn decrypt_after_recovery_negative(amount_custodians: usize, threshold: u3 // Read the private signing keys for reference let sig_keys = read_signing_keys(env.test_path(), env.priv_prefixes()).await; + let operator_verf_keys = operator_verf_key_map(env.test_path(), env.pub_prefixes()).await; + let custodian_context_id = env.req_new_cus; // Purge the private storage to test the backup purge_priv(env.test_path(), env.priv_prefixes()).await; @@ -465,6 +493,8 @@ async fn decrypt_after_recovery_negative(amount_custodians: usize, threshold: u3 // Execute the backup restoring with corrupted custodian outputs run_full_custodian_recovery( &kms_clients, + &operator_verf_keys, + custodian_context_id, env.mnemonics.clone(), n, Some(corrupt_custodian_outputs), @@ -918,6 +948,8 @@ async fn shutdown_servers_and_client( #[allow(clippy::type_complexity)] async fn run_full_custodian_recovery( kms_clients: &HashMap>, + operator_verf_keys: &HashMap, + custodian_context_id: RequestId, mnemonics: Vec, amount_parties: usize, mutate_outputs: Option)>, @@ -925,7 +957,14 @@ async fn run_full_custodian_recovery( let mut rng = AesRng::seed_from_u64(13); let recovery_req_resp = run_custodian_recovery_init(kms_clients).await; assert_eq!(recovery_req_resp.len(), amount_parties); - let mut cus_out = emulate_custodian(&mut rng, recovery_req_resp, mnemonics).await; + let mut cus_out = emulate_custodian( + &mut rng, + recovery_req_resp, + operator_verf_keys, + custodian_context_id, + mnemonics, + ) + .await; if let Some(mutate) = mutate_outputs { mutate(&mut cus_out); } @@ -956,6 +995,31 @@ async fn read_signing_keys( sig_keys } +#[cfg(feature = "insecure")] +async fn operator_verf_key_map( + test_path: Option<&std::path::Path>, + pub_storage_prefixes: &[Option], +) -> HashMap { + let mut verf_keys = Vec::new(); + for storage_prefix in pub_storage_prefixes.iter() { + let cur_pub_store = + FileStorage::new(test_path, StorageType::PUB, storage_prefix.as_deref()).unwrap(); + let cur_pk: PublicSigKey = read_versioned_at_request_id( + &cur_pub_store, + &SIGNING_KEY_ID, + &PubDataType::VerfKey.to_string(), + ) + .await + .unwrap(); + verf_keys.push(cur_pk); + } + verf_keys + .into_iter() + .enumerate() + .map(|(idx, pk)| ((idx + 1) as u32, pk)) + .collect() +} + // Right now only used by insecure tests #[cfg(feature = "insecure")] async fn run_custodian_recovery_init( @@ -1056,10 +1120,10 @@ async fn run_restore_from_backup( async fn emulate_custodian( rng: &mut AesRng, recovery_requests: Vec<(u32, RecoveryRequest)>, + operator_verf_keys: &HashMap, + custodian_context_id: RequestId, mnemonics: Vec, ) -> HashMap { - let backup_id = recovery_requests[0].1.backup_id.clone().unwrap(); - // Setup a map to contain the results for each operator role let mut outputs_for_operators: HashMap<(u32, Address), Vec> = HashMap::new(); @@ -1068,6 +1132,9 @@ async fn emulate_custodian( let custodian: Custodian = custodian_from_seed_phrase(cur_mnemonic, Role::indexed_from_zero(cur_idx)).unwrap(); for (i, cur_recovery_req) in &recovery_requests { + let cur_verf_key = operator_verf_keys + .get(i) + .expect("operator verification key missing for party"); let cur_cus_reenc = cur_recovery_req.cts.get(&((cur_idx + 1) as u64)).unwrap(); let cur_enc_key = safe_deserialize( std::io::Cursor::new(&cur_recovery_req.ephem_op_enc_key), @@ -1078,12 +1145,10 @@ async fn emulate_custodian( .verify_reencrypt( rng, &cur_cus_reenc.to_owned().try_into().unwrap(), - &cur_verf_key, + cur_verf_key, &cur_enc_key, ) .unwrap(); - let cur_verf_key: PublicSigKey = - bc2wrap::deserialize_safe(&cur_out.operator_verification_key).unwrap(); // Add the result from this custodian to the map of results to the correct operator match outputs_for_operators.entry((*i, cur_verf_key.address())) { std::collections::hash_map::Entry::Occupied(occupied_entry) => { @@ -1103,7 +1168,7 @@ async fn emulate_custodian( ( i, CustodianRecoveryRequest { - custodian_context_id: Some(backup_id.clone()), + custodian_context_id: Some(custodian_context_id.into()), custodian_recovery_outputs: v, }, ), diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index 6836a4f1b2..e111e23abd 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -184,28 +184,18 @@ where )); } - // Observe we have already validated that every mpc context ID is equal, and that there is at least t+1 entries - let pivot_cus_res = *parsed_custodian_rec.keys().next().unwrap(); - for cur_cus_res in parsed_custodian_rec.values() { - if cur_cus_res.mpc_context_id != parsed_custodian_rec[&pivot_cus_res].mpc_context_id { - return Err(anyhow::anyhow!( - "MPC context ID mismatch among recovery outputs" - )); - } - } - - if !parsed_custodian_rec[&pivot_cus_res] - .mpc_context_id - .is_valid() - { + // The MPC context to validate against is taken from the operator-signed `RecoveryValidationMaterial` + // stored at backup time. + let mpc_context_id = recovery_material.mpc_context(); + if !mpc_context_id.is_valid() { return Err(anyhow::anyhow!( - "Invalid MPC context ID in recovery outputs" + "Invalid MPC context ID in recovery validation material" )); } Ok(( custodian_context_id, - parsed_custodian_rec[&pivot_cus_res].mpc_context_id, // We have already validated they are all equal + mpc_context_id, recovery_material, parsed_custodian_rec, )) @@ -415,7 +405,7 @@ where } if !self .crypto_storage - .custodian_context_exists(&mpc_context_id) + .mpc_context_exists(&mpc_context_id) .await .map_err(|e| { MetricedError::new( @@ -610,8 +600,8 @@ where Ok(recovery_material) } -/// Filter and validate the custodian recovery outputs, returning a map from custodian role to recovery output -/// Each output is verified to be correctly signed by the custodian and to be intended for the current operator role. +/// Filter and validate the custodian recovery outputs, returning a map from custodian role to recovery output. +/// Each output is verified to be correctly signcrypted to the current operator. async fn filter_custodian_data( custodian_recovery_outputs: Vec, recovery_material: &RecoveryValidationMaterial, @@ -622,17 +612,6 @@ async fn filter_custodian_data( let mut parsed_custodian_rec: HashMap = HashMap::new(); let mut skip_reasons: Vec = Vec::new(); for cur_recovery_output in &custodian_recovery_outputs { - let current_verf_key: PublicSigKey = - bc2wrap::deserialize_safe(&cur_recovery_output.operator_verification_key)?; - if current_verf_key != *my_verf_key { - tracing::warn!( - "Received recovery output for operator {}, but current server is {}. The output will be ignored.", - current_verf_key.address(), - my_verf_key.address(), - ); - skip_reasons.push(RecoverySkipReason::WrongOperator); - continue; - } if cur_recovery_output.custodian_role == 0 || cur_recovery_output.custodian_role > custodian_recovery_outputs.len() as u64 { @@ -643,9 +622,12 @@ async fn filter_custodian_data( skip_reasons.push(RecoverySkipReason::InvalidRole); continue; } - let cur_verf = match recovery_material.custodian_context().custodian_nodes.get( - &Role::indexed_from_one(cur_recovery_output.custodian_role as usize), - ) { + let role = Role::indexed_from_one(cur_recovery_output.custodian_role as usize); + let cur_verf = match recovery_material + .custodian_context() + .custodian_nodes + .get(&role) + { Some(custodian_setup_msg) => &custodian_setup_msg.public_verf_key, None => { tracing::warn!( @@ -680,34 +662,26 @@ async fn filter_custodian_data( .is_err() { tracing::warn!( - "Could not validate signcryption for custodian role {}", + "Could not validate signcryption for custodian role {} (wrong operator or tampered)", cur_recovery_output.custodian_role ); skip_reasons.push(RecoverySkipReason::InvalidSigncryption); continue; } - match >::try_from( - cur_recovery_output.to_owned(), - ) { - Ok(output) => match parsed_custodian_rec.entry(output.custodian_role) { - std::collections::hash_map::Entry::Occupied(_) => { - tracing::warn!( - "Received multiple recovery outputs for custodian {}. Only the first one will be used.", - current_verf_key.address(), - ); - skip_reasons.push(RecoverySkipReason::DuplicateRole); - } - std::collections::hash_map::Entry::Vacant(vacant_entry) => { - vacant_entry.insert(output); - } - }, - Err(e) => { + let output = InternalCustodianRecoveryOutput { + signcryption: cur_signcryption, + custodian_role: role, + }; + match parsed_custodian_rec.entry(role) { + std::collections::hash_map::Entry::Occupied(_) => { tracing::warn!( - "Failed to parse custodian recovery output for operator role {}: {e}. The output will be ignored.", - current_verf_key.address(), + "Received multiple recovery outputs for custodian role {}. Only the first one will be used.", + role, ); - skip_reasons.push(RecoverySkipReason::ParseError); - continue; + skip_reasons.push(RecoverySkipReason::DuplicateRole); + } + std::collections::hash_map::Entry::Vacant(vacant_entry) => { + vacant_entry.insert(output); } } } @@ -1301,21 +1275,14 @@ mod tests { (rec_material, verf_key, dec_key, enc_key) } - fn dummy_output_for_operator( - custodian_role: u64, - operator_verification_key: PublicSigKey, - ) -> CustodianRecoveryOutput { + fn dummy_output_for_operator(custodian_role: u64) -> CustodianRecoveryOutput { CustodianRecoveryOutput { custodian_role, - // TODO(zama-ai/kms-internal/issues/2836) - // we may change how the verification key is serialized - operator_verification_key: bc2wrap::serialize(&operator_verification_key).unwrap(), backup_output: Some(OperatorBackupOutput { signcryption: vec![1, 2, 3], pke_type: 0, signing_type: 0, }), - mpc_context_id: Some(kms_grpc::RequestId::from_bytes([7u8; 32]).into()), } } @@ -1336,12 +1303,10 @@ mod tests { #[tokio::test] async fn test_filter_custodian_missing_cus_output() { let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let mut outputs = vec![dummy_output_for_operator(1, verf_key.clone())]; + let mut outputs = vec![dummy_output_for_operator(1)]; let cus_2 = CustodianRecoveryOutput { custodian_role: 2, - operator_verification_key: bc2wrap::serialize(&verf_key).unwrap(), backup_output: None, // Missing backup output for custodian role 2 - mpc_context_id: Some(kms_grpc::RequestId::from_bytes([7u8; 32]).into()), }; outputs.push(cus_2); let result = @@ -1357,8 +1322,9 @@ mod tests { #[tokio::test] async fn test_filter_custodian_data_invalid_operator_role() { let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let outputs = vec![dummy_output_for_operator(1, verf_key.clone())]; + let outputs = vec![dummy_output_for_operator(1)]; let (bad_verf_key, _bad_sig_key) = gen_sig_keys(&mut AesRng::seed_from_u64(42)); + let _ = verf_key; let result = filter_custodian_data( outputs, &recovery_material, @@ -1370,8 +1336,8 @@ mod tests { let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( - skipped.contains(&RecoverySkipReason::WrongOperator), - "expected WrongOperator in skip reasons: {skipped:?}" + skipped.contains(&RecoverySkipReason::InvalidSigncryption), + "expected InvalidSigncryption in skip reasons: {skipped:?}" ); } @@ -1379,8 +1345,8 @@ mod tests { async fn test_filter_custodian_data_invalid_custodian_role() { let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); let outputs = vec![ - dummy_output_for_operator(0, verf_key.clone()), // custodian_role == 0 - dummy_output_for_operator(99, verf_key.clone()), // custodian_role out of bounds + dummy_output_for_operator(0), // custodian_role == 0 + dummy_output_for_operator(99), // custodian_role out of bounds ]; let result = filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; @@ -1396,9 +1362,9 @@ mod tests { async fn test_filter_custodian_data_invalid_signature() { let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); let outputs = vec![ - dummy_output_for_operator(1, verf_key.clone()), - dummy_output_for_operator(2, verf_key.clone()), - dummy_output_for_operator(3, verf_key.clone()), + dummy_output_for_operator(1), + dummy_output_for_operator(2), + dummy_output_for_operator(3), ]; let result = filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; @@ -1418,10 +1384,7 @@ mod tests { .custodian_context .custodian_nodes .remove(&Role::indexed_from_one(2)); - let outputs = vec![ - dummy_output_for_operator(1, verf_key.clone()), - dummy_output_for_operator(2, verf_key.clone()), - ]; + let outputs = vec![dummy_output_for_operator(1), dummy_output_for_operator(2)]; let result = filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); diff --git a/core/service/src/engine/context_manager.rs b/core/service/src/engine/context_manager.rs index 3f86434602..70de5a477e 100644 --- a/core/service/src/engine/context_manager.rs +++ b/core/service/src/engine/context_manager.rs @@ -971,6 +971,7 @@ async fn gen_recovery_validation( commitments, custodian_context.to_owned(), sig_key, + mpc_context_id, )?; tracing::info!( "Generated inner recovery request for backup_id/context_id={}", @@ -1785,8 +1786,6 @@ mod tests { let internal_rec_req = InternalRecoveryRequest::new( recovery_material.payload.custodian_context.backup_enc_key, recovery_material.payload.cts, - backup_id, - server_verf_key.clone(), ) .unwrap(); let custodian_id = custodian1.verification_key().verf_key_id(); diff --git a/core/service/tests/integration_test.rs b/core/service/tests/integration_test.rs index 18eecc0e81..b7051e2315 100644 --- a/core/service/tests/integration_test.rs +++ b/core/service/tests/integration_test.rs @@ -787,6 +787,7 @@ mod kms_custodian_binary_tests { &mut rng, &bc2wrap::serialize(&backup_ske).unwrap(), backup_id, + *DEFAULT_MPC_CONTEXT, ) .unwrap(); let ct_map = signcrypt_result.ct_shares; @@ -817,13 +818,8 @@ mod kms_custodian_binary_tests { let ct = ct_map.get(&custodian_role).unwrap(); ciphertexts.insert(custodian_role, ct.to_owned()); } - let recovery_request = InternalRecoveryRequest::new( - ephemeral_pub_key.clone(), - ciphertexts, - backup_id, - verification_key.clone(), - ) - .unwrap(); + let recovery_request = + InternalRecoveryRequest::new(ephemeral_pub_key.clone(), ciphertexts).unwrap(); safe_write_element_versioned(&Path::new(&operator_verf_path), &verification_key) .await .unwrap(); @@ -862,13 +858,7 @@ mod kms_custodian_binary_tests { outputs.push(payload); } operator - .verify_and_recover( - &outputs, - recovery_material, - backup_id, - ephem_dec_key, - ephem_enc_key, - ) + .verify_and_recover(&outputs, recovery_material, ephem_dec_key, ephem_enc_key) .unwrap() } } From c2e1c311f94ad8382797e49303d4bcbf25c2a4de Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 14:07:44 +0200 Subject: [PATCH 03/29] refactor: change to flow --- core/service/src/backup/custodian.rs | 6 +- core/service/src/backup/error.rs | 14 + core/service/src/backup/operator.rs | 297 +++++---- core/service/src/engine/backup_operator.rs | 571 ++++++++++++++---- .../tests/backward_compatibility_kms.rs | 9 +- 5 files changed, 631 insertions(+), 266 deletions(-) diff --git a/core/service/src/backup/custodian.rs b/core/service/src/backup/custodian.rs index 698e793ce8..f1b19bb4fe 100644 --- a/core/service/src/backup/custodian.rs +++ b/core/service/src/backup/custodian.rs @@ -10,10 +10,10 @@ use crate::cryptography::{ use crate::engine::validation::{RequestIdParsingErr, parse_optional_grpc_request_id}; use crate::{consts::SAFE_SER_SIZE_LIMIT, cryptography::signatures::PublicSigKey}; use hashing::DomainSep; +use kms_grpc::RequestId; use kms_grpc::kms::v1::{ CustodianContext, CustodianRecoveryOutput, CustodianSetupMessage, OperatorBackupOutput, }; -use kms_grpc::RequestId; use rand::{CryptoRng, Rng}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -342,13 +342,13 @@ impl Custodian { return Err(BackupError::CustodianRecoveryError); } // check the decrypted result - if !backup_material.matches_expected_metadata( + if let Err(mismatch) = backup_material.check_expected_metadata( &self.signing_key.verf_key(), self.role, &operator_verification_key.verf_key_id(), ) { tracing::error!( - "Backup material did not match expected metadata for operator: {}", + "Backup material did not match expected metadata ({mismatch:?}) for operator: {}", operator_verification_key.address() ); return Err(BackupError::CustodianRecoveryError); diff --git a/core/service/src/backup/error.rs b/core/service/src/backup/error.rs index 6a2537ae8b..3f8b37fc08 100644 --- a/core/service/src/backup/error.rs +++ b/core/service/src/backup/error.rs @@ -12,6 +12,12 @@ pub enum SetupSkipReason { } /// Why a single custodian recovery output was skipped during filtering. +/// +/// `InvalidSigncryption` covers both tampered ciphertexts and outputs addressed to a different +/// operator +/// +/// The `*InPayload` / `*Malformed` / `*Mismatch` / `CommitmentMismatch` variants fire only after a +/// successful unsigncrypt has produced a `BackupMaterial`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RecoverySkipReason { InvalidRole, @@ -20,6 +26,14 @@ pub enum RecoverySkipReason { InvalidSigncryption, ParseError, DuplicateRole, + BackupIdMalformed, + MpcContextIdMalformed, + BackupIdMismatch, + MpcContextIdMismatch, + CustodianRoleMismatchInPayload, + CustodianKeyMismatchInPayload, + OperatorMismatchInPayload, + CommitmentMismatch, } #[derive(Error, Debug)] diff --git a/core/service/src/backup/operator.rs b/core/service/src/backup/operator.rs index 46da08976b..b3e90a1ede 100644 --- a/core/service/src/backup/operator.rs +++ b/core/service/src/backup/operator.rs @@ -3,7 +3,10 @@ use super::{ error::{BackupError, SetupSkipReason}, secretsharing, }; -use crate::backup::custodian::{InternalCustodianContext, InternalCustodianRecoveryOutput}; +use crate::backup::{ + custodian::{InternalCustodianContext, InternalCustodianRecoveryOutput}, + error::RecoverySkipReason, +}; use crate::{ anyhow_error_and_log, consts::SAFE_SER_SIZE_LIMIT, @@ -372,78 +375,6 @@ impl Named for RecoveryValidationMaterialPayload { const NAME: &'static str = "backup::RecoveryValidationMaterialPayload"; } -#[allow(clippy::too_many_arguments)] -fn checked_decryption_deserialize( - unsign_key: &UnifiedUnsigncryptionKey, - signcryption: &UnifiedSigncryption, - commitment: &[u8], - custodian_role: Role, - expected_backup_id: RequestId, - expected_mpc_context_id: ContextId, -) -> Result>, BackupError> { - let backup_material: BackupMaterial = unsign_key - .unsigncrypt(&DSEP_BACKUP_RECOVERY, signcryption) - .map_err(|e| { - BackupError::OperatorError(format!( - "Failed to unsigncrypt backup share for custodian role {custodian_role}: {e}", - )) - })?; - if !backup_material.backup_id.is_valid() { - tracing::error!( - "Invalid backup_id {} in the decrypted backup material for operator with address: {}", - backup_material.backup_id, - backup_material.operator_pk.address() - ); - return Err(BackupError::CustodianRecoveryError); - } - if !backup_material.mpc_context_id.is_valid() { - tracing::error!( - "Invalid MPC context ID {} in the decrypted backup material for operator with address: {}", - backup_material.mpc_context_id, - backup_material.operator_pk.address() - ); - return Err(BackupError::CustodianRecoveryError); - } - if backup_material.backup_id != expected_backup_id { - tracing::error!( - "backup_id mismatch in backup material: expected {} but got {}", - expected_backup_id, - backup_material.backup_id - ); - return Err(BackupError::CustodianRecoveryError); - } - if backup_material.mpc_context_id != expected_mpc_context_id { - tracing::error!( - "mpc_context_id mismatch in backup material: expected {} but got {}", - expected_mpc_context_id, - backup_material.mpc_context_id - ); - return Err(BackupError::CustodianRecoveryError); - } - // check metadata - if !backup_material.matches_expected_metadata( - unsign_key.sender_verf_key, - custodian_role, - unsign_key.receiver_id, - ) { - return Err(BackupError::OperatorError( - "backup metadata check failure".to_string(), - )); - } - - // check commitment - let actual_commitment = - safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) - .map_err(|e| BackupError::OperatorError(e.to_string()))?; - if actual_commitment != commitment { - return Err(BackupError::OperatorError( - "backup commitment check failure".to_string(), - )); - } - - Ok(backup_material.shares) -} - #[derive(Clone, Serialize, Deserialize, VersionsDispatch)] pub enum BackupMaterialVersioned { V0(BackupMaterial), @@ -465,29 +396,31 @@ pub struct BackupMaterial { } impl BackupMaterial { - pub fn matches_expected_metadata( + /// Verify the operator-/custodian-bound metadata fields of a freshly unsigncrypted + /// `BackupMaterial` against the expected routing parameters. + pub fn check_expected_metadata( &self, custodian_verf_key: &PublicSigKey, custodian_role: Role, operator_pk_id: &[u8], - ) -> bool { + ) -> Result<(), RecoverySkipReason> { if self.custodian_role != custodian_role { tracing::error!( "custodian_role mismatch: expected {} but got {}", self.custodian_role, custodian_role ); - return false; + return Err(RecoverySkipReason::CustodianRoleMismatchInPayload); } if &self.custodian_pk != custodian_verf_key { tracing::error!("custodian_pk mismatch"); - return false; + return Err(RecoverySkipReason::CustodianKeyMismatchInPayload); } if self.operator_pk.verf_key_id() != operator_pk_id { tracing::error!("operator_pk_id mismatch"); - return false; + return Err(RecoverySkipReason::OperatorMismatchInPayload); } - true + Ok(()) } } @@ -678,63 +611,176 @@ impl Operator { }) } - /// Operators that does the recovery collects all the materials - /// used during the backup protocol such as shares, keys and signcryptions, - /// and then uses them to verify whether the shares are correct before - /// doing the reconstruction. + /// Validate a single signcrypted custodian recovery output. /// - /// Commitments do not come from the same location as the custodian message - /// so the are a separate input. + /// Runs every check the operator-side recovery path requires: unsigncryption (which also + /// enforces the signcryption's receiver-id binding), `backup_id` / `mpc_context_id` validity + + /// equality against the operator-signed `RecoveryValidationMaterial`, custodian / operator key + /// equality inside the decrypted payload, and the commitment match. Returns the precise + /// `RecoverySkipReason` on the first failure. + pub(crate) fn validate_one_recovery_output( + &self, + output: &InternalCustodianRecoveryOutput, + recovery_material: &RecoveryValidationMaterial, + ephm_dec_key: &UnifiedPrivateEncKey, + ephm_enc_key: &UnifiedPublicEncKey, + ) -> Result { + let (_, custodian_verf_key) = self.custodian_keys.get(&output.custodian_role).ok_or({ + tracing::warn!("missing custodian key for role {}", output.custodian_role); + RecoverySkipReason::MissingVerificationKey + })?; + let operator_id = self.verification_key.verf_key_id(); + let unsign_key = UnifiedUnsigncryptionKey::new( + ephm_dec_key, + ephm_enc_key, + custodian_verf_key, + &operator_id, + ); + let backup_material: BackupMaterial = unsign_key + .unsigncrypt(&DSEP_BACKUP_RECOVERY, &output.signcryption) + .map_err(|e| { + tracing::warn!( + "Could not unsigncrypt backup share for custodian role {} (wrong operator or tampered): {e}", + output.custodian_role + ); + RecoverySkipReason::InvalidSigncryption + })?; + let expected_backup_id: RequestId = recovery_material.custodian_context().context_id; + let expected_mpc_context_id = recovery_material.mpc_context(); + if !backup_material.backup_id.is_valid() { + tracing::warn!( + "BackupMaterial.backup_id {} is malformed for custodian role {}", + backup_material.backup_id, + output.custodian_role + ); + return Err(RecoverySkipReason::BackupIdMalformed); + } + if !backup_material.mpc_context_id.is_valid() { + tracing::warn!( + "BackupMaterial.mpc_context_id {} is malformed for custodian role {}", + backup_material.mpc_context_id, + output.custodian_role + ); + return Err(RecoverySkipReason::MpcContextIdMalformed); + } + if backup_material.backup_id != expected_backup_id { + tracing::warn!( + "BackupMaterial.backup_id mismatch for custodian role {}: expected {} got {}", + output.custodian_role, + expected_backup_id, + backup_material.backup_id + ); + return Err(RecoverySkipReason::BackupIdMismatch); + } + if backup_material.mpc_context_id != expected_mpc_context_id { + tracing::warn!( + "BackupMaterial.mpc_context_id mismatch for custodian role {}: expected {} got {}", + output.custodian_role, + expected_mpc_context_id, + backup_material.mpc_context_id + ); + return Err(RecoverySkipReason::MpcContextIdMismatch); + } + if let Err(mismatch) = backup_material.check_expected_metadata( + custodian_verf_key, + output.custodian_role, + &operator_id, + ) { + tracing::warn!( + "Metadata check ({mismatch:?}) failed for custodian role {}", + output.custodian_role + ); + return Err(mismatch); + } + let actual_commitment = + safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) + .map_err(|e| { + tracing::warn!( + "Could not hash BackupMaterial for commitment check (role {}): {e}", + output.custodian_role + ); + RecoverySkipReason::ParseError + })?; + let expected_commitment = recovery_material.get(&output.custodian_role).map_err(|_| { + tracing::warn!( + "No stored commitment for custodian role {}", + output.custodian_role + ); + RecoverySkipReason::MissingVerificationKey + })?; + if actual_commitment.as_slice() != expected_commitment { + tracing::warn!( + "Commitment mismatch for custodian role {}: BackupMaterial hash does not match the operator-signed commitment", + output.custodian_role + ); + return Err(RecoverySkipReason::CommitmentMismatch); + } + Ok(backup_material) + } + + /// Validate every signcrypted custodian recovery output and reconstruct the operator's secret. pub fn verify_and_recover( &self, custodian_recovery_output: &[InternalCustodianRecoveryOutput], recovery_material: &RecoveryValidationMaterial, - ephm_dec_key: &UnifiedPrivateEncKey, // Note that this is the ephemeral decryption key, NOT the actual backup decryption key + ephm_dec_key: &UnifiedPrivateEncKey, ephm_enc_key: &UnifiedPublicEncKey, ) -> Result, BackupError> { - let expected_backup_id = recovery_material.custodian_context().context_id; - let expected_mpc_context_id = recovery_material.mpc_context(); - // the output is ordered by custodian ID, from 0 to n-1 - // first check the signature and decrypt - // decrypted_buf[j][i] where j = jth custodian, i = ith block - let decrypted_buf = custodian_recovery_output - .iter() - .map(|custodian_output| { - let (_, custodian_verf_key) = self - .custodian_keys - .get(&custodian_output.custodian_role) - .ok_or_else(|| { - BackupError::OperatorError(format!( - "missing custodian key for {}", - custodian_output.custodian_role - )) - })?; - let commitment = recovery_material - .get(&custodian_output.custodian_role) - .map_err(|_| BackupError::OperatorError("missing commitment".to_string()))?; - let operator_id = &self.verification_key.verf_key_id(); - let unsign_key = UnifiedUnsigncryptionKey::new( - ephm_dec_key, - ephm_enc_key, - custodian_verf_key, - operator_id, - ); - checked_decryption_deserialize( - &unsign_key, - &custodian_output.signcryption, - commitment, - custodian_output.custodian_role, - expected_backup_id, - expected_mpc_context_id, - ) - }) - .collect::, _>>()?; + let mut validated: HashMap = HashMap::new(); + let mut skip_reasons: Vec = Vec::new(); + for output in custodian_recovery_output { + match self.validate_one_recovery_output( + output, + recovery_material, + ephm_dec_key, + ephm_enc_key, + ) { + Ok(bm) => match validated.entry(output.custodian_role) { + std::collections::hash_map::Entry::Occupied(_) => { + tracing::warn!( + "Received multiple recovery outputs for custodian role {}. Only the first one will be used.", + output.custodian_role + ); + skip_reasons.push(RecoverySkipReason::DuplicateRole); + } + std::collections::hash_map::Entry::Vacant(v) => { + v.insert(bm); + } + }, + Err(reason) => skip_reasons.push(reason), + } + } + let threshold = recovery_material.custodian_context().threshold as usize; + let required_min = threshold + 1; + if validated.len() < required_min { + let received = validated.len(); + tracing::error!( + received, + threshold, + ?skip_reasons, + "Cannot recover the backup decryption key: not enough valid recovery outputs" + ); + return Err(BackupError::RecoveryThresholdNotMet { + required_min, + received, + threshold, + skipped: skip_reasons, + }); + } + self.recover_from_validated(&validated) + } + + /// Reconstruct the operator's secret from already-validated per-role `BackupMaterial`s. + pub fn recover_from_validated( + &self, + validated: &HashMap, + ) -> Result, BackupError> { + let decrypted_buf: Vec<&Vec>> = + validated.values().map(|bm| &bm.shares).collect(); let num_blocks = if let Some(x) = decrypted_buf.iter().map(|v| v.len()).min() { x } else { - // This is normally impossible to happen because if it did - // then it would mean the validation on expected_shares above failed return Err(BackupError::NoBlocksError); }; @@ -742,7 +788,6 @@ impl Operator { for b in 0..num_blocks { let mut shamir_sharing = ShamirSharings::new(); for blocks in decrypted_buf.iter() { - // we should be able to safely add shares since it checks whether the role is repeated shamir_sharing.add_share(blocks[b]); } all_sharings.push(shamir_sharing); diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index e111e23abd..2256a324ab 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -1,7 +1,8 @@ use crate::backup::custodian::InternalCustodianRecoveryOutput; use crate::backup::error::{BackupError, RecoverySkipReason}; -use crate::backup::operator::DSEP_BACKUP_RECOVERY; +use crate::backup::operator::BackupMaterial; use crate::consts::DEFAULT_EPOCH_ID; +use crate::cryptography::signcryption::UnifiedSigncryption; use crate::engine::base::{CrsGenMetadata, KmsFheKeyHandles, derive_request_id}; use crate::engine::context::ContextInfo; use crate::engine::threshold::service::session::PRSSSetupCombined; @@ -21,7 +22,6 @@ use crate::{ Encryption, PkeScheme, PkeSchemeType, UnifiedPrivateEncKey, UnifiedPublicEncKey, }, signatures::{PrivateSigKey, PublicSigKey}, - signcryption::{UnifiedUnsigncryptionKey, Unsigncrypt}, }, engine::{ base::BaseKmsStruct, threshold::service::ThresholdFheKeys, traits::BackupOperator, @@ -136,10 +136,10 @@ where )) } - /// Validate the recovery request from the custodian, and if valid return the parsed recovery outputs from the custodians along with the recovery material and context ID. - /// Validation ensures that there is a sufficient amount of recovery outputs from the custodians, and that each of them is correctly signed by the custodian and intended for the current operator. + /// Validate the recovery request from the custodian and return the fully-validated, decrypted + /// per-role `BackupMaterial`s. /// - /// Returns a tuple of (custodian_context_id, mpc_context_id, recovery_material, parsed_custodian_rec) + /// Returns (custodian_context_id, mpc_context_id, validated_rec, operator). pub(crate) async fn validate_custodian_backup_recovery_request( &self, ephemeral_dec_key: &UnifiedPrivateEncKey, @@ -148,8 +148,8 @@ where ) -> anyhow::Result<( ContextId, ContextId, - RecoveryValidationMaterial, - HashMap, + HashMap, + Operator, )> { let custodian_context_id = parse_optional_grpc_request_id( &req.custodian_context_id, @@ -163,29 +163,8 @@ where ) .await? }; - let parsed_custodian_rec = { - filter_custodian_data( - req.custodian_recovery_outputs, - &recovery_material, - &self.base_kms.verf_key(), - ephemeral_dec_key, - ephemeral_enc_key, - ) - .await? - }; - // Check that we have enough valid recovery outputs - if parsed_custodian_rec.len() - < (recovery_material.custodian_context().threshold as usize) + 1 - { - return Err(anyhow::anyhow!( - "Only received {} valid recovery outputs, but threshold is {}. Cannot recover the backup decryption key.", - parsed_custodian_rec.len(), - recovery_material.custodian_context().threshold - )); - } - // The MPC context to validate against is taken from the operator-signed `RecoveryValidationMaterial` - // stored at backup time. + // stored at backup time. `filter_custodian_data` enforces the per-share equality. let mpc_context_id = recovery_material.mpc_context(); if !mpc_context_id.is_valid() { return Err(anyhow::anyhow!( @@ -193,11 +172,34 @@ where )); } + let amount_custodians = recovery_material.custodian_context().custodian_nodes.len(); + let operator = Operator::new_for_validating( + recovery_material + .custodian_context() + .custodian_nodes + .values() + .cloned() + .collect_vec(), + (*self.base_kms.verf_key()).clone(), + recovery_material.custodian_context().threshold as usize, + amount_custodians, + )?; + + let validated_rec = filter_custodian_data( + req.custodian_recovery_outputs, + &operator, + &recovery_material, + ephemeral_dec_key, + ephemeral_enc_key, + ) + .await?; + // `filter_custodian_data` already enforces `len() >= threshold + 1` + Ok(( custodian_context_id, mpc_context_id, - recovery_material, - parsed_custodian_rec, + validated_rec, + operator, )) } } @@ -365,7 +367,7 @@ where } }; let inner = request.into_inner(); - let (custodian_context_id, mpc_context_id, recovery_material, parsed_custodian_rec) = self + let (custodian_context_id, mpc_context_id, parsed_custodian_rec, operator) = self .validate_custodian_backup_recovery_request( &ephemeral_dec_key, &ephemeral_enc_key, @@ -432,42 +434,16 @@ where backup_vault.lock().await; match backup_vault.keychain { Some(KeychainProxy::SecretSharing(ref mut keychain)) => { - // Amount of custodians get defined during context creation - let amount_custodians = recovery_material - .payload - .custodian_context - .custodian_nodes - .len(); - let operator = Operator::new_for_validating( - recovery_material.custodian_context().custodian_nodes.values().cloned().collect_vec(), - (*self.base_kms.verf_key()).clone(), - recovery_material.custodian_context().threshold as usize, - amount_custodians, - ).map_err(|e| { - MetricedError::new( - OP_CUSTODIAN_BACKUP_RECOVERY, - None, - anyhow::anyhow!("Failed to create operator for secret sharing based decryption: {e}"), - tonic::Code::Internal, - ) - })?; - let custodian_outputs: Vec = - parsed_custodian_rec.values().cloned().collect(); let serialized_dec_key = operator - .verify_and_recover( - &custodian_outputs, - &recovery_material, - &ephemeral_dec_key, - &ephemeral_enc_key, - ) + .recover_from_validated(&parsed_custodian_rec) .map_err(|e| { MetricedError::new( OP_CUSTODIAN_BACKUP_RECOVERY, None, anyhow::anyhow!( - "Failed to verify the backup decryption request: {e}" + "Failed to reconstruct the backup decryption key: {e}" ), - tonic::Code::Unauthenticated, + tonic::Code::Internal, ) })?; let backup_dec_key: UnifiedPrivateEncKey = safe_deserialize( @@ -600,20 +576,22 @@ where Ok(recovery_material) } -/// Filter and validate the custodian recovery outputs, returning a map from custodian role to recovery output. -/// Each output is verified to be correctly signcrypted to the current operator. +/// Proto-side adapter for the operator-side validator. +/// Validates and unsigncrypts the [`BackupMaterial`] of the custodians. async fn filter_custodian_data( custodian_recovery_outputs: Vec, + operator: &Operator, recovery_material: &RecoveryValidationMaterial, - my_verf_key: &PublicSigKey, ephemeral_dec_key: &UnifiedPrivateEncKey, ephemeral_enc_key: &UnifiedPublicEncKey, -) -> anyhow::Result> { - let mut parsed_custodian_rec: HashMap = HashMap::new(); +) -> anyhow::Result> { + let outputs_len = custodian_recovery_outputs.len(); + let mut parsed_custodian_rec: HashMap = HashMap::new(); let mut skip_reasons: Vec = Vec::new(); + for cur_recovery_output in &custodian_recovery_outputs { if cur_recovery_output.custodian_role == 0 - || cur_recovery_output.custodian_role > custodian_recovery_outputs.len() as u64 + || cur_recovery_output.custodian_role > outputs_len as u64 { tracing::warn!( "Received recovery output with invalid custodian role {}. The output will be ignored.", @@ -623,30 +601,8 @@ async fn filter_custodian_data( continue; } let role = Role::indexed_from_one(cur_recovery_output.custodian_role as usize); - let cur_verf = match recovery_material - .custodian_context() - .custodian_nodes - .get(&role) - { - Some(custodian_setup_msg) => &custodian_setup_msg.public_verf_key, - None => { - tracing::warn!( - "Could not find verification key for custodian role {}", - cur_recovery_output.custodian_role - ); - skip_reasons.push(RecoverySkipReason::MissingVerificationKey); - continue; - } - }; - let verf_key_id = my_verf_key.verf_key_id(); - let unsign_key = UnifiedUnsigncryptionKey::new( - ephemeral_dec_key, - ephemeral_enc_key, - cur_verf, - &verf_key_id, - ); - let cur_signcryption = match &cur_recovery_output.backup_output { + let cur_signcryption: UnifiedSigncryption = match &cur_recovery_output.backup_output { Some(cur_op_out) => cur_op_out.try_into()?, None => { tracing::warn!( @@ -657,32 +613,29 @@ async fn filter_custodian_data( continue; } }; - if unsign_key - .validate_signcryption(&DSEP_BACKUP_RECOVERY, &cur_signcryption) - .is_err() - { - tracing::warn!( - "Could not validate signcryption for custodian role {} (wrong operator or tampered)", - cur_recovery_output.custodian_role - ); - skip_reasons.push(RecoverySkipReason::InvalidSigncryption); - continue; - } - let output = InternalCustodianRecoveryOutput { + let internal = InternalCustodianRecoveryOutput { signcryption: cur_signcryption, custodian_role: role, }; - match parsed_custodian_rec.entry(role) { - std::collections::hash_map::Entry::Occupied(_) => { - tracing::warn!( - "Received multiple recovery outputs for custodian role {}. Only the first one will be used.", - role, - ); - skip_reasons.push(RecoverySkipReason::DuplicateRole); - } - std::collections::hash_map::Entry::Vacant(vacant_entry) => { - vacant_entry.insert(output); - } + + match operator.validate_one_recovery_output( + &internal, + recovery_material, + ephemeral_dec_key, + ephemeral_enc_key, + ) { + Ok(backup_material) => match parsed_custodian_rec.entry(role) { + std::collections::hash_map::Entry::Occupied(_) => { + tracing::warn!( + "Received multiple recovery outputs for custodian role {role}. Only the first one will be used." + ); + skip_reasons.push(RecoverySkipReason::DuplicateRole); + } + std::collections::hash_map::Entry::Vacant(vacant_entry) => { + vacant_entry.insert(backup_material); + } + }, + Err(reason) => skip_reasons.push(reason), } } let threshold = recovery_material.custodian_context().threshold as usize; @@ -1175,7 +1128,9 @@ pub(crate) async fn keychain_initialized( mod tests { use super::*; use crate::backup::error::{BackupError, RecoverySkipReason}; + use crate::backup::operator::{DSEP_BACKUP_COMMITMENT, DSEP_BACKUP_RECOVERY}; use crate::consts::DEFAULT_MPC_CONTEXT; + use crate::engine::base::safe_serialize_hash_element_versioned; use crate::vault::storage::{StorageProxy, ram::RamStorage, tests::TestType}; use crate::{ backup::custodian::{CustodianSetupMessagePayload, HEADER, InternalCustodianContext}, @@ -1300,6 +1255,28 @@ mod tests { } } + /// Build the recovering `Operator` from a `RecoveryValidationMaterial` for tests that call + /// `filter_custodian_data` directly. Mirrors what + /// `validate_custodian_backup_recovery_request` does in production. + fn build_operator_from_recovery_material( + recovery_material: &RecoveryValidationMaterial, + verf_key: &PublicSigKey, + ) -> Operator { + let amount_custodians = recovery_material.custodian_context().custodian_nodes.len(); + Operator::new_for_validating( + recovery_material + .custodian_context() + .custodian_nodes + .values() + .cloned() + .collect_vec(), + verf_key.clone(), + recovery_material.custodian_context().threshold as usize, + amount_custodians, + ) + .expect("operator construction for test") + } + #[tokio::test] async fn test_filter_custodian_missing_cus_output() { let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); @@ -1309,8 +1286,9 @@ mod tests { backup_output: None, // Missing backup output for custodian role 2 }; outputs.push(cus_2); + let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); let result = - filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; + filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( @@ -1321,18 +1299,12 @@ mod tests { #[tokio::test] async fn test_filter_custodian_data_invalid_operator_role() { - let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); + let (recovery_material, _verf_key, dec_key, enc_key) = dummy_recovery_material(1); let outputs = vec![dummy_output_for_operator(1)]; let (bad_verf_key, _bad_sig_key) = gen_sig_keys(&mut AesRng::seed_from_u64(42)); - let _ = verf_key; - let result = filter_custodian_data( - outputs, - &recovery_material, - &bad_verf_key, - &dec_key, - &enc_key, - ) - .await; + let operator = build_operator_from_recovery_material(&recovery_material, &bad_verf_key); + let result = + filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( @@ -1348,8 +1320,9 @@ mod tests { dummy_output_for_operator(0), // custodian_role == 0 dummy_output_for_operator(99), // custodian_role out of bounds ]; + let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); let result = - filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; + filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( @@ -1366,8 +1339,9 @@ mod tests { dummy_output_for_operator(2), dummy_output_for_operator(3), ]; + let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); let result = - filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; + filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( @@ -1378,15 +1352,19 @@ mod tests { #[tokio::test] async fn test_filter_custodian_data_missing_verification_key() { - let (mut recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - recovery_material - .payload - .custodian_context - .custodian_nodes - .remove(&Role::indexed_from_one(2)); - let outputs = vec![dummy_output_for_operator(1), dummy_output_for_operator(2)]; + // The fixture has 3 custodians (roles 1..=3). Submit four outputs so role 4 passes the + // role-range check, then `validate_one_recovery_output` looks role 4 up in the operator's + // `custodian_keys` map, doesn't find it, and skips with `MissingVerificationKey`. + let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); + let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); + let outputs = vec![ + dummy_output_for_operator(1), + dummy_output_for_operator(2), + dummy_output_for_operator(3), + dummy_output_for_operator(4), + ]; let result = - filter_custodian_data(outputs, &recovery_material, &verf_key, &dec_key, &enc_key).await; + filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( @@ -1394,6 +1372,331 @@ mod tests { "expected MissingVerificationKey in skip reasons: {skipped:?}" ); } + + /// Granular post-unsigncrypt fixture. + struct GranularFixture { + operator_verf_key: PublicSigKey, + operator_verf_key_id: Vec, + ephem_dec_key: UnifiedPrivateEncKey, + ephem_enc_key: UnifiedPublicEncKey, + custodian_context: crate::backup::custodian::InternalCustodianContext, + custodian_sig_keys: BTreeMap, + operator_sig_key: crate::cryptography::signatures::PrivateSigKey, + backup_id: RequestId, + mpc_context_id: ContextId, + } + + impl GranularFixture { + fn build() -> Self { + use crate::backup::custodian::{HEADER, InternalCustodianContext}; + use crate::cryptography::signatures::gen_sig_keys; + use std::time::{SystemTime, UNIX_EPOCH}; + let mut rng = AesRng::seed_from_u64(11); + let (operator_verf_key, operator_sig_key) = gen_sig_keys(&mut rng); + let mut enc = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (ephem_dec_key, ephem_enc_key) = enc.keygen().unwrap(); + + let mut custodian_sig_keys: BTreeMap = BTreeMap::new(); + let mut setup_msgs = Vec::new(); + for i in 1..=3 { + let (cus_verf, cus_sig) = gen_sig_keys(&mut rng); + custodian_sig_keys.insert(Role::indexed_from_one(i), cus_sig); + let mut cus_enc = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_cus_dec, cus_enc_pk) = cus_enc.keygen().unwrap(); + let payload = CustodianSetupMessagePayload { + header: HEADER.to_string(), + random_value: [4_u8; 32], + timestamp: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs(), + public_enc_key: cus_enc_pk, + verification_key: cus_verf, + }; + let mut payload_serial = Vec::new(); + safe_serialize(&payload, &mut payload_serial, SAFE_SER_SIZE_LIMIT).unwrap(); + setup_msgs.push(CustodianSetupMessage { + custodian_role: i as u64, + name: format!("Custodian-{i}"), + payload: payload_serial, + }); + } + let backup_id = derive_request_id("granular_test").unwrap(); + let mpc_context_id = *DEFAULT_MPC_CONTEXT; + // dummy backup_enc_key for the context; unused by these tests + let (_dec, dummy_enc) = Encryption::new(PkeSchemeType::MlKem512, &mut rng) + .keygen() + .unwrap(); + let custodian_context_proto = CustodianContext { + custodian_nodes: setup_msgs, + custodian_context_id: Some(backup_id.into()), + threshold: 1, + }; + let custodian_context = + InternalCustodianContext::new(custodian_context_proto, dummy_enc).unwrap(); + let operator_verf_key_id = operator_verf_key.verf_key_id(); + Self { + operator_verf_key, + operator_verf_key_id, + ephem_dec_key, + ephem_enc_key, + custodian_context, + custodian_sig_keys, + operator_sig_key, + backup_id, + mpc_context_id, + } + } + + /// Build a `BackupMaterial` that would normally be authentic for the given role, then let + /// the test tamper it before signcryption. Returns (signcrypted output proto, the commitment + /// over the *tampered* material, the commitment over the *expected* material). + fn build_share( + &self, + role: Role, + tamper: impl FnOnce(&mut BackupMaterial), + ) -> (CustodianRecoveryOutput, Vec) { + use crate::cryptography::signcryption::{Signcrypt, UnifiedSigncryptionKey}; + let mut rng = AesRng::seed_from_u64(role.one_based() as u64 * 7 + 100); + let custodian_setup = self + .custodian_context + .custodian_nodes + .get(&role) + .expect("role in fixture"); + let mut bm = BackupMaterial { + backup_id: self.backup_id, + mpc_context_id: self.mpc_context_id, + custodian_pk: custodian_setup.public_verf_key.clone(), + custodian_role: role, + operator_pk: self.operator_verf_key.clone(), + shares: Vec::new(), + }; + tamper(&mut bm); + let custodian_sig = self + .custodian_sig_keys + .get(&role) + .expect("custodian sig key"); + let sc_key = UnifiedSigncryptionKey::new( + custodian_sig, + &self.ephem_enc_key, + &self.operator_verf_key_id, + ); + let signcryption = sc_key + .signcrypt(&mut rng, &DSEP_BACKUP_RECOVERY, &bm) + .expect("signcrypt"); + let commitment = + safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &bm).unwrap(); + let output = CustodianRecoveryOutput { + custodian_role: role.one_based() as u64, + backup_output: Some(OperatorBackupOutput { + signcryption: signcryption.payload, + pke_type: signcryption.pke_type as i32, + signing_type: signcryption.signing_type as i32, + }), + }; + (output, commitment) + } + + /// Build a `RecoveryValidationMaterial` containing `commitments`, signed by the operator. + fn make_recovery_material( + &self, + commitments: BTreeMap>, + ) -> RecoveryValidationMaterial { + // The `cts` field on the recovery material isn't read by `filter_custodian_data`; pass + // any well-formed placeholders matching the commitment role set. + let mut cts = BTreeMap::new(); + for role in commitments.keys() { + cts.insert( + *role, + InnerOperatorBackupOutput { + signcryption: UnifiedSigncryption { + payload: vec![1, 2, 3], + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }, + }, + ); + } + RecoveryValidationMaterial::new( + cts, + commitments, + self.custodian_context.clone(), + &self.operator_sig_key, + self.mpc_context_id, + ) + .unwrap() + } + } + + async fn run_single_share_filter( + fx: &GranularFixture, + output: CustodianRecoveryOutput, + commitments: BTreeMap>, + ) -> Vec { + let recovery_material = fx.make_recovery_material(commitments); + let operator = + build_operator_from_recovery_material(&recovery_material, &fx.operator_verf_key); + let result = filter_custodian_data( + vec![output], + &operator, + &recovery_material, + &fx.ephem_dec_key, + &fx.ephem_enc_key, + ) + .await; + let (_received, skipped) = expect_threshold_not_met(result.unwrap_err()); + skipped + } + + #[tokio::test] + async fn test_filter_skips_backup_id_malformed() { + // An all-zero `RequestId` fails `is_valid()` before the equality check, so the malformed + // branch fires (not `BackupIdMismatch`). + let fx = GranularFixture::build(); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.backup_id = RequestId::from_bytes([0u8; 32]); + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::BackupIdMalformed), + "expected BackupIdMalformed in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_mpc_context_id_malformed() { + let fx = GranularFixture::build(); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.mpc_context_id = ContextId::from_bytes([0u8; 32]); + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::MpcContextIdMalformed), + "expected MpcContextIdMalformed in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_backup_id_mismatch() { + let fx = GranularFixture::build(); + let other_id = derive_request_id("other_backup").unwrap(); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.backup_id = other_id; + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::BackupIdMismatch), + "expected BackupIdMismatch in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_mpc_context_id_mismatch() { + let fx = GranularFixture::build(); + let other_mpc = ContextId::from_bytes([0x77_u8; 32]); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.mpc_context_id = other_mpc; + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::MpcContextIdMismatch), + "expected MpcContextIdMismatch in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_custodian_role_mismatch_in_payload() { + // Routing role 1, but the payload claims role 2. The custodian-1 signature is valid; the + // operator's metadata check catches the inconsistency. + let fx = GranularFixture::build(); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.custodian_role = Role::indexed_from_one(2); + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::CustodianRoleMismatchInPayload), + "expected CustodianRoleMismatchInPayload in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_custodian_key_mismatch_in_payload() { + // Same role on the wire, but the payload's `custodian_pk` is some unrelated key. + let fx = GranularFixture::build(); + let (rogue_pk, _rogue_sk) = + crate::cryptography::signatures::gen_sig_keys(&mut AesRng::seed_from_u64(999)); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.custodian_pk = rogue_pk; + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::CustodianKeyMismatchInPayload), + "expected CustodianKeyMismatchInPayload in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_operator_mismatch_in_payload() { + // The payload's `operator_pk` doesn't match this operator. Defence-in-depth — the + // signcryption's receiver id check would normally have caught this upstream; here we + // construct it by hand to confirm the post-decrypt check still fires. + let fx = GranularFixture::build(); + let (rogue_pk, _rogue_sk) = + crate::cryptography::signatures::gen_sig_keys(&mut AesRng::seed_from_u64(1234)); + let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { + bm.operator_pk = rogue_pk; + }); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), commitment); + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::OperatorMismatchInPayload), + "expected OperatorMismatchInPayload in {skipped:?}" + ); + } + + #[tokio::test] + async fn test_filter_skips_commitment_mismatch() { + // The share itself is internally consistent, but the operator-signed recovery material + // stores a different commitment for that role. + let fx = GranularFixture::build(); + let (output, _real_commitment) = fx.build_share(Role::indexed_from_one(1), |_bm| {}); + let mut commitments = BTreeMap::new(); + commitments.insert(Role::indexed_from_one(1), vec![0xAB_u8; 32]); // wrong commitment + commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); + commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); + let skipped = run_single_share_filter(&fx, output, commitments).await; + assert!( + skipped.contains(&RecoverySkipReason::CommitmentMismatch), + "expected CommitmentMismatch in {skipped:?}" + ); + } #[tokio::test] async fn test_update_backup_vault() { let mut priv_storage = RamStorage::new(); diff --git a/core/service/tests/backward_compatibility_kms.rs b/core/service/tests/backward_compatibility_kms.rs index 6c011f539e..941b5de067 100644 --- a/core/service/tests/backward_compatibility_kms.rs +++ b/core/service/tests/backward_compatibility_kms.rs @@ -845,6 +845,7 @@ fn test_recovery_material( let (custodian_pk, _) = gen_sig_keys(&mut rng); let backup_material = BackupMaterial { backup_id, + mpc_context_id: kms_grpc::identifiers::ContextId::from_bytes([9u8; 32]), custodian_pk, custodian_role: cus_role, operator_pk: operator_pk.clone(), @@ -910,7 +911,9 @@ fn test_internal_recovery_request( }; cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); } - let new_versionized = InternalRecoveryRequest::new(enc_key, cts, backup_id, verf_key).unwrap(); + let _ = backup_id; + let _ = verf_key; + let new_versionized = InternalRecoveryRequest::new(enc_key, cts).unwrap(); if original_versionized != new_versionized { Err(test.failure( @@ -989,11 +992,10 @@ fn test_internal_custodian_recovery_output( signing_type: SigningSchemeType::Ecdsa256k1, }; + let _ = operator_verification_key; let new_versionized = InternalCustodianRecoveryOutput { signcryption, custodian_role: Role::indexed_from_one(2), - operator_verification_key, - mpc_context_id: kms_grpc::RequestId::from_bytes([7u8; 32]), }; if original_versionized != new_versionized { @@ -1213,6 +1215,7 @@ fn test_operator_backup_output( &mut rng, &test.plaintext, RequestId::from_bytes(test.backup_id), + kms_grpc::identifiers::ContextId::from_bytes([9u8; 32]), ) .unwrap(); From ff7744d7ab96a3963cc58c44525482a3cfd9222a Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 14:30:14 +0200 Subject: [PATCH 04/29] test: removed unneeded tests --- core/service/src/engine/backup_operator.rs | 474 ++++----------------- 1 file changed, 83 insertions(+), 391 deletions(-) diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index 2256a324ab..3b0801c7d3 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -1277,77 +1277,94 @@ mod tests { .expect("operator construction for test") } - #[tokio::test] - async fn test_filter_custodian_missing_cus_output() { - let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let mut outputs = vec![dummy_output_for_operator(1)]; - let cus_2 = CustodianRecoveryOutput { - custodian_role: 2, - backup_output: None, // Missing backup output for custodian role 2 - }; - outputs.push(cus_2); - let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); + async fn run_filter_expect_skip( + outputs: Vec, + recovery_material: &RecoveryValidationMaterial, + verf_key: &PublicSigKey, + dec_key: &UnifiedPrivateEncKey, + enc_key: &UnifiedPublicEncKey, + expected: RecoverySkipReason, + ) { + let operator = build_operator_from_recovery_material(recovery_material, verf_key); let result = - filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; + filter_custodian_data(outputs, &operator, recovery_material, dec_key, enc_key).await; let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); assert_eq!(received, 0); assert!( - skipped.contains(&RecoverySkipReason::MissingSigncryption), - "expected MissingSigncryption in skip reasons: {skipped:?}" + skipped.contains(&expected), + "expected {expected:?} in skip reasons: {skipped:?}" ); } + #[tokio::test] + async fn test_filter_custodian_missing_cus_output() { + let (rec, verf_key, dec_key, enc_key) = dummy_recovery_material(1); + let outputs = vec![ + dummy_output_for_operator(1), + CustodianRecoveryOutput { + custodian_role: 2, + backup_output: None, + }, + ]; + run_filter_expect_skip( + outputs, + &rec, + &verf_key, + &dec_key, + &enc_key, + RecoverySkipReason::MissingSigncryption, + ) + .await; + } + #[tokio::test] async fn test_filter_custodian_data_invalid_operator_role() { - let (recovery_material, _verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let outputs = vec![dummy_output_for_operator(1)]; + let (rec, _verf_key, dec_key, enc_key) = dummy_recovery_material(1); let (bad_verf_key, _bad_sig_key) = gen_sig_keys(&mut AesRng::seed_from_u64(42)); - let operator = build_operator_from_recovery_material(&recovery_material, &bad_verf_key); - let result = - filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; - let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); - assert_eq!(received, 0); - assert!( - skipped.contains(&RecoverySkipReason::InvalidSigncryption), - "expected InvalidSigncryption in skip reasons: {skipped:?}" - ); + run_filter_expect_skip( + vec![dummy_output_for_operator(1)], + &rec, + &bad_verf_key, + &dec_key, + &enc_key, + RecoverySkipReason::InvalidSigncryption, + ) + .await; } #[tokio::test] async fn test_filter_custodian_data_invalid_custodian_role() { - let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let outputs = vec![ - dummy_output_for_operator(0), // custodian_role == 0 - dummy_output_for_operator(99), // custodian_role out of bounds - ]; - let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); - let result = - filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; - let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); - assert_eq!(received, 0); - assert!( - skipped.contains(&RecoverySkipReason::InvalidRole), - "expected InvalidRole in skip reasons: {skipped:?}" - ); + let (rec, verf_key, dec_key, enc_key) = dummy_recovery_material(1); + run_filter_expect_skip( + vec![ + dummy_output_for_operator(0), // custodian_role == 0 + dummy_output_for_operator(99), // custodian_role out of bounds + ], + &rec, + &verf_key, + &dec_key, + &enc_key, + RecoverySkipReason::InvalidRole, + ) + .await; } #[tokio::test] async fn test_filter_custodian_data_invalid_signature() { - let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let outputs = vec![ - dummy_output_for_operator(1), - dummy_output_for_operator(2), - dummy_output_for_operator(3), - ]; - let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); - let result = - filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; - let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); - assert_eq!(received, 0); - assert!( - skipped.contains(&RecoverySkipReason::InvalidSigncryption), - "expected InvalidSigncryption in skip reasons: {skipped:?}" - ); + let (rec, verf_key, dec_key, enc_key) = dummy_recovery_material(1); + run_filter_expect_skip( + vec![ + dummy_output_for_operator(1), + dummy_output_for_operator(2), + dummy_output_for_operator(3), + ], + &rec, + &verf_key, + &dec_key, + &enc_key, + RecoverySkipReason::InvalidSigncryption, + ) + .await; } #[tokio::test] @@ -1355,348 +1372,23 @@ mod tests { // The fixture has 3 custodians (roles 1..=3). Submit four outputs so role 4 passes the // role-range check, then `validate_one_recovery_output` looks role 4 up in the operator's // `custodian_keys` map, doesn't find it, and skips with `MissingVerificationKey`. - let (recovery_material, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - let operator = build_operator_from_recovery_material(&recovery_material, &verf_key); - let outputs = vec![ - dummy_output_for_operator(1), - dummy_output_for_operator(2), - dummy_output_for_operator(3), - dummy_output_for_operator(4), - ]; - let result = - filter_custodian_data(outputs, &operator, &recovery_material, &dec_key, &enc_key).await; - let (received, skipped) = expect_threshold_not_met(result.unwrap_err()); - assert_eq!(received, 0); - assert!( - skipped.contains(&RecoverySkipReason::MissingVerificationKey), - "expected MissingVerificationKey in skip reasons: {skipped:?}" - ); - } - - /// Granular post-unsigncrypt fixture. - struct GranularFixture { - operator_verf_key: PublicSigKey, - operator_verf_key_id: Vec, - ephem_dec_key: UnifiedPrivateEncKey, - ephem_enc_key: UnifiedPublicEncKey, - custodian_context: crate::backup::custodian::InternalCustodianContext, - custodian_sig_keys: BTreeMap, - operator_sig_key: crate::cryptography::signatures::PrivateSigKey, - backup_id: RequestId, - mpc_context_id: ContextId, - } - - impl GranularFixture { - fn build() -> Self { - use crate::backup::custodian::{HEADER, InternalCustodianContext}; - use crate::cryptography::signatures::gen_sig_keys; - use std::time::{SystemTime, UNIX_EPOCH}; - let mut rng = AesRng::seed_from_u64(11); - let (operator_verf_key, operator_sig_key) = gen_sig_keys(&mut rng); - let mut enc = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (ephem_dec_key, ephem_enc_key) = enc.keygen().unwrap(); - - let mut custodian_sig_keys: BTreeMap = BTreeMap::new(); - let mut setup_msgs = Vec::new(); - for i in 1..=3 { - let (cus_verf, cus_sig) = gen_sig_keys(&mut rng); - custodian_sig_keys.insert(Role::indexed_from_one(i), cus_sig); - let mut cus_enc = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (_cus_dec, cus_enc_pk) = cus_enc.keygen().unwrap(); - let payload = CustodianSetupMessagePayload { - header: HEADER.to_string(), - random_value: [4_u8; 32], - timestamp: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs(), - public_enc_key: cus_enc_pk, - verification_key: cus_verf, - }; - let mut payload_serial = Vec::new(); - safe_serialize(&payload, &mut payload_serial, SAFE_SER_SIZE_LIMIT).unwrap(); - setup_msgs.push(CustodianSetupMessage { - custodian_role: i as u64, - name: format!("Custodian-{i}"), - payload: payload_serial, - }); - } - let backup_id = derive_request_id("granular_test").unwrap(); - let mpc_context_id = *DEFAULT_MPC_CONTEXT; - // dummy backup_enc_key for the context; unused by these tests - let (_dec, dummy_enc) = Encryption::new(PkeSchemeType::MlKem512, &mut rng) - .keygen() - .unwrap(); - let custodian_context_proto = CustodianContext { - custodian_nodes: setup_msgs, - custodian_context_id: Some(backup_id.into()), - threshold: 1, - }; - let custodian_context = - InternalCustodianContext::new(custodian_context_proto, dummy_enc).unwrap(); - let operator_verf_key_id = operator_verf_key.verf_key_id(); - Self { - operator_verf_key, - operator_verf_key_id, - ephem_dec_key, - ephem_enc_key, - custodian_context, - custodian_sig_keys, - operator_sig_key, - backup_id, - mpc_context_id, - } - } - - /// Build a `BackupMaterial` that would normally be authentic for the given role, then let - /// the test tamper it before signcryption. Returns (signcrypted output proto, the commitment - /// over the *tampered* material, the commitment over the *expected* material). - fn build_share( - &self, - role: Role, - tamper: impl FnOnce(&mut BackupMaterial), - ) -> (CustodianRecoveryOutput, Vec) { - use crate::cryptography::signcryption::{Signcrypt, UnifiedSigncryptionKey}; - let mut rng = AesRng::seed_from_u64(role.one_based() as u64 * 7 + 100); - let custodian_setup = self - .custodian_context - .custodian_nodes - .get(&role) - .expect("role in fixture"); - let mut bm = BackupMaterial { - backup_id: self.backup_id, - mpc_context_id: self.mpc_context_id, - custodian_pk: custodian_setup.public_verf_key.clone(), - custodian_role: role, - operator_pk: self.operator_verf_key.clone(), - shares: Vec::new(), - }; - tamper(&mut bm); - let custodian_sig = self - .custodian_sig_keys - .get(&role) - .expect("custodian sig key"); - let sc_key = UnifiedSigncryptionKey::new( - custodian_sig, - &self.ephem_enc_key, - &self.operator_verf_key_id, - ); - let signcryption = sc_key - .signcrypt(&mut rng, &DSEP_BACKUP_RECOVERY, &bm) - .expect("signcrypt"); - let commitment = - safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &bm).unwrap(); - let output = CustodianRecoveryOutput { - custodian_role: role.one_based() as u64, - backup_output: Some(OperatorBackupOutput { - signcryption: signcryption.payload, - pke_type: signcryption.pke_type as i32, - signing_type: signcryption.signing_type as i32, - }), - }; - (output, commitment) - } - - /// Build a `RecoveryValidationMaterial` containing `commitments`, signed by the operator. - fn make_recovery_material( - &self, - commitments: BTreeMap>, - ) -> RecoveryValidationMaterial { - // The `cts` field on the recovery material isn't read by `filter_custodian_data`; pass - // any well-formed placeholders matching the commitment role set. - let mut cts = BTreeMap::new(); - for role in commitments.keys() { - cts.insert( - *role, - InnerOperatorBackupOutput { - signcryption: UnifiedSigncryption { - payload: vec![1, 2, 3], - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }, - }, - ); - } - RecoveryValidationMaterial::new( - cts, - commitments, - self.custodian_context.clone(), - &self.operator_sig_key, - self.mpc_context_id, - ) - .unwrap() - } - } - - async fn run_single_share_filter( - fx: &GranularFixture, - output: CustodianRecoveryOutput, - commitments: BTreeMap>, - ) -> Vec { - let recovery_material = fx.make_recovery_material(commitments); - let operator = - build_operator_from_recovery_material(&recovery_material, &fx.operator_verf_key); - let result = filter_custodian_data( - vec![output], - &operator, - &recovery_material, - &fx.ephem_dec_key, - &fx.ephem_enc_key, + let (rec, verf_key, dec_key, enc_key) = dummy_recovery_material(1); + run_filter_expect_skip( + vec![ + dummy_output_for_operator(1), + dummy_output_for_operator(2), + dummy_output_for_operator(3), + dummy_output_for_operator(4), + ], + &rec, + &verf_key, + &dec_key, + &enc_key, + RecoverySkipReason::MissingVerificationKey, ) .await; - let (_received, skipped) = expect_threshold_not_met(result.unwrap_err()); - skipped - } - - #[tokio::test] - async fn test_filter_skips_backup_id_malformed() { - // An all-zero `RequestId` fails `is_valid()` before the equality check, so the malformed - // branch fires (not `BackupIdMismatch`). - let fx = GranularFixture::build(); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.backup_id = RequestId::from_bytes([0u8; 32]); - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::BackupIdMalformed), - "expected BackupIdMalformed in {skipped:?}" - ); } - #[tokio::test] - async fn test_filter_skips_mpc_context_id_malformed() { - let fx = GranularFixture::build(); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.mpc_context_id = ContextId::from_bytes([0u8; 32]); - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::MpcContextIdMalformed), - "expected MpcContextIdMalformed in {skipped:?}" - ); - } - - #[tokio::test] - async fn test_filter_skips_backup_id_mismatch() { - let fx = GranularFixture::build(); - let other_id = derive_request_id("other_backup").unwrap(); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.backup_id = other_id; - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::BackupIdMismatch), - "expected BackupIdMismatch in {skipped:?}" - ); - } - - #[tokio::test] - async fn test_filter_skips_mpc_context_id_mismatch() { - let fx = GranularFixture::build(); - let other_mpc = ContextId::from_bytes([0x77_u8; 32]); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.mpc_context_id = other_mpc; - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::MpcContextIdMismatch), - "expected MpcContextIdMismatch in {skipped:?}" - ); - } - - #[tokio::test] - async fn test_filter_skips_custodian_role_mismatch_in_payload() { - // Routing role 1, but the payload claims role 2. The custodian-1 signature is valid; the - // operator's metadata check catches the inconsistency. - let fx = GranularFixture::build(); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.custodian_role = Role::indexed_from_one(2); - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::CustodianRoleMismatchInPayload), - "expected CustodianRoleMismatchInPayload in {skipped:?}" - ); - } - - #[tokio::test] - async fn test_filter_skips_custodian_key_mismatch_in_payload() { - // Same role on the wire, but the payload's `custodian_pk` is some unrelated key. - let fx = GranularFixture::build(); - let (rogue_pk, _rogue_sk) = - crate::cryptography::signatures::gen_sig_keys(&mut AesRng::seed_from_u64(999)); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.custodian_pk = rogue_pk; - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::CustodianKeyMismatchInPayload), - "expected CustodianKeyMismatchInPayload in {skipped:?}" - ); - } - - #[tokio::test] - async fn test_filter_skips_operator_mismatch_in_payload() { - // The payload's `operator_pk` doesn't match this operator. Defence-in-depth — the - // signcryption's receiver id check would normally have caught this upstream; here we - // construct it by hand to confirm the post-decrypt check still fires. - let fx = GranularFixture::build(); - let (rogue_pk, _rogue_sk) = - crate::cryptography::signatures::gen_sig_keys(&mut AesRng::seed_from_u64(1234)); - let (output, commitment) = fx.build_share(Role::indexed_from_one(1), |bm| { - bm.operator_pk = rogue_pk; - }); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), commitment); - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::OperatorMismatchInPayload), - "expected OperatorMismatchInPayload in {skipped:?}" - ); - } - - #[tokio::test] - async fn test_filter_skips_commitment_mismatch() { - // The share itself is internally consistent, but the operator-signed recovery material - // stores a different commitment for that role. - let fx = GranularFixture::build(); - let (output, _real_commitment) = fx.build_share(Role::indexed_from_one(1), |_bm| {}); - let mut commitments = BTreeMap::new(); - commitments.insert(Role::indexed_from_one(1), vec![0xAB_u8; 32]); // wrong commitment - commitments.insert(Role::indexed_from_one(2), vec![0_u8; 32]); - commitments.insert(Role::indexed_from_one(3), vec![0_u8; 32]); - let skipped = run_single_share_filter(&fx, output, commitments).await; - assert!( - skipped.contains(&RecoverySkipReason::CommitmentMismatch), - "expected CommitmentMismatch in {skipped:?}" - ); - } #[tokio::test] async fn test_update_backup_vault() { let mut priv_storage = RamStorage::new(); From bf50d1e346fb40fa54a12b8910292b3b05b16291 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 15:29:15 +0200 Subject: [PATCH 05/29] chore: handled small claude review findings --- core-client/src/s3_operations.rs | 6 ++ core/service/src/backup/tests.rs | 11 ++-- core/service/src/engine/backup_operator.rs | 66 ++----------------- .../src/vault/storage/crypto_material/base.rs | 26 -------- 4 files changed, 15 insertions(+), 94 deletions(-) diff --git a/core-client/src/s3_operations.rs b/core-client/src/s3_operations.rs index 18dcac48a9..0dc9624e15 100644 --- a/core-client/src/s3_operations.rs +++ b/core-client/src/s3_operations.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "testing")] use std::collections::HashMap; use std::{collections::HashSet, path::Path}; @@ -8,11 +9,15 @@ use kms_grpc::rpc_types::PrivDataType; use kms_grpc::rpc_types::PubDataType; #[cfg(feature = "testing")] use kms_lib::cryptography::signatures::PrivateSigKey; +#[cfg(feature = "testing")] use kms_lib::vault::storage::file::FileStorage; +#[cfg(feature = "testing")] use kms_lib::vault::storage::s3::{ S3Storage, build_anonymous_s3_client, find_region_from_s3_url, split_url, }; +#[cfg(feature = "testing")] use kms_lib::vault::storage::{StorageReader, StorageType}; +#[cfg(feature = "testing")] use kms_lib::{consts::SIGNING_KEY_ID, cryptography::signatures::PublicSigKey}; /// Fetch all remote elements and store them locally for the core client @@ -83,6 +88,7 @@ pub async fn fetch_public_elements( } /// This fetches the KMS public verification key from S3 for all the cores. +#[cfg(feature = "testing")] pub(crate) async fn fetch_kms_verification_keys( sim_conf: &CoreClientConfig, ) -> anyhow::Result> { diff --git a/core/service/src/backup/tests.rs b/core/service/src/backup/tests.rs index e30c3551b0..5f24a9c022 100644 --- a/core/service/src/backup/tests.rs +++ b/core/service/src/backup/tests.rs @@ -234,7 +234,7 @@ fn full_flow( custodian_threshold, ); assert!(backups.len() == operator_count); - let recovered_secrets = operator_recover(&backups, &operators, &backup_id); + let recovered_secrets = operator_recover(&backups, &operators); assert!(recovered_secrets.len() == operator_count); for op_addr in ops_addresses { @@ -285,7 +285,7 @@ fn full_flow_drop_msg() { custodian_threshold, ); assert!(backups.len() == operator_count); - let recovered_secrets = operator_recover(&backups, &operators, &backup_id); + let recovered_secrets = operator_recover(&backups, &operators); assert!(recovered_secrets.len() == operator_count); for addr in op_addresses { @@ -406,7 +406,7 @@ fn full_flow_malicious_custodian_second() { ); // We should still be able to recover even though one custodian is malicious assert!(backups.len() == operator_count); - let recovered_secrets = operator_recover(&backups, &operators, &backup_id); + let recovered_secrets = operator_recover(&backups, &operators); assert!(recovered_secrets.len() == operator_count); for op_addr in &op_addresses { @@ -445,7 +445,7 @@ fn full_flow_malicious_custodian_second() { custodian_threshold, ); assert!(backups.len() == operator_count); - let recovered_secrets = operator_recover(&backups, &operators, &backup_id); + let recovered_secrets = operator_recover(&backups, &operators); assert!(recovered_secrets.len() == operator_count); for op_addr in &op_addresses { @@ -508,7 +508,7 @@ fn full_flow_malicious_operator() { ); // One missing and one malicious operator assert!(backups.len() == operator_count - 2); - let recovered_secrets = operator_recover(&backups, &operators, &backup_id); + let recovered_secrets = operator_recover(&backups, &operators); assert!(recovered_secrets.len() == operator_count - 2); for (cur_role, cur_secret) in recovered_secrets { @@ -664,7 +664,6 @@ fn custodian_recover( fn operator_recover( reencryptions: &BTreeMap, BTreeMap>, operators: &OperatorsMap, - _backup_id: &RequestId, ) -> BTreeMap, Vec> { let mut res = BTreeMap::new(); for (cur_op_addr, (cur_op, cur_com, cur_emphemeral_dec, cur_ephemeral_enc)) in operators { diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index 3b0801c7d3..a236c960c1 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -139,18 +139,13 @@ where /// Validate the recovery request from the custodian and return the fully-validated, decrypted /// per-role `BackupMaterial`s. /// - /// Returns (custodian_context_id, mpc_context_id, validated_rec, operator). + /// Returns (validated_rec, operator). pub(crate) async fn validate_custodian_backup_recovery_request( &self, ephemeral_dec_key: &UnifiedPrivateEncKey, ephemeral_enc_key: &UnifiedPublicEncKey, req: CustodianRecoveryRequest, - ) -> anyhow::Result<( - ContextId, - ContextId, - HashMap, - Operator, - )> { + ) -> anyhow::Result<(HashMap, Operator)> { let custodian_context_id = parse_optional_grpc_request_id( &req.custodian_context_id, RequestIdParsingErr::BackupRecovery, @@ -195,12 +190,7 @@ where .await?; // `filter_custodian_data` already enforces `len() >= threshold + 1` - Ok(( - custodian_context_id, - mpc_context_id, - validated_rec, - operator, - )) + Ok((validated_rec, operator)) } } @@ -367,7 +357,7 @@ where } }; let inner = request.into_inner(); - let (custodian_context_id, mpc_context_id, parsed_custodian_rec, operator) = self + let (parsed_custodian_rec, operator) = self .validate_custodian_backup_recovery_request( &ephemeral_dec_key, &ephemeral_enc_key, @@ -382,52 +372,6 @@ where tonic::Code::InvalidArgument, ) })?; - // Validate that the contexts are still valid - if !self - .crypto_storage - .custodian_context_exists(&custodian_context_id) - .await - .map_err(|e| { - MetricedError::new( - OP_CUSTODIAN_BACKUP_RECOVERY, - None, - anyhow::anyhow!("Failed to check existence of custodian context: {e}"), - tonic::Code::Internal, - ) - })? - { - return Err(MetricedError::new( - OP_CUSTODIAN_BACKUP_RECOVERY, - None, - anyhow::anyhow!( - "The custodian context associated with the provided context ID does not exist, thus is not valid" - ), - tonic::Code::InvalidArgument, - )); - } - if !self - .crypto_storage - .mpc_context_exists(&mpc_context_id) - .await - .map_err(|e| { - MetricedError::new( - OP_CUSTODIAN_BACKUP_RECOVERY, - None, - anyhow::anyhow!("Failed to check existence of MPC context: {e}"), - tonic::Code::Internal, - ) - })? - { - return Err(MetricedError::new( - OP_CUSTODIAN_BACKUP_RECOVERY, - None, - anyhow::anyhow!( - "The MPC context associated with the provided context ID does not exist, thus is not valid" - ), - tonic::Code::InvalidArgument, - )); - } - match self.crypto_storage.backup_vault { Some(ref backup_vault) => { let mut backup_vault: tokio::sync::MutexGuard<'_, Vault> = @@ -1128,9 +1072,7 @@ pub(crate) async fn keychain_initialized( mod tests { use super::*; use crate::backup::error::{BackupError, RecoverySkipReason}; - use crate::backup::operator::{DSEP_BACKUP_COMMITMENT, DSEP_BACKUP_RECOVERY}; use crate::consts::DEFAULT_MPC_CONTEXT; - use crate::engine::base::safe_serialize_hash_element_versioned; use crate::vault::storage::{StorageProxy, ram::RamStorage, tests::TestType}; use crate::{ backup::custodian::{CustodianSetupMessagePayload, HEADER, InternalCustodianContext}, diff --git a/core/service/src/vault/storage/crypto_material/base.rs b/core/service/src/vault/storage/crypto_material/base.rs index 68c4f57dd2..8376a37adc 100644 --- a/core/service/src/vault/storage/crypto_material/base.rs +++ b/core/service/src/vault/storage/crypto_material/base.rs @@ -285,32 +285,6 @@ where .await } - pub async fn custodian_context_exists( - &self, - cus_context_id: &ContextId, - ) -> Result { - self.data_exists( - &RequestId::from(*cus_context_id), - &[PubDataType::RecoveryMaterial], - &[], - ) - .await - .map_err(|_e| StorageError::Reading) - } - - pub async fn mpc_context_exists( - &self, - mpc_context_id: &ContextId, - ) -> Result { - self.data_exists( - &RequestId::from(*mpc_context_id), - &[], - &[PrivDataType::ContextInfo], - ) - .await - .map_err(|_e| StorageError::Reading) - } - /// Handle the storage of data after generation, and update the meta store accordingly. /// This methods assumes that `req_id` has already been added to the meta store and will fail if not. /// From f457e0d00e091df7d127344d10b9f50863ee85cf Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 15:39:55 +0200 Subject: [PATCH 06/29] feat: initial backwards comp addition --- Cargo.toml | 2 +- .../generate-v0.14.0/Cargo.toml | 63 + .../generate-v0.14.0/src/data_0_14.rs | 1726 +++++++++++++++++ .../generate-v0.14.0/src/generate.rs | 174 ++ .../generate-v0.14.0/src/lib.rs | 7 + .../generate-v0.14.0/src/main.rs | 64 + 6 files changed, 2035 insertions(+), 1 deletion(-) create mode 100644 backward-compatibility/generate-v0.14.0/Cargo.toml create mode 100644 backward-compatibility/generate-v0.14.0/src/data_0_14.rs create mode 100644 backward-compatibility/generate-v0.14.0/src/generate.rs create mode 100644 backward-compatibility/generate-v0.14.0/src/lib.rs create mode 100644 backward-compatibility/generate-v0.14.0/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 00e4acae49..9099c1f42a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ authors = ["Zama"] publish = true edition = "2024" license = "BSD-3-Clause-Clear" -version = "0.13.20-0" +version = "0.14.0-0" repository = "https://github.com/zama-ai/kms" description = "Key Management System for the Zama Protocol." diff --git a/backward-compatibility/generate-v0.14.0/Cargo.toml b/backward-compatibility/generate-v0.14.0/Cargo.toml new file mode 100644 index 0000000000..c194065dfb --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/Cargo.toml @@ -0,0 +1,63 @@ +[package] +name = "backward-compatibility-generate-v0-14-0" +version = "0.14.0" +publish = false +authors = ["Zama"] +edition = "2021" +license = "BSD-3-Clause-Clear" + +[dependencies] +# Import the base backward-compatibility crate for shared types and utilities +backward-compatibility = { path = ".." } +bc2wrap = { git = "https://github.com/zama-ai/kms.git", package = "bc2wrap", rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291" } + +# NOTE: Some dependencies below are duplicated from ../Cargo.toml +# This is intentional - these crates are excluded from the workspace for isolation. +# Each generator may need different versions to match its target KMS version. + +# All dependencies below target tag v0.14.0-0. +kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291"} +kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291"} +algebra_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-algebra", default-features = false, rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291" } +threshold_execution_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-execution", default-features = false, rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291", features = ["testing"] } +threshold_networking_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-networking", default-features = false, rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291" } +threshold_types_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-types", default-features = false, rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291" } +#error-utils_0_14_0 = { path = "./core/error-utils", default-features = false } +#thread-handles_0_14_0 = { path = "./core/thread-handles" } + +# Dependencies for the 0.14.0 version +# Note: these dependencies should match the versions used by the KMS and distributed decryption +# modules as much as possible to avoid serialization differences +cfg-if_1_0_4 = { package = "cfg-if", version = "=1.0.4" } +tfhe_versionable_0_7 = { package = "tfhe-versionable", version = "=0.7.0" } +tfhe_1_6_1 = { package = "tfhe", version = "=1.6.1", features = [ + "shortint", +] } +alloy-sol-types-1_4_1 = { package = "alloy-sol-types", version = "=1.4.1" } +alloy-primitives-1_4_1 = { package = "alloy-primitives", version = "=1.4.1" } + +# Common dependencies +itertools = "=0.14.0" +# Note: This serde version is used for metadata types imported from backward-compatibility crate. +# The old KMS types (kms_0_11) will use their own serde 1.0.210 from their dependency tree. +# Both serde versions coexist in the same binary - this is intentional and correct! +serde = { version = "=1.0.228", features = ["derive"] } +# bincode needed for generate.rs utility functions, must match bc2wrap version (2.0.1 from v0.12.2) +# WARNING: Bincode beyond 2.0.1 may never be used! Due to actions by the project we consider newer versions compromised +# See https://www.reddit.com/r/rust/comments/1pnz1iz/bincode_development_has_ceased_permanently/ +bincode = { version = "=2.0.1", features = ["serde"] } +aes-prng = "=0.2.1" +rand = "=0.8.5" +ron = { version = "=0.10.1", features = ["integer128"] } +tokio = { version = "=1.49.0", features = ["full"] } +tokio-rustls = { version = "=0.26.2", default-features = false, features = ["aws_lc_rs"] } # Async TLS - LOW RISK: rustls team, memory-safe TLS implementation + +[[bin]] +name = "backward-compatibility-generate-v0-14-0" + +[patch.crates-io] +# MEDIUM RISK: Using fork instead of upstream - verify changes, consider upstreaming +attestation-doc-validation = { git = 'https://github.com/mkmks/attestation-doc-validation.git', branch = 'timestamps' } +rcgen = { git = 'https://github.com/zama-ai/rcgen.git' } +rustls = { git = 'https://github.com/zama-ai/rustls.git', branch = 'rel-0.23' } +rustls-webpki = { git = 'https://github.com/zama-ai/webpki.git', branch = 'rel-0.103' } diff --git a/backward-compatibility/generate-v0.14.0/src/data_0_14.rs b/backward-compatibility/generate-v0.14.0/src/data_0_14.rs new file mode 100644 index 0000000000..ba2752fe84 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/data_0_14.rs @@ -0,0 +1,1726 @@ +//! Data generation for kms-core v0.14.0 +//! This file provides the code that is used to generate all the data to serialize and versionize +//! for kms-core v0.14.0 + +use aes_prng::AesRng; +use algebra_0_13_20::{ + galois_rings::degree_4::{ResiduePolyF4Z128, ResiduePolyF4Z64}, + sharing::share::Share, +}; +use kms_0_13_20::backup::custodian::{ + Custodian, CustodianSetupMessagePayload, InternalCustodianContext, +}; +use kms_0_13_20::backup::{ + custodian::{InternalCustodianRecoveryOutput, InternalCustodianSetupMessage}, + operator::{ + BackupMaterial, InnerOperatorBackupOutput, InternalRecoveryRequest, Operator, + RecoveryValidationMaterial, DSEP_BACKUP_COMMITMENT, + }, + BackupCiphertext, +}; +use kms_0_13_20::consts::SAFE_SER_SIZE_LIMIT; +use kms_0_13_20::cryptography::{ + encryption::{Encryption, PkeScheme, PkeSchemeType, UnifiedCipher}, + hybrid_ml_kem::HybridKemCt, + signatures::{compute_eip712_signature, gen_sig_keys, SigningSchemeType}, + signcryption::{ + Signcrypt, UnifiedSigncryption, UnifiedSigncryptionKeyOwned, UnifiedUnsigncryptionKeyOwned, + }, +}; +use kms_0_13_20::engine::base::{ + safe_serialize_hash_element_versioned, CrsGenMetadata, KeyGenMetadataInner, KmsFheKeyHandles, +}; +use kms_0_13_20::engine::centralized::central_kms::generate_client_fhe_key; +use kms_0_13_20::engine::context::{ContextInfo, NodeInfo, SoftwareVersion}; +use kms_0_13_20::engine::threshold::service::session::PRSSSetupCombined; +use kms_0_13_20::engine::threshold::service::{PublicKeyMaterial, ThresholdFheKeys}; +use kms_0_13_20::util::key_setup::FhePublicKey; +use kms_0_13_20::vault::keychain::AppKeyBlob; +use kms_grpc_0_13_20::{ + kms::v1::{CustodianContext, CustodianSetupMessage, TypedPlaintext}, + rpc_types::{PrivDataType, PubDataType, SignedPubDataHandleInternal}, + solidity_types::{ + CrsgenVerification, CrsgenVerificationQ126, KeygenVerification, KeygenVerificationQ126, + }, + RequestId, +}; +use rand::{RngCore, SeedableRng}; +use std::collections::BTreeMap; +use std::num::Wrapping; +use std::{borrow::Cow, collections::HashMap, fs::create_dir_all, path::PathBuf}; +use tfhe_1_6_1::safe_serialization::safe_serialize; +use tfhe_1_6_1::shortint::parameters::{ + LweCiphertextCount, NoiseSquashingClassicParameters, NoiseSquashingCompressionParameters, +}; +use tfhe_1_6_1::{ + core_crypto::commons::{ + ciphertext_modulus::CiphertextModulus, + generators::DeterministicSeeder, + math::random::{DefaultRandomGenerator, Seed, TUniform}, + }, + shortint::parameters::NoiseSquashingParameters, + shortint::{ + engine::ShortintEngine, + parameters::{ + DecompositionBaseLog, DecompositionLevelCount, DynamicDistribution, GlweDimension, + LweDimension, PolynomialSize, + }, + CarryModulus, ClassicPBSParameters, EncryptionKeyChoice, MaxNoiseLevel, MessageModulus, + }, + ServerKey, Tag, +}; +use tfhe_versionable_0_7::Upgrade; +use threshold_execution_0_13_20::small_execution::prf::PrfKey; +use threshold_execution_0_13_20::tfhe_internals::public_keysets::FhePubKeySet; +use threshold_execution_0_13_20::{ + small_execution::prss::{PrssSet, PrssSetV0}, + tests::helper::testing::{get_dummy_prss_setup, get_networkless_base_session_for_parties}, + tfhe_internals::{ + parameters::{DKGParams, DKGParamsRegular, DKGParamsSnS, DkgMode}, + test_feature::insecure_initialize_key_material, + }, +}; +use threshold_networking_0_13_20::tls::ReleasePCRValues; +use threshold_types_0_13_20::role::Role; +use tokio::runtime::Runtime; + +use backward_compatibility::parameters::{ + ClassicPBSParametersTest, DKGParamsRegularTest, DKGParamsSnSTest, + SwitchAndSquashCompressionParametersTest, SwitchAndSquashParametersTest, +}; +use backward_compatibility::{ + AppKeyBlobTest, BackupCiphertextTest, ContextInfoTest, CrsGenMetadataTest, + CrsGenMetadataWithExtraDataTest, HybridKemCtTest, InternalCustodianContextTest, + InternalCustodianRecoveryOutputTest, InternalCustodianSetupMessageTest, + InternalRecoveryRequestTest, KeyGenMetadataTest, KeyGenMetadataWithExtraDataTest, + KmsFheKeyHandlesTest, NodeInfoTest, OperatorBackupOutputTest, PRSSSetupTest, PrfKeyTest, + PrivDataTypeTest, PrivateSigKeyTest, PrssSetTest, PrssSetupCombinedTest, PubDataTypeTest, + PublicSigKeyTest, RecoveryValidationMaterialTest, ReleasePCRValuesTest, ShareTest, + SigncryptionPayloadTest, SignedPubDataHandleInternalTest, SoftwareVersionTest, TestMetadataDD, + TestMetadataKMS, TestMetadataKmsGrpc, ThresholdFheKeysTest, TypedPlaintextTest, + UnifiedCipherTest, UnifiedSigncryptionKeyTest, UnifiedSigncryptionTest, + UnifiedUnsigncryptionKeyTest, DISTRIBUTED_DECRYPTION_MODULE_NAME, KMS_GRPC_MODULE_NAME, + KMS_MODULE_NAME, +}; + +use kms_0_13_20::cryptography::signcryption::SigncryptionPayload; + +use crate::generate::{ + store_versioned_auxiliary_05, store_versioned_test_05, KMSCoreVersion, TEST_DKG_PARAMS_SNS, +}; + +// Macro to store a versioned test +macro_rules! store_versioned_test { + ($msg:expr, $dir:expr, $test_filename:expr $(,)? ) => { + store_versioned_test_05($msg, $dir, $test_filename) + }; +} + +// Macro to store a versioned auxiliary data associated to a test +macro_rules! store_versioned_auxiliary { + ($msg:expr, $dir:expr, $test_name:expr, $filename:expr $(,)? ) => { + store_versioned_auxiliary_05($msg, $dir, $test_name, $filename) + }; +} + +fn convert_dkg_params_sns(value: DKGParamsSnSTest) -> DKGParamsSnS { + DKGParamsSnS { + regular_params: convert_dkg_params_regular(value.regular_params), + sns_params: convert_sns_parameters(value.sns_params), + sns_compression_params: Some(convert_sns_compression_parameters( + value.sns_compression_parameters, + )), + } +} + +// Parameters `dedicated_compact_public_key_parameters` and `compression_decompression_parameters` +// are set to None because they are optional tfhe-rs types, which means their backward compatibility +// is already tested. +fn convert_dkg_params_regular(value: DKGParamsRegularTest) -> DKGParamsRegular { + DKGParamsRegular { + dkg_mode: DkgMode::Z128, + sec: value.sec, + ciphertext_parameters: convert_classic_pbs_parameters(value.ciphertext_parameters), + dedicated_compact_public_key_parameters: None, + compression_decompression_parameters: None, + secret_key_deviations: None, + cpk_re_randomization_ksk_params: None, + } +} + +fn convert_classic_pbs_parameters(value: ClassicPBSParametersTest) -> ClassicPBSParameters { + ClassicPBSParameters { + lwe_dimension: LweDimension(value.lwe_dimension), + glwe_dimension: GlweDimension(value.glwe_dimension), + polynomial_size: PolynomialSize(value.polynomial_size), + lwe_noise_distribution: DynamicDistribution::TUniform(TUniform::new( + value.lwe_noise_gaussian, + )), + glwe_noise_distribution: DynamicDistribution::TUniform(TUniform::new(0)), + pbs_base_log: DecompositionBaseLog(value.pbs_base_log), + pbs_level: DecompositionLevelCount(value.pbs_level), + ks_base_log: DecompositionBaseLog(value.ks_base_log), + ks_level: DecompositionLevelCount(value.ks_level), + message_modulus: MessageModulus(value.message_modulus), + carry_modulus: CarryModulus(value.carry_modulus), + max_noise_level: MaxNoiseLevel::new(value.max_noise_level), + log2_p_fail: value.log2_p_fail, + ciphertext_modulus: CiphertextModulus::new_native(), + encryption_key_choice: { + match &*value.encryption_key_choice { + "big" => EncryptionKeyChoice::Big, + "small" => EncryptionKeyChoice::Small, + _ => panic!("Invalid encryption key choice"), + } + }, + // no need to test this as it's from tfhe-rs + modulus_switch_noise_reduction_params: + tfhe_1_6_1::shortint::prelude::ModulusSwitchType::Standard, + } +} + +fn convert_sns_parameters(value: SwitchAndSquashParametersTest) -> NoiseSquashingParameters { + NoiseSquashingParameters::Classic(NoiseSquashingClassicParameters { + glwe_dimension: GlweDimension(value.glwe_dimension), + glwe_noise_distribution: DynamicDistribution::new_t_uniform(value.glwe_noise_distribution), + polynomial_size: PolynomialSize(value.polynomial_size), + decomp_base_log: DecompositionBaseLog(value.pbs_base_log), + decomp_level_count: DecompositionLevelCount(value.pbs_level), + ciphertext_modulus: CiphertextModulus::::new_native(), + modulus_switch_noise_reduction_params: + tfhe_1_6_1::shortint::prelude::ModulusSwitchType::Standard, + message_modulus: MessageModulus(value.message_modulus), + carry_modulus: CarryModulus(value.carry_modulus), + }) +} + +fn convert_sns_compression_parameters( + value: SwitchAndSquashCompressionParametersTest, +) -> NoiseSquashingCompressionParameters { + NoiseSquashingCompressionParameters { + packing_ks_level: DecompositionLevelCount(value.packing_ks_level), + packing_ks_base_log: DecompositionBaseLog(value.packing_ks_base_log), + packing_ks_polynomial_size: PolynomialSize(value.packing_ks_polynomial_size), + packing_ks_glwe_dimension: GlweDimension(value.packing_ks_glwe_dimension), + lwe_per_glwe: LweCiphertextCount(value.lwe_per_glwe), + packing_ks_key_noise_distribution: DynamicDistribution::new_t_uniform( + value.packing_ks_key_noise_distribution, + ), + ciphertext_modulus: CiphertextModulus::::new_native(), + message_modulus: MessageModulus(value.message_modulus), + carry_modulus: CarryModulus(value.carry_modulus), + } +} + +// Distributed Decryption test +const PRSS_SETUP_RPOLY_64_TEST: PRSSSetupTest = PRSSSetupTest { + test_filename: Cow::Borrowed("prss_setup_rpoly_64"), + amount: 10, + threshold: 3, + role_i: 1, + residue_poly_size: 64, +}; + +// Distributed Decryption test +const PRSS_SETUP_RPOLY_128_TEST: PRSSSetupTest = PRSSSetupTest { + test_filename: Cow::Borrowed("prss_setup_rpoly_128"), + amount: 10, + threshold: 3, + role_i: 1, + residue_poly_size: 128, +}; + +// Distributed Decryption test +const PRF_KEY_TEST: PrfKeyTest = PrfKeyTest { + test_filename: Cow::Borrowed("prf_key"), + seed: 100, +}; + +// Distributed Decryption test +const PRSS_SET_64_TEST: PrssSetTest = PrssSetTest { + test_filename: Cow::Borrowed("prss_set_64"), + legacy_filename: Cow::Borrowed("legacy_prss_set_64"), + amount_parties: 7, + amount_points: 7, + residue_poly_size: 64, + state: 11111, +}; + +// Distributed Decryption test +const PRSS_SET_128_TEST: PrssSetTest = PrssSetTest { + test_filename: Cow::Borrowed("prss_set_128"), + legacy_filename: Cow::Borrowed("legacy_prss_set_128"), + amount_parties: 13, + amount_points: 3, + residue_poly_size: 128, + state: 2222, +}; + +// Distributed Decryption test +const SHARE_64_TEST: ShareTest = ShareTest { + test_filename: Cow::Borrowed("share_64"), + value: 34653246, + owner: 1, + residue_poly_size: 64, +}; + +// Distributed Decryption test +const SHARE_128_TEST: ShareTest = ShareTest { + test_filename: Cow::Borrowed("share_128"), + value: 934565743256423875434534434, + owner: 1, + residue_poly_size: 128, +}; + +// Distributed Decryption test +const RELEASE_PCR_VALUES_TEST: ReleasePCRValuesTest = ReleasePCRValuesTest { + test_filename: Cow::Borrowed("release_pcr_values"), + state: 64, +}; + +// KMS test +const PRIVATE_SIG_KEY_TEST: PrivateSigKeyTest = PrivateSigKeyTest { + test_filename: Cow::Borrowed("private_sig_key"), + state: 100, +}; + +// KMS-grpc test +const SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST: SignedPubDataHandleInternalTest = + SignedPubDataHandleInternalTest { + test_filename: Cow::Borrowed("signed_pub_data_handle_internal"), + state: 100, + key_handle: Cow::Borrowed("key_handle"), + signature: [1, 2, 3], + external_signature: [4, 5, 6], + }; + +const PUB_DATA_TYPE: PubDataTypeTest = PubDataTypeTest { + test_filename: Cow::Borrowed("pub_data_type"), +}; + +const PRIV_DATA_TYPE: PrivDataTypeTest = PrivDataTypeTest { + test_filename: Cow::Borrowed("priv_data_type"), +}; + +// KMS test +const PUBLIC_SIG_KEY_TEST: PublicSigKeyTest = PublicSigKeyTest { + test_filename: Cow::Borrowed("public_sig_key"), + state: 100, +}; + +// KMS test +// TODO: include eip712_domain parameter +const KMS_FHE_KEY_HANDLES_TEST: KmsFheKeyHandlesTest = KmsFheKeyHandlesTest { + test_filename: Cow::Borrowed("kms_fhe_key_handles"), + client_key_filename: Cow::Borrowed("client_key_handle"), + public_key_filename: Cow::Borrowed("public_key_handle"), + server_key_filename: Cow::Borrowed("server_key_handle"), + sig_key_filename: Cow::Borrowed("sig_key_handle"), + decompression_key_filename: Cow::Borrowed("decompression_key"), + state: 100, + seed: 100, + element: Cow::Borrowed("element"), + dkg_parameters_sns: TEST_DKG_PARAMS_SNS, +}; + +// KMS test +const THRESHOLD_FHE_KEYS_TEST: ThresholdFheKeysTest = ThresholdFheKeysTest { + test_filename: Cow::Borrowed("threshold_fhe_keys"), + private_key_set_filename: Cow::Borrowed("private_key_set"), + integer_server_key_filename: Cow::Borrowed("integer_server_key"), + sns_key_filename: Cow::Borrowed("sns_key"), + info_filename: Cow::Borrowed("info"), + decompression_key_filename: Cow::Borrowed("decompression_key"), + state: 100, + amount: 2, + threshold: 1, + role_i: 1, + element: Cow::Borrowed("element"), + dkg_parameters_sns: TEST_DKG_PARAMS_SNS, +}; + +// KMS test +const KEY_GEN_METADATA_TEST: KeyGenMetadataTest = KeyGenMetadataTest { + test_filename: Cow::Borrowed("key_gen_metadata"), + legacy_filename: Cow::Borrowed("legacy_key_gen_metadata"), + state: 100, +}; + +// KMS test +const CRS_GEN_METADATA_TEST: CrsGenMetadataTest = CrsGenMetadataTest { + test_filename: Cow::Borrowed("crs_gen_metadata"), + legacy_filename: Cow::Borrowed("legacy_crs_gen_metadata"), + state: 100, + max_num_bits: 2048, +}; + +// KMS test — for key generation metadata with the 14.0 format (including extra data). +const KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST: KeyGenMetadataWithExtraDataTest = + KeyGenMetadataWithExtraDataTest { + test_filename: Cow::Borrowed("key_gen_metadata_with_extra_data"), + state: 101, + extra_data: Cow::Borrowed(&[0x02, 0xAA, 0xBB, 0xCC]), + }; + +const CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST: CrsGenMetadataWithExtraDataTest = + CrsGenMetadataWithExtraDataTest { + test_filename: Cow::Borrowed("crs_gen_metadata_with_extra_data"), + state: 101, + max_num_bits: 2048, + extra_data: Cow::Borrowed(&[0x02, 0xDD, 0xEE, 0xFF]), + }; + +// KMS test +const APP_KEY_BLOB_TEST: AppKeyBlobTest = AppKeyBlobTest { + test_filename: Cow::Borrowed("app_key_blob"), + root_key_id: Cow::Borrowed("root_key_id"), + data_key_blob: Cow::Borrowed("data_key_blob"), + ciphertext: Cow::Borrowed("ciphertext"), + iv: Cow::Borrowed("iv"), + auth_tag: Cow::Borrowed("auth_tag"), +}; + +// KMS test +fn typed_plaintext_test() -> TypedPlaintextTest { + TypedPlaintextTest { + test_filename: Cow::Borrowed("typed_plaintext"), + plaintext_bytes: vec![1, 2, 3, 4, 5], + fhe_type: 8, // FheTypes::Uint8 + } +} + +// KMS test +fn signcryption_payload_test() -> SigncryptionPayloadTest { + SigncryptionPayloadTest { + test_filename: Cow::Borrowed("signcryption_payload"), + plaintext_bytes: vec![1, 2, 3, 4, 5], + fhe_type: 8, // FheTypes::Uint8 + link: vec![222, 173, 190, 239], + } +} + +// KMS test +const SIGNCRYPTION_KEY_TEST: UnifiedSigncryptionKeyTest = UnifiedSigncryptionKeyTest { + test_filename: Cow::Borrowed("signcryption_key"), + state: 100, +}; + +// KMS test +const UNSIGNCRYPTION_KEY_TEST: UnifiedUnsigncryptionKeyTest = UnifiedUnsigncryptionKeyTest { + test_filename: Cow::Borrowed("designcryption_key"), + state: 200, +}; + +// KMS test +const UNIFIED_SIGNCRYPTION_TEST: UnifiedSigncryptionTest = UnifiedSigncryptionTest { + test_filename: Cow::Borrowed("unified_signcryption"), + state: 202, +}; + +// KMS test +const BACKUP_CIPHERTEXT_TEST: BackupCiphertextTest = BackupCiphertextTest { + test_filename: Cow::Borrowed("backup_ciphertext"), + unified_cipher_filename: Cow::Borrowed("unified_ciphertext_handle"), + state: 200, +}; + +// KMS test +const UNIFIED_CIPHER_TEST: UnifiedCipherTest = UnifiedCipherTest { + test_filename: Cow::Borrowed("unified_ciphertext"), + hybrid_kem_filename: Cow::Borrowed("hybrid_kem_ct_handle"), + state: 123, +}; + +// KMS test +const PRSS_SETUP_COMBINED_TEST: PrssSetupCombinedTest = PrssSetupCombinedTest { + test_filename: Cow::Borrowed("prss_setup_combined"), + prss_setup_64: Cow::Borrowed("prss_setup_64"), + prss_setup_128: Cow::Borrowed("prss_setup_128"), + role_i: 3, + amount: 13, + threshold: 4, +}; + +// KMS test +fn hybrid_kem_ct_test() -> HybridKemCtTest { + HybridKemCtTest { + test_filename: Cow::Borrowed("hybrid_kem_ct"), + nonce: [2u8; 12], + kem_ct: vec![1, 2, 3, 4, 5], + payload_ct: vec![6, 7, 8, 9, 10], + } +} + +// KMS test +fn context_info_test() -> ContextInfoTest { + ContextInfoTest { + test_filename: Cow::Borrowed("context_info"), + threshold: 3, + state: 234, + } +} + +// KMS test +fn node_info_test() -> NodeInfoTest { + NodeInfoTest { + test_filename: Cow::Borrowed("node_info"), + mpc_identity: Cow::Borrowed("node_mpc_identity"), + party_id: 4, + external_url: Cow::Borrowed("https://node4.example.com/mpc/something-something"), + public_storage_url: Cow::Borrowed("https://storage.example.com/node4"), + public_storage_prefix: Cow::Borrowed("PUB"), + ca_cert: Some(vec![1, 2, 3, 4, 6, 7, 8, 9]), + state: 500, + } +} + +// KMS test +const SOFTWARE_VERSION_TEST: SoftwareVersionTest = SoftwareVersionTest { + test_filename: Cow::Borrowed("software_version"), + major: 0, + minor: 13, + patch: 4, + tag: Cow::Borrowed("super fun version"), +}; + +// KMS test +const RECOVERY_MATERIAL_TEST: RecoveryValidationMaterialTest = RecoveryValidationMaterialTest { + test_filename: Cow::Borrowed("recovery_material"), + internal_cus_context_filename: Cow::Borrowed("internal_cus_context_handle"), + state: 300, + custodian_count: 5, + mpc_context_id: [7u8; 32], +}; + +// KMS test +const INTERNAL_RECOVERY_REQUEST_TEST: InternalRecoveryRequestTest = InternalRecoveryRequestTest { + test_filename: Cow::Borrowed("internal_recovery_request"), + amount: 10, + state: 300, +}; + +// KMS test +const INTERNAL_CUS_CONTEXT_TEST: InternalCustodianContextTest = InternalCustodianContextTest { + test_filename: Cow::Borrowed("internal_cus_context"), + internal_cus_setup_filename: Cow::Borrowed("internal_cus_setup_handle"), + unified_enc_key_filename: Cow::Borrowed("unified_enc_key_handle"), + state: 300, + custodian_count: 5, +}; + +// KMS test +const INTERNAL_CUS_SETUP_MSG_TEST: InternalCustodianSetupMessageTest = + InternalCustodianSetupMessageTest { + test_filename: Cow::Borrowed("internal_custodian_setup_message"), + state: 42, + }; + +// KMS test +const INTERNAL_CUS_REC_OUT_TEST: InternalCustodianRecoveryOutputTest = + InternalCustodianRecoveryOutputTest { + test_filename: Cow::Borrowed("internal_custodian_recovery_output"), + state: 43, + mpc_context_id: [7u8; 32], + }; + +// KMS test +const OPERATOR_BACKUP_OUTPUT_TEST: OperatorBackupOutputTest = OperatorBackupOutputTest { + test_filename: Cow::Borrowed("operator_backup_output"), + custodian_count: 3, + custodian_threshold: 1, + plaintext: [0u8; 32], + backup_id: [1u8; 32], + seed: 42, +}; + +fn dummy_domain() -> alloy_sol_types_1_4_1::Eip712Domain { + alloy_sol_types_1_4_1::eip712_domain!( + name: "Authorization token", + version: "1", + chain_id: 8006, + verifying_contract: alloy_primitives_1_4_1::address!("66f9664f97F2b50F62D13eA064982f936dE76657"), + ) +} + +pub struct V0_13_20; + +struct KmsV0_13_20; + +impl KmsV0_13_20 { + fn gen_private_sig_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(PRIVATE_SIG_KEY_TEST.state); + let (_, private_sig_key) = gen_sig_keys(&mut rng); + + store_versioned_test!(&private_sig_key, dir, &PRIVATE_SIG_KEY_TEST.test_filename); + + TestMetadataKMS::PrivateSigKey(PRIVATE_SIG_KEY_TEST) + } + + fn gen_public_sig_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(PUBLIC_SIG_KEY_TEST.state); + let (public_sig_key, _) = gen_sig_keys(&mut rng); + + store_versioned_test!(&public_sig_key, dir, &PUBLIC_SIG_KEY_TEST.test_filename); + + TestMetadataKMS::PublicSigKey(PUBLIC_SIG_KEY_TEST) + } + + fn gen_typed_plaintext(dir: &PathBuf) -> TestMetadataKMS { + let test = typed_plaintext_test(); + + let plaintext = TypedPlaintext { + bytes: test.plaintext_bytes.clone(), + fhe_type: test.fhe_type, + }; + + // TypedPlaintext doesn't use tfhe-versionable, serialize directly with bincode + let serialized = bc2wrap::serialize(&plaintext).unwrap(); + let filename = format!("{}.bincode", test.test_filename); + std::fs::write(dir.join(&filename), serialized).unwrap(); + + TestMetadataKMS::TypedPlaintext(test) + } + + fn gen_app_key_blob(dir: &PathBuf) -> TestMetadataKMS { + let app_key_blob = AppKeyBlob { + root_key_id: APP_KEY_BLOB_TEST.root_key_id.to_string(), + data_key_blob: APP_KEY_BLOB_TEST.data_key_blob.into_owned().into(), + ciphertext: APP_KEY_BLOB_TEST.ciphertext.into_owned().into(), + iv: APP_KEY_BLOB_TEST.iv.into_owned().into(), + auth_tag: APP_KEY_BLOB_TEST.auth_tag.into_owned().into(), + }; + + store_versioned_test!(&app_key_blob, dir, &APP_KEY_BLOB_TEST.test_filename); + + TestMetadataKMS::AppKeyBlob(APP_KEY_BLOB_TEST) + } + + fn gen_key_gen_metadata(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(KEY_GEN_METADATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + // We need to serialize something that is versioned, so let us just use signing keys for the test + let (pretend_server_key, pretend_public_key) = gen_sig_keys(&mut rng); + let preprocessing_id: RequestId = RequestId::new_random(&mut rng); + let key_id: RequestId = RequestId::new_random(&mut rng); + + let mut key_digest_map: HashMap> = HashMap::new(); + let mut legacy: HashMap = HashMap::new(); + let server_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_server_key).unwrap(); + let pub_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_public_key).unwrap(); + let sol_type = KeygenVerificationQ126::new_standard( + &preprocessing_id, + &key_id, + server_key_digest.clone(), + pub_key_digest.clone(), + ); + key_digest_map.insert(PubDataType::ServerKey, server_key_digest); + key_digest_map.insert(PubDataType::PublicKey, pub_key_digest); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + + legacy.insert( + PubDataType::ServerKey, + SignedPubDataHandleInternal { + key_handle: key_id.to_string(), + signature: vec![1_u8; 65], + external_signature: external_signature.clone(), + }, + ); + legacy.insert( + PubDataType::PublicKey, + SignedPubDataHandleInternal { + key_handle: key_id.to_string(), + signature: vec![2_u8; 65], + external_signature: external_signature.clone(), + }, + ); + + let current = KeyGenMetadataInner { + key_id, + preprocessing_id, + key_digest_map, + external_signature, + extra_data: None, + }; + store_versioned_auxiliary!( + &legacy, + dir, + &KEY_GEN_METADATA_TEST.test_filename, + &KEY_GEN_METADATA_TEST.legacy_filename, + ); + store_versioned_test!(¤t, dir, &KEY_GEN_METADATA_TEST.test_filename); + + TestMetadataKMS::KeyGenMetadata(KEY_GEN_METADATA_TEST) + } + + fn gen_crs_metadata(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(CRS_GEN_METADATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + let crs_id: RequestId = RequestId::new_random(&mut rng); + let digest = [12u8; 32].to_vec(); + let max_num_bits = CRS_GEN_METADATA_TEST.max_num_bits; + let sol_type = CrsgenVerificationQ126::new(&crs_id, max_num_bits as usize, digest.clone()); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + let current_crs_meta_data = CrsGenMetadata::new( + crs_id, + digest, + max_num_bits, + external_signature.clone(), + vec![], // Empty extra data to signal legacy + ); + + let legacy_crs_meta_data = SignedPubDataHandleInternal::new( + crs_id.to_string(), + [3u8; 65].to_vec(), + external_signature.clone(), + ); + + store_versioned_auxiliary!( + &legacy_crs_meta_data, + dir, + &CRS_GEN_METADATA_TEST.test_filename, + &CRS_GEN_METADATA_TEST.legacy_filename, + ); + store_versioned_test!( + ¤t_crs_meta_data, + dir, + &CRS_GEN_METADATA_TEST.test_filename + ); + + TestMetadataKMS::CrsGenMetadata(CRS_GEN_METADATA_TEST) + } + + /// Twin of `gen_key_gen_metadata` for version 14.0 (with extra_data). + fn gen_key_gen_metadata_with_extra_data(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + let (pretend_server_key, pretend_public_key) = gen_sig_keys(&mut rng); + let preprocessing_id: RequestId = RequestId::new_random(&mut rng); + let key_id: RequestId = RequestId::new_random(&mut rng); + + let extra_data = KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST.extra_data.to_vec(); + let mut key_digest_map: HashMap> = HashMap::new(); + let server_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_server_key).unwrap(); + let pub_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_public_key).unwrap(); + let sol_type = KeygenVerification::new_uncompressed( + &preprocessing_id, + &key_id, + server_key_digest.clone(), + pub_key_digest.clone(), + extra_data.clone(), + ); + key_digest_map.insert(PubDataType::ServerKey, server_key_digest); + key_digest_map.insert(PubDataType::PublicKey, pub_key_digest); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + + let current = KeyGenMetadataInner { + key_id, + preprocessing_id, + key_digest_map, + external_signature, + extra_data: Some(extra_data), + }; + store_versioned_test!( + ¤t, + dir, + &KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST.test_filename, + ); + + TestMetadataKMS::KeyGenMetadataWithExtraData(KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST) + } + + /// Twin of `gen_crs_metadata` for version 14.0 (with extra_data). + fn gen_crs_metadata_with_extra_data(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + let crs_id: RequestId = RequestId::new_random(&mut rng); + let digest = [12u8; 32].to_vec(); + let max_num_bits = CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.max_num_bits; + let extra_data = CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.extra_data.to_vec(); + let sol_type = CrsgenVerification::new( + &crs_id, + max_num_bits as usize, + digest.clone(), + extra_data.clone(), + ); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + let current_crs_meta_data = CrsGenMetadata::new( + crs_id, + digest, + max_num_bits, + external_signature.clone(), + extra_data, + ); + + store_versioned_test!( + ¤t_crs_meta_data, + dir, + &CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.test_filename + ); + + TestMetadataKMS::CrsGenMetadataWithExtraData(CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST) + } + + #[allow(clippy::ptr_arg)] + fn gen_signcryption_payload(dir: &PathBuf) -> TestMetadataKMS { + let test = signcryption_payload_test(); + + let payload = SigncryptionPayload { + plaintext: TypedPlaintext { + bytes: test.plaintext_bytes.clone(), + fhe_type: test.fhe_type, + }, + link: test.link.clone(), + }; + + // SigncryptionPayload doesn't use tfhe-versionable, serialize with bc2wrap from v0.11.1 + // This uses the exact bc2wrap implementation and bincode version from v0.11.1 + let serialized = bc2wrap::serialize(&payload).unwrap(); + let filename = format!("{}.bincode", test.test_filename); + std::fs::write(dir.join(&filename), serialized).unwrap(); + + TestMetadataKMS::SigncryptionPayload(test) + } + + fn gen_signcryption_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(SIGNCRYPTION_KEY_TEST.state); + let (_verf_key, server_sig_key) = gen_sig_keys(&mut rng); + let (client_verf_key, _server_sig_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let signcrypt_key = UnifiedSigncryptionKeyOwned::new( + server_sig_key, + enc_key, + client_verf_key.verf_key_id(), + ); + store_versioned_test!(&signcrypt_key, dir, &SIGNCRYPTION_KEY_TEST.test_filename); + TestMetadataKMS::UnifiedSigncryptionKeyOwned(SIGNCRYPTION_KEY_TEST) + } + + fn gen_designcryption_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(UNSIGNCRYPTION_KEY_TEST.state); + let (sender_verf_key, _sender_sig_key) = gen_sig_keys(&mut rng); + let (receiver_verf_key, _receiver_sig_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (dec_key, enc_key) = encryption.keygen().unwrap(); + let signcrypt_key = UnifiedUnsigncryptionKeyOwned::new( + dec_key, + enc_key, + sender_verf_key, + receiver_verf_key.verf_key_id().to_vec(), + ); + store_versioned_test!(&signcrypt_key, dir, &UNSIGNCRYPTION_KEY_TEST.test_filename); + TestMetadataKMS::UnifiedUnsigncryptionKeyOwned(UNSIGNCRYPTION_KEY_TEST) + } + + fn gen_backup_ciphertext(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(BACKUP_CIPHERTEXT_TEST.state); + let backup_id: RequestId = RequestId::new_random(&mut rng); + // Generate the unified ciphertext after using the RNG for generating backup ID since backup ID + // will also be generated as part of the test + let mut kem_ct = [0_u8; 32]; + rng.fill_bytes(&mut kem_ct); + let mut payload_ct = [0_u8; 32]; + rng.fill_bytes(&mut payload_ct); + let ciphertext: UnifiedCipher = UnifiedCipher { + cipher: HybridKemCt { + nonce: [0_u8; 12], + kem_ct: kem_ct.to_vec(), + payload_ct: payload_ct.to_vec(), + }, + pke_type: PkeSchemeType::MlKem512, + }; + store_versioned_auxiliary!( + &ciphertext, + dir, + &BACKUP_CIPHERTEXT_TEST.test_filename, + &BACKUP_CIPHERTEXT_TEST.unified_cipher_filename, + ); + + let backup_ct = BackupCiphertext { + ciphertext, + priv_data_type: PrivDataType::SigningKey, + backup_id, + }; + + store_versioned_test!(&backup_ct, dir, &BACKUP_CIPHERTEXT_TEST.test_filename); + TestMetadataKMS::BackupCiphertext(BACKUP_CIPHERTEXT_TEST) + } + + fn gen_unified_signcryption(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(UNIFIED_SIGNCRYPTION_TEST.state); + let (verf_key, server_sig_key) = gen_sig_keys(&mut rng); + let (client_verf_key, _server_sig_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let signcrypt_key = UnifiedSigncryptionKeyOwned::new( + server_sig_key, + enc_key, + client_verf_key.verf_key_id(), + ); + let signcryption = signcrypt_key + .signcrypt(&mut rng, b"TESTTEST", &verf_key) + .unwrap(); + + store_versioned_test!(&signcryption, dir, &UNIFIED_SIGNCRYPTION_TEST.test_filename); + TestMetadataKMS::UnifiedSigncryption(UNIFIED_SIGNCRYPTION_TEST) + } + + fn gen_unified_cipher(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(UNIFIED_CIPHER_TEST.state); + let mut kem_ct = [0_u8; 32]; + rng.fill_bytes(&mut kem_ct); + let mut payload_ct = [0_u8; 32]; + rng.fill_bytes(&mut payload_ct); + let kem = HybridKemCt { + nonce: [0_u8; 12], + kem_ct: kem_ct.to_vec(), + payload_ct: payload_ct.to_vec(), + }; + store_versioned_auxiliary!( + &kem, + dir, + &UNIFIED_CIPHER_TEST.test_filename, + &UNIFIED_CIPHER_TEST.hybrid_kem_filename, + ); + let cipher = UnifiedCipher { + cipher: kem, + pke_type: PkeSchemeType::MlKem512, + }; + + store_versioned_test!(&cipher, dir, &UNIFIED_CIPHER_TEST.test_filename); + + TestMetadataKMS::UnifiedCipher(UNIFIED_CIPHER_TEST) + } + + fn gen_hybrid_kem_ct(dir: &PathBuf) -> TestMetadataKMS { + let test = hybrid_kem_ct_test(); + let cipher = HybridKemCt { + nonce: test.nonce, + kem_ct: test.kem_ct.clone(), + payload_ct: test.payload_ct.clone(), + }; + + store_versioned_test!(&cipher, dir, &test.test_filename); + + TestMetadataKMS::HybridKemCt(test) + } + + fn gen_prss_setup_combined(dir: &PathBuf) -> TestMetadataKMS { + let role = Role::indexed_from_one(PRSS_SETUP_COMBINED_TEST.role_i); + let base_session_64 = get_networkless_base_session_for_parties( + PRSS_SETUP_COMBINED_TEST.amount as usize, + PRSS_SETUP_COMBINED_TEST.threshold, + role, + ); + let base_session_128 = get_networkless_base_session_for_parties( + PRSS_SETUP_COMBINED_TEST.amount as usize, + PRSS_SETUP_COMBINED_TEST.threshold, + role, + ); + let prss_setup_z64 = get_dummy_prss_setup::(base_session_64); + let prss_setup_z128 = get_dummy_prss_setup::(base_session_128); + let prss = PRSSSetupCombined { + prss_setup_z64: prss_setup_z64.clone(), + prss_setup_z128: prss_setup_z128.clone(), + num_parties: PRSS_SETUP_COMBINED_TEST.amount, + threshold: PRSS_SETUP_COMBINED_TEST.threshold, + }; + store_versioned_auxiliary!( + &prss_setup_z64, + dir, + &PRSS_SETUP_COMBINED_TEST.test_filename, + &PRSS_SETUP_COMBINED_TEST.prss_setup_64, + ); + store_versioned_auxiliary!( + &prss_setup_z128, + dir, + &PRSS_SETUP_COMBINED_TEST.test_filename, + &PRSS_SETUP_COMBINED_TEST.prss_setup_128, + ); + + store_versioned_test!(&prss, dir, &PRSS_SETUP_COMBINED_TEST.test_filename); + TestMetadataKMS::PrssSetupCombined(PRSS_SETUP_COMBINED_TEST) + } + + fn gen_context_info(dir: &PathBuf) -> TestMetadataKMS { + let test = context_info_test(); + let mut rng = AesRng::seed_from_u64(test.state); + // Note that `NodeInfo`, `SoftwareVersion` and `ReleasePCRValues` are tested separately so we just do a simple static construction here + let node_info = NodeInfo { + mpc_identity: "Staoshi Nakamoto".to_string(), + party_id: 42, + verification_key: None, + external_url: "https://node42.example.com".to_string(), + ca_cert: None, + public_storage_url: "https://storage.example.com/node42".to_string(), + public_storage_prefix: Some("PUB".to_string()), + extra_verification_keys: vec![], + }; + let software_version = SoftwareVersion { + major: 2, + minor: 11, + patch: 12, + tag: None, + }; + let pcr_values = ReleasePCRValues { + pcr0: vec![0_u8; 32], + pcr1: vec![1_u8; 32], + pcr2: vec![2_u8; 32], + }; + let context_info = ContextInfo { + mpc_nodes: vec![node_info.clone(), node_info.clone()], + software_version, + context_id: RequestId::new_random(&mut rng).into(), + threshold: test.threshold, + pcr_values: vec![pcr_values.clone(), pcr_values.clone()], + }; + + store_versioned_test!(&context_info, dir, &test.test_filename); + + TestMetadataKMS::ContextInfo(test) + } + + fn gen_node_info(dir: &PathBuf) -> TestMetadataKMS { + let node_info_test = node_info_test(); + let mut rng = AesRng::seed_from_u64(node_info_test.state); + let (verf_key, _sig_key) = gen_sig_keys(&mut rng); + let (verf_key2, _sig_key) = gen_sig_keys(&mut rng); + let node_info = NodeInfo { + mpc_identity: node_info_test.mpc_identity.to_string(), + party_id: node_info_test.party_id, + verification_key: Some(verf_key), + external_url: node_info_test.external_url.to_string(), + ca_cert: node_info_test.ca_cert.clone(), // We currently don't have simple code for generating certificates + public_storage_url: node_info_test.public_storage_url.to_string(), + public_storage_prefix: Some(node_info_test.public_storage_prefix.to_string()), + extra_verification_keys: vec![verf_key2], + }; + + store_versioned_test!(&node_info, dir, &node_info_test.test_filename); + + TestMetadataKMS::NodeInfo(node_info_test) + } + + fn gen_software_version(dir: &PathBuf) -> TestMetadataKMS { + let software_version = SoftwareVersion { + major: SOFTWARE_VERSION_TEST.major, + minor: SOFTWARE_VERSION_TEST.minor, + patch: SOFTWARE_VERSION_TEST.patch, + tag: Some(SOFTWARE_VERSION_TEST.tag.to_string()), + }; + + store_versioned_test!(&software_version, dir, &SOFTWARE_VERSION_TEST.test_filename); + + TestMetadataKMS::SoftwareVersion(SOFTWARE_VERSION_TEST) + } + + fn gen_recovery_material(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(RECOVERY_MATERIAL_TEST.state); + let backup_id: RequestId = RequestId::new_random(&mut rng); + let (operator_pk, operator_sk) = gen_sig_keys(&mut rng); + let mut commitments = BTreeMap::new(); + let mut cts = BTreeMap::new(); + for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { + let cus_role = Role::indexed_from_one(role_j); + let (custodian_pk, _) = gen_sig_keys(&mut rng); + let backup_material = BackupMaterial { + backup_id, + custodian_pk, + custodian_role: cus_role, + operator_pk: operator_pk.clone(), + shares: Vec::new(), + }; + let msg_digest = + safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) + .unwrap(); + commitments.insert(cus_role, msg_digest); + let mut payload = [0_u8; 32]; + rng.fill_bytes(&mut payload); + let cts_out = InnerOperatorBackupOutput { + signcryption: UnifiedSigncryption { + payload: payload.to_vec(), + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }, + }; + cts.insert(cus_role, cts_out); + } + + // Dummy payload; but needs to be a properly serialized payload + // This must be generated after the commitment stuff, since the test will regenerate the commitment stuff, + // but read the custodian context from disk + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let (cus_pk, _) = gen_sig_keys(&mut rng); + let payload = CustodianSetupMessagePayload { + header: "header".to_string(), + random_value: [4_u8; 32], + timestamp: 0, + public_enc_key: enc_key.clone(), + verification_key: cus_pk.clone(), + }; + let mut payload_serial = Vec::new(); + safe_serialize(&payload, &mut payload_serial, SAFE_SER_SIZE_LIMIT).unwrap(); + let mut custodian_nodes = Vec::new(); + for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { + let setup_msg = CustodianSetupMessage { + custodian_role: role_j as u64, + name: format!("Custodian-{role_j}"), + payload: payload_serial.clone(), + }; + custodian_nodes.push(setup_msg); + } + let custodian_context = CustodianContext { + custodian_nodes, + custodian_context_id: Some(backup_id.into()), + threshold: 1, + }; + let internal_custodian_context = + InternalCustodianContext::new(custodian_context, enc_key).unwrap(); + store_versioned_auxiliary!( + &internal_custodian_context, + dir, + &RECOVERY_MATERIAL_TEST.test_filename, + &RECOVERY_MATERIAL_TEST.internal_cus_context_filename, + ); + let recovery_material = RecoveryValidationMaterial::new( + cts, + commitments, + internal_custodian_context, + &operator_sk, + kms_grpc_0_13_20::ContextId::from_bytes(RECOVERY_MATERIAL_TEST.mpc_context_id), + ) + .unwrap(); + store_versioned_test!( + &recovery_material, + dir, + &RECOVERY_MATERIAL_TEST.test_filename + ); + TestMetadataKMS::RecoveryValidationMaterial(RECOVERY_MATERIAL_TEST) + } + + fn gen_internal_recovery_request(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_RECOVERY_REQUEST_TEST.state); + let backup_id: RequestId = RequestId::new_random(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let (verf_key, _) = gen_sig_keys(&mut rng); + let mut cts = BTreeMap::new(); + for role_j in 1..=INTERNAL_RECOVERY_REQUEST_TEST.amount { + let cur_role = Role::indexed_from_one(role_j as usize); + let mut payload = [0_u8; 32]; + rng.fill_bytes(&mut payload); + let signcryption = UnifiedSigncryption { + payload: payload.to_vec(), + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }; + cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); + } + let recovery_material = + InternalRecoveryRequest::new(enc_key, cts, backup_id, verf_key).unwrap(); + store_versioned_test!( + &recovery_material, + dir, + &INTERNAL_RECOVERY_REQUEST_TEST.test_filename + ); + TestMetadataKMS::InternalRecoveryRequest(INTERNAL_RECOVERY_REQUEST_TEST) + } + + fn gen_internal_cus_context_handles(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_CONTEXT_TEST.state); + let context_id: RequestId = RequestId::new_random(&mut rng); + let mut cus_nodes = BTreeMap::new(); + for role_j in 1..=INTERNAL_CUS_CONTEXT_TEST.custodian_count { + let cus_role = Role::indexed_from_one(role_j); + let (custodian_verf_key, _) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_, cus_enc_key) = encryption.keygen().unwrap(); + let mut rnd = [0_u8; 32]; + rng.fill_bytes(&mut rnd); + let setup_msg = InternalCustodianSetupMessage { + header: "header".to_string(), + custodian_role: cus_role, + name: format!("role{role_j}"), + random_value: rnd, + timestamp: 42, + public_enc_key: cus_enc_key, + public_verf_key: custodian_verf_key, + }; + cus_nodes.insert(cus_role, setup_msg); + } + // Generate the extra encryption key last since it will be loaded from file and + // thus we should avoid using the RNG for the things that it will be used to generate in the test + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_, cus_enc_key) = encryption.keygen().unwrap(); + let internal_cus_context = InternalCustodianContext { + threshold: 1, + context_id, + custodian_nodes: cus_nodes, + backup_enc_key: cus_enc_key.clone(), + }; + store_versioned_auxiliary!( + &cus_enc_key, + dir, + &INTERNAL_CUS_CONTEXT_TEST.test_filename, + &INTERNAL_CUS_CONTEXT_TEST.unified_enc_key_filename, + ); + + store_versioned_test!( + &internal_cus_context, + dir, + &INTERNAL_CUS_CONTEXT_TEST.test_filename + ); + + TestMetadataKMS::InternalCustodianContext(INTERNAL_CUS_CONTEXT_TEST) + } + + fn gen_kms_fhe_key_handles(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(KMS_FHE_KEY_HANDLES_TEST.state); + let (_, private_sig_key) = gen_sig_keys(&mut rng); + store_versioned_auxiliary!( + &private_sig_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.sig_key_filename, + ); + + let dkg_params: DKGParams = DKGParams::WithSnS(convert_dkg_params_sns( + KMS_FHE_KEY_HANDLES_TEST.dkg_parameters_sns, + )); + let seed = Some(Seed(KMS_FHE_KEY_HANDLES_TEST.seed)); + + let client_key = generate_client_fhe_key(dkg_params, Tag::default(), seed); + store_versioned_auxiliary!( + &client_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.client_key_filename, + ); + + // The following code is basically the same as in `generate_fhe_keys` in + // `service/src/cryptography/central_kms.rs`, because we need to retrieve and save some of + // its intermediate values in order to be able to re-build a KmsFheKeyHandles in tests + let server_key = client_key.generate_server_key(); + let server_key = server_key.into_raw_parts(); + let decompression_key = server_key.3.clone(); + + store_versioned_auxiliary!( + &decompression_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.decompression_key_filename, + ); + + let server_key = ServerKey::from_raw_parts( + server_key.0, + server_key.1, + server_key.2, + server_key.3, + server_key.4, + server_key.5, + server_key.6, + server_key.7, + Tag::default(), + ); + + store_versioned_auxiliary!( + &server_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.server_key_filename, + ); + + let public_key = FhePublicKey::new(&client_key); + store_versioned_auxiliary!( + &public_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.public_key_filename, + ); + + let public_key_set = FhePubKeySet { + public_key, + server_key, + }; + + // NOTE: kms_fhe_key_handles.public_key_info is a HashMap + // so generation is not deterministic + let key_id = kms_grpc_0_13_20::RequestId::zeros(); + let preproc_id = kms_grpc_0_13_20::RequestId::zeros(); + let kms_fhe_key_handles = KmsFheKeyHandles::new( + &private_sig_key, + client_key, + &key_id, + &preproc_id, + &public_key_set, + decompression_key, + &dummy_domain(), + Vec::new(), // empty extra_data + ) + .unwrap(); + + store_versioned_test!( + &kms_fhe_key_handles, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename + ); + + TestMetadataKMS::KmsFheKeyHandles(KMS_FHE_KEY_HANDLES_TEST) + } + + fn gen_threshold_fhe_keys(dir: &PathBuf) -> TestMetadataKMS { + let role = Role::indexed_from_one(THRESHOLD_FHE_KEYS_TEST.role_i); + let mut base_session = get_networkless_base_session_for_parties( + THRESHOLD_FHE_KEYS_TEST.amount, + THRESHOLD_FHE_KEYS_TEST.threshold, + role, + ); + let dkg_params: DKGParams = DKGParams::WithSnS(convert_dkg_params_sns( + THRESHOLD_FHE_KEYS_TEST.dkg_parameters_sns, + )); + + let rt = Runtime::new().unwrap(); + let (fhe_pub_key_set, private_key_set) = rt.block_on(async { + insecure_initialize_key_material(&mut base_session, dkg_params, Tag::default()) + .await + .unwrap() + }); + store_versioned_auxiliary!( + &private_key_set, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.private_key_set_filename, + ); + + let (integer_server_key, _, _, _, sns_key, _, _, _, _) = + fhe_pub_key_set.server_key.clone().into_raw_parts(); + store_versioned_auxiliary!( + &sns_key, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.sns_key_filename, + ); + store_versioned_auxiliary!( + &integer_server_key, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.integer_server_key_filename, + ); + + // NOTE: this is not deterministic since the result is a HashMap + // compute_all_info doesn't exist in v0.11.1, so we create the metadata manually + let info: HashMap = HashMap::new(); + store_versioned_auxiliary!( + &info, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.info_filename, + ); + + let decompression_key = fhe_pub_key_set.server_key.to_owned().into_raw_parts().3; + store_versioned_auxiliary!( + &decompression_key, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.decompression_key_filename, + ); + + let public_material = PublicKeyMaterial::Uncompressed { + integer_server_key: std::sync::Arc::new(integer_server_key), + sns_key: sns_key.map(std::sync::Arc::new), + decompression_key: decompression_key.map(std::sync::Arc::new), + }; + let threshold_fhe_keys = ThresholdFheKeys::new( + std::sync::Arc::new(private_key_set), + public_material, + kms_0_13_20::engine::base::KeyGenMetadata::LegacyV0(info), + ); + + store_versioned_test!( + &threshold_fhe_keys, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename + ); + + TestMetadataKMS::ThresholdFheKeys(THRESHOLD_FHE_KEYS_TEST) + } + + /// Generates the _internal_ custodian setup message + fn gen_internal_cus_setup_msg(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_SETUP_MSG_TEST.state); + let (_verification_key, signing_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (private_key, public_key) = encryption.keygen().unwrap(); + let custodian = Custodian::new( + Role::indexed_from_one(1), + signing_key, + public_key, + private_key, + ) + .unwrap(); + let custodian_setup_message = custodian + .generate_setup_message(&mut rng, "custodian-1".to_string()) + .unwrap(); + store_versioned_test!( + &custodian_setup_message, + dir, + &INTERNAL_CUS_SETUP_MSG_TEST.test_filename + ); + TestMetadataKMS::InternalCustodianSetupMessage(INTERNAL_CUS_SETUP_MSG_TEST) + } + + fn gen_internal_cus_rec_out(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_REC_OUT_TEST.state); + let (operator_verification_key, _) = gen_sig_keys(&mut rng); + let mut buf = [0u8; 100]; + rng.fill_bytes(&mut buf); + let signcryption = UnifiedSigncryption { + payload: buf.to_vec(), + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }; + let icro = InternalCustodianRecoveryOutput { + signcryption, + custodian_role: Role::indexed_from_one(2), + operator_verification_key, + mpc_context_id: kms_grpc_0_13_20::RequestId::from_bytes( + INTERNAL_CUS_REC_OUT_TEST.mpc_context_id, + ), + }; + store_versioned_test!(&icro, dir, &INTERNAL_CUS_REC_OUT_TEST.test_filename); + TestMetadataKMS::InternalCustodianRecoveryOutput(INTERNAL_CUS_REC_OUT_TEST) + } + + fn gen_operator_backup_output(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(OPERATOR_BACKUP_OUTPUT_TEST.seed); + + let custodians: Vec<_> = (1..=OPERATOR_BACKUP_OUTPUT_TEST.custodian_count) + .map(|i| { + let (_verification_key, signing_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (private_key, public_key) = encryption.keygen().unwrap(); + Custodian::new( + Role::indexed_from_one(i), + signing_key, + public_key, + private_key, + ) + .unwrap() + }) + .collect(); + let custodian_messages: Vec<_> = custodians + .iter() + .enumerate() + .map(|(i, c)| { + c.generate_setup_message(&mut rng, format!("Custodian-{i}")) + .unwrap() + }) + .collect(); + + let operator = { + let (_verification_key, signing_key) = gen_sig_keys(&mut rng); + Operator::new_for_sharing( + custodian_messages, + signing_key, + OPERATOR_BACKUP_OUTPUT_TEST.custodian_threshold, + custodians.len(), + ) + .unwrap() + }; + let operator_backup_output = &operator + .secret_share_and_signcrypt( + &mut rng, + &OPERATOR_BACKUP_OUTPUT_TEST.plaintext, + RequestId::from_bytes(OPERATOR_BACKUP_OUTPUT_TEST.backup_id), + ) + .unwrap() + .ct_shares[&Role::indexed_from_one(1)]; + + store_versioned_test!( + operator_backup_output, + dir, + &OPERATOR_BACKUP_OUTPUT_TEST.test_filename + ); + TestMetadataKMS::OperatorBackupOutput(OPERATOR_BACKUP_OUTPUT_TEST) + } +} + +struct DistributedDecryptionV0_13_20; + +impl DistributedDecryptionV0_13_20 { + fn gen_prss_setup_rpoly_64(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(PRSS_SETUP_RPOLY_64_TEST.role_i); + let base_session = get_networkless_base_session_for_parties( + PRSS_SETUP_RPOLY_64_TEST.amount, + PRSS_SETUP_RPOLY_64_TEST.threshold, + role, + ); + let prss_setup = get_dummy_prss_setup::(base_session); + + store_versioned_test!(&prss_setup, dir, &PRSS_SETUP_RPOLY_64_TEST.test_filename); + + TestMetadataDD::PRSSSetup(PRSS_SETUP_RPOLY_64_TEST) + } + + fn gen_prss_setup_rpoly_128(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(PRSS_SETUP_RPOLY_128_TEST.role_i); + let base_session = get_networkless_base_session_for_parties( + PRSS_SETUP_RPOLY_128_TEST.amount, + PRSS_SETUP_RPOLY_128_TEST.threshold, + role, + ); + let prss_setup = get_dummy_prss_setup::(base_session); + + store_versioned_test!(&prss_setup, dir, &PRSS_SETUP_RPOLY_128_TEST.test_filename); + + TestMetadataDD::PRSSSetup(PRSS_SETUP_RPOLY_128_TEST) + } + + fn gen_prss_set_64(dir: &PathBuf) -> TestMetadataDD { + let mut rng = AesRng::seed_from_u64(PRSS_SET_64_TEST.state); + + let mut party_set = Vec::new(); + for i in 1..=PRSS_SET_64_TEST.amount_parties { + party_set.push(Role::indexed_from_one(i)); + } + + let mut set_key = [0u8; 16]; + rng.fill_bytes(&mut set_key); + + let mut f_a_points = Vec::new(); + for _ in 0..PRSS_SET_64_TEST.amount_points { + f_a_points.push(ResiduePolyF4Z64::from_scalar(Wrapping(rng.next_u64()))); + } + + let current_set = PrssSet::::new( + party_set.clone(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + let legacy_set = PrssSetV0::::new( + party_set.iter().map(|r| r.one_based()).collect(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + store_versioned_auxiliary!( + &legacy_set.upgrade().unwrap(), + dir, + &PRSS_SET_64_TEST.test_filename, + &PRSS_SET_64_TEST.legacy_filename, + ); + store_versioned_test!(¤t_set, dir, &PRSS_SET_64_TEST.test_filename); + + TestMetadataDD::PrssSet(PRSS_SET_64_TEST) + } + + fn gen_prss_set_128(dir: &PathBuf) -> TestMetadataDD { + let mut rng = AesRng::seed_from_u64(PRSS_SET_128_TEST.state); + + let mut party_set = Vec::new(); + for i in 1..=PRSS_SET_128_TEST.amount_parties { + party_set.push(Role::indexed_from_one(i)); + } + + let mut set_key = [0u8; 16]; + rng.fill_bytes(&mut set_key); + + let mut f_a_points = Vec::new(); + for _ in 0..PRSS_SET_128_TEST.amount_points { + f_a_points.push(ResiduePolyF4Z128::from_scalar(Wrapping( + rng.next_u64() as u128 + ))); + } + + let current_set = PrssSet::::new( + party_set.clone(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + let legacy_set = PrssSetV0::::new( + party_set.iter().map(|r| r.one_based()).collect(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + store_versioned_auxiliary!( + &legacy_set.upgrade().unwrap(), + dir, + &PRSS_SET_128_TEST.test_filename, + &PRSS_SET_128_TEST.legacy_filename, + ); + store_versioned_test!(¤t_set, dir, &PRSS_SET_128_TEST.test_filename); + + TestMetadataDD::PrssSet(PRSS_SET_128_TEST) + } + + fn gen_share_64(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(SHARE_64_TEST.owner); + let val = ResiduePolyF4Z64::from_scalar(Wrapping(SHARE_64_TEST.value as u64)); + let share = Share::::new(role, val); + + store_versioned_test!(&share, dir, &SHARE_64_TEST.test_filename); + + TestMetadataDD::Share(SHARE_64_TEST) + } + + fn gen_share_128(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(SHARE_128_TEST.owner); + let val = ResiduePolyF4Z128::from_scalar(Wrapping(SHARE_128_TEST.value)); + let share = Share::::new(role, val); + + store_versioned_test!(&share, dir, &SHARE_128_TEST.test_filename); + + TestMetadataDD::Share(SHARE_128_TEST) + } + + fn gen_prf_key(dir: &PathBuf) -> TestMetadataDD { + let mut buf = [0u8; 16]; + let mut rng = AesRng::from_seed(PRF_KEY_TEST.seed.to_le_bytes()); + rng.fill_bytes(&mut buf); + + let prf_key = PrfKey(buf); + + store_versioned_test!(&prf_key, dir, &PRF_KEY_TEST.test_filename); + + TestMetadataDD::PrfKey(PRF_KEY_TEST) + } + + fn gen_release_pcr_values(dir: &PathBuf) -> TestMetadataDD { + let mut rng = AesRng::seed_from_u64(RELEASE_PCR_VALUES_TEST.state); + let mut pcr0 = [0u8; 64]; + rng.fill_bytes(&mut pcr0); + let mut pcr1 = [0u8; 33]; + rng.fill_bytes(&mut pcr1); + let mut pcr2 = [0u8; 73]; + rng.fill_bytes(&mut pcr2); + + let pcr_values = ReleasePCRValues { + pcr0: pcr0.to_vec(), + pcr1: pcr1.to_vec(), + pcr2: pcr2.to_vec(), + }; + + store_versioned_test!(&pcr_values, dir, &RELEASE_PCR_VALUES_TEST.test_filename); + + TestMetadataDD::ReleasePCRValues(RELEASE_PCR_VALUES_TEST) + } +} + +struct KmsGrpcV0_13_20; + +impl KmsGrpcV0_13_20 { + fn gen_signed_pub_data_handle_internal(dir: &PathBuf) -> TestMetadataKmsGrpc { + let signed_pub_data_handle_internal = SignedPubDataHandleInternal::new( + SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.key_handle.to_string(), + SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.signature.to_vec(), + SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST + .external_signature + .to_vec(), + ); + + store_versioned_test!( + &signed_pub_data_handle_internal, + dir, + &SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.test_filename + ); + + TestMetadataKmsGrpc::SignedPubDataHandleInternal(SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST) + } + + fn gen_pub_data_type(dir: &PathBuf) -> TestMetadataKmsGrpc { + let pub_data_type = PubDataType::DecompressionKey; + store_versioned_test!(&pub_data_type, dir, &PUB_DATA_TYPE.test_filename); + + TestMetadataKmsGrpc::PubDataType(PUB_DATA_TYPE) + } + + fn gen_priv_data_type(dir: &PathBuf) -> TestMetadataKmsGrpc { + let priv_data_type = PrivDataType::ContextInfo; + store_versioned_test!(&priv_data_type, dir, &PRIV_DATA_TYPE.test_filename); + + TestMetadataKmsGrpc::PrivDataType(PRIV_DATA_TYPE) + } +} + +impl KMSCoreVersion for V0_14_0 { + const VERSION_NUMBER: &'static str = "0.14.0"; + + // Without this, some keys will be generated differently every time we run the script + fn seed_prng(seed: u128) { + let mut seeder = DeterministicSeeder::::new(Seed(seed)); + let shortint_engine = ShortintEngine::new_from_seeder(&mut seeder); + ShortintEngine::with_thread_local_mut(|local_engine| { + let _ = std::mem::replace(local_engine, shortint_engine); + }); + } + + fn gen_kms_data() -> Vec { + let dir = Self::data_dir().join(KMS_MODULE_NAME); + create_dir_all(&dir).unwrap(); + + vec![ + KmsV0_13_20::gen_private_sig_key(&dir), + KmsV0_13_20::gen_public_sig_key(&dir), + KmsV0_13_20::gen_app_key_blob(&dir), + KmsV0_13_20::gen_key_gen_metadata(&dir), + KmsV0_13_20::gen_crs_metadata(&dir), + KmsV0_13_20::gen_key_gen_metadata_with_extra_data(&dir), + KmsV0_13_20::gen_crs_metadata_with_extra_data(&dir), + KmsV0_13_20::gen_typed_plaintext(&dir), + KmsV0_13_20::gen_signcryption_payload(&dir), + KmsV0_13_20::gen_signcryption_key(&dir), + KmsV0_13_20::gen_designcryption_key(&dir), + KmsV0_13_20::gen_unified_signcryption(&dir), + KmsV0_13_20::gen_backup_ciphertext(&dir), + KmsV0_13_20::gen_unified_cipher(&dir), + KmsV0_13_20::gen_hybrid_kem_ct(&dir), + KmsV0_13_20::gen_prss_setup_combined(&dir), + KmsV0_13_20::gen_context_info(&dir), + KmsV0_13_20::gen_node_info(&dir), + KmsV0_13_20::gen_software_version(&dir), + KmsV0_13_20::gen_recovery_material(&dir), + KmsV0_13_20::gen_internal_recovery_request(&dir), + KmsV0_13_20::gen_internal_cus_context_handles(&dir), + KmsV0_13_20::gen_internal_cus_setup_msg(&dir), + KmsV0_13_20::gen_kms_fhe_key_handles(&dir), + KmsV0_13_20::gen_threshold_fhe_keys(&dir), + KmsV0_13_20::gen_internal_cus_rec_out(&dir), + KmsV0_13_20::gen_operator_backup_output(&dir), + ] + } + + fn gen_threshold_fhe_data() -> Vec { + let dir = Self::data_dir().join(DISTRIBUTED_DECRYPTION_MODULE_NAME); + create_dir_all(&dir).unwrap(); + + vec![ + DistributedDecryptionV0_13_20::gen_prss_setup_rpoly_64(&dir), + DistributedDecryptionV0_13_20::gen_prss_setup_rpoly_128(&dir), + DistributedDecryptionV0_13_20::gen_prss_set_64(&dir), + DistributedDecryptionV0_13_20::gen_prss_set_128(&dir), + DistributedDecryptionV0_13_20::gen_share_64(&dir), + DistributedDecryptionV0_13_20::gen_share_128(&dir), + DistributedDecryptionV0_13_20::gen_prf_key(&dir), + DistributedDecryptionV0_13_20::gen_release_pcr_values(&dir), + ] + } + + fn gen_kms_grpc_data() -> Vec { + let dir = Self::data_dir().join(KMS_GRPC_MODULE_NAME); + create_dir_all(&dir).unwrap(); + + vec![ + KmsGrpcV0_13_20::gen_signed_pub_data_handle_internal(&dir), + KmsGrpcV0_13_20::gen_pub_data_type(&dir), + KmsGrpcV0_13_20::gen_priv_data_type(&dir), + ] + } +} diff --git a/backward-compatibility/generate-v0.14.0/src/generate.rs b/backward-compatibility/generate-v0.14.0/src/generate.rs new file mode 100644 index 0000000000..398b485da3 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/generate.rs @@ -0,0 +1,174 @@ +//! Utility functions, traits and macros to generate and store versioned data for any kms-core version. + +use std::{ + borrow::Cow, + fs, + path::{Path, PathBuf}, +}; + +use serde::Serialize; +use tfhe_versionable_0_7::Versionize as Versionize_0_7; + +use backward_compatibility::{ + data_dir, dir_for_version, + parameters::{ + ClassicPBSParametersTest, DKGParamsRegularTest, DKGParamsSnSTest, + SwitchAndSquashCompressionParametersTest, SwitchAndSquashParametersTest, + }, + TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc, +}; + +// Parameters set for tests in kms-core 0.9, found in `PARAMS_TEST_BK_SNS`. However, for stability +// reasons, these should never change. +// For `DKGParamsRegularTest`, parameters `dedicated_compact_public_key_parameters` and +// `compression_decompression_parameters` are not included because they are optional tfhe-rs types, +// which means their backward compatibility is already tested. +pub const TEST_DKG_PARAMS_SNS: DKGParamsSnSTest = DKGParamsSnSTest { + regular_params: DKGParamsRegularTest { + sec: 128, + ciphertext_parameters: ClassicPBSParametersTest { + lwe_dimension: 10, + glwe_dimension: 1, + polynomial_size: 256, + lwe_noise_gaussian: 0, + glwe_noise_gaussian: 0, + pbs_base_log: 16, + pbs_level: 1, + ks_base_log: 14, + ks_level: 1, + message_modulus: 4, + carry_modulus: 4, + max_noise_level: 5, + log2_p_fail: -49.5137, // dummy parameter + encryption_key_choice: Cow::Borrowed("big"), + }, + flag: true, + }, + sns_params: SwitchAndSquashParametersTest { + glwe_dimension: 1, + glwe_noise_distribution: 0, + polynomial_size: 256, + pbs_base_log: 32, + pbs_level: 2, + message_modulus: 4, + carry_modulus: 4, + }, + sns_compression_parameters: SwitchAndSquashCompressionParametersTest { + packing_ks_level: 1, + packing_ks_base_log: 16, + packing_ks_polynomial_size: 256, + packing_ks_glwe_dimension: 1, + lwe_per_glwe: 10, + packing_ks_key_noise_distribution: 0, + message_modulus: 4, + carry_modulus: 4, + }, +}; + +pub fn save_bcode>(msg: &Data, path: P) { + // Use bincode 2.x API with legacy config to match bc2wrap behavior + let config = bincode::config::legacy().with_fixed_int_encoding(); + let encoded = bincode::serde::encode_to_vec(msg, config).unwrap(); + fs::write(path, encoded).unwrap(); +} + +/// Stores the test data in `dir`, encoded in bincode, using the right tfhe-versionable version +macro_rules! define_store_versioned_test_fn { + ($fn_name:ident, $versionize_trait:ident) => { + pub fn $fn_name>( + msg: &Data, + dir: P, + test_filename: &str, + ) { + let versioned = msg.versionize(); + + // Store in bincode + let filename_bincode = format!("{}.bcode", test_filename); + save_bcode(&versioned, dir.as_ref().join(filename_bincode)); + } + }; +} +define_store_versioned_test_fn!(store_versioned_test_05, Versionize_0_7); + +/// Stores the auxiliary data in `dir`, encoded in bincode, using the right tfhe-versionable version +macro_rules! define_store_versioned_auxiliary_fn { + ($fn_name:ident, $versionize_trait:ident) => { + pub fn $fn_name>( + msg: &Data, + dir: P, + test_name: &str, + filename: &str, + ) { + let versioned = msg.versionize(); + + // Store in bincode + let filename_bincode = format!("{}.bcode", filename); + let sub_dir_name = format!("auxiliary_{}", test_name); + let sub_dir = dir.as_ref().join(&sub_dir_name); + fs::create_dir_all(&sub_dir).unwrap(); + save_bcode( + &versioned, + dir.as_ref().join(sub_dir_name).join(filename_bincode), + ); + } + }; +} +define_store_versioned_auxiliary_fn!(store_versioned_auxiliary_05, Versionize_0_7); + +pub fn store_metadata(new_data: &Vec, path: P) +where + Meta: Serialize + serde::de::DeserializeOwned + Clone, + P: AsRef, +{ + let path = path.as_ref(); + + // If file doesn't exist, just write the new data + if !path.exists() { + let serialized = + ron::ser::to_string_pretty(new_data, ron::ser::PrettyConfig::default()).unwrap(); + fs::write(path, serialized).unwrap(); + return; + } + + // Load existing metadata + let existing_content = fs::read_to_string(path).unwrap(); + let mut combined_data: Vec = + ron::from_str(&existing_content).expect("Failed to deserialize existing metadata"); + + // Append new entries + combined_data.extend_from_slice(new_data); + + // Write combined data + let serialized = + ron::ser::to_string_pretty(&combined_data, ron::ser::PrettyConfig::default()).unwrap(); + fs::write(path, serialized).unwrap(); +} + +pub trait KMSCoreVersion { + const VERSION_NUMBER: &'static str; + + fn data_dir() -> PathBuf { + let base_data_dir = data_dir(); + dir_for_version(base_data_dir, Self::VERSION_NUMBER) + } + + /// How to fix the prng seed for this version to make sure the generated (public) keys do not change every time we run the script + fn seed_prng(seed: u128); + + /// Generates data for the KMS module for this version. + /// This should create KMS-core types, versionize them and store them into the version specific directory. + /// The metadata for the generated tests should be returned in the same order that the tests will be run. + fn gen_kms_data() -> Vec; + + /// Generates data for the KMG grpc module for this version. + /// This should create types from kms-grpc, + /// versionize them and store them into the version specific directory. + /// The metadata for the generated tests should be returned in the same order that the tests will be run. + fn gen_kms_grpc_data() -> Vec; + + /// Generates data for the distributed decryption module for this version. + /// This should create types from distributed decryption, + /// versionize them and store them into the version specific directory. + /// The metadata for the generated tests should be returned in the same order that the tests will be run. + fn gen_threshold_fhe_data() -> Vec; +} diff --git a/backward-compatibility/generate-v0.14.0/src/lib.rs b/backward-compatibility/generate-v0.14.0/src/lib.rs new file mode 100644 index 0000000000..6a8eb286f2 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/lib.rs @@ -0,0 +1,7 @@ +//! Data generation utilities for backward compatibility tests. +//! +//! This crate is separate from `backward-compatibility` to isolate version-specific +//! dependencies (like old KMS versions) from the test loading and execution logic. + +pub mod data_0_13; +pub mod generate; diff --git a/backward-compatibility/generate-v0.14.0/src/main.rs b/backward-compatibility/generate-v0.14.0/src/main.rs new file mode 100644 index 0000000000..9e2aaf50a9 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/main.rs @@ -0,0 +1,64 @@ +//! Main file to run for generating all the versioned data for all kms-core versions. + +use backward_compatibility::{ + data_dir, TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc, Testcase, + DISTRIBUTED_DECRYPTION_MODULE_NAME, KMS_GRPC_MODULE_NAME, KMS_MODULE_NAME, PRNG_SEED, +}; +use backward_compatibility_generate_v0_13_20::{ + data_0_13::V0_13_20, + generate::{store_metadata, KMSCoreVersion}, +}; + +// Type aliases +type KmsTestcases = Vec>; +type KmsGrpcTestcases = Vec>; +type DdTestcases = Vec>; + +fn gen_testcases( + gen_data_fn: F, + module_name: &str, +) -> Vec> +where + F: Fn() -> Vec, + Metadata: Clone, +{ + let tests = gen_data_fn(); + + tests + .iter() + .map(|metadata| Testcase { + kms_core_version_min: Vers::VERSION_NUMBER.to_string(), + kms_core_module: module_name.to_string(), + metadata: metadata.clone(), + }) + .collect() +} + +fn gen_all_data() -> (KmsTestcases, KmsGrpcTestcases, DdTestcases) { + // Seed TFHE-rs' key generation PRNG + Vers::seed_prng(PRNG_SEED); + + let kms_testcases = + gen_testcases::(Vers::gen_kms_data, KMS_MODULE_NAME); + + let kms_grpc_testcases = gen_testcases::( + Vers::gen_kms_grpc_data, + KMS_GRPC_MODULE_NAME, + ); + + let dd_testcases = gen_testcases::( + Vers::gen_threshold_fhe_data, + DISTRIBUTED_DECRYPTION_MODULE_NAME, + ); + + (kms_testcases, kms_grpc_testcases, dd_testcases) +} + +fn main() { + let (kms_testcases, kms_grpc_testcases, dd_testcases) = gen_all_data::(); + + // Use module name as the filename prefix + store_metadata(&kms_testcases, data_dir().join("kms.ron")); + store_metadata(&kms_grpc_testcases, data_dir().join("kms-grpc.ron")); + store_metadata(&dd_testcases, data_dir().join("threshold-fhe.ron")); +} From 210453aa5e8d15cdc49e47e38a720111624c197f Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 16:11:54 +0200 Subject: [PATCH 07/29] chore: updated backwards compatibility tests --- Cargo.lock | 38 +- Cargo.toml | 3 +- Makefile | 6 +- ai-docs/COMMANDS.md | 1 + backward-compatibility/ADDING_NEW_VERSIONS.md | 5 +- backward-compatibility/Cargo.toml | 2 +- .../auxiliary_threshold_fhe_keys/info.bcode | 2 +- .../data/0_11_0/kms/threshold_fhe_keys.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_10/kms/key_gen_metadata.bcode | 2 +- .../0_13_10/kms/kms_fhe_key_handles.bcode | 2 +- .../internal_custodian_recovery_output.bcode | 3 - .../internal_custodian_setup_message.bcode | 2 +- .../kms/internal_recovery_request.bcode | 3 - .../key_gen_metadata_with_extra_data.bcode | 2 +- .../0_13_20/kms/kms_fhe_key_handles.bcode | 2 +- .../0_13_20/kms/operator_backup_output.bcode | 3 - .../data/0_13_20/kms/recovery_material.bcode | 3 - .../data/0_14_0/kms-grpc/priv_data_type.bcode | 3 + .../data/0_14_0/kms-grpc/pub_data_type.bcode | 3 + .../signed_pub_data_handle_internal.bcode | 3 + .../data/0_14_0/kms/app_key_blob.bcode | 3 + .../unified_ciphertext_handle.bcode | 3 + .../legacy_crs_gen_metadata.bcode | 3 + .../unified_enc_key_handle.bcode | 3 + .../legacy_key_gen_metadata.bcode | 3 + .../client_key_handle.bcode | 3 + .../decompression_key.bcode | 3 + .../public_key_handle.bcode | 3 + .../server_key_handle.bcode | 3 + .../sig_key_handle.bcode | 3 + .../prss_setup_128.bcode | 3 + .../prss_setup_64.bcode | 3 + .../internal_cus_context_handle.bcode | 0 .../decompression_key.bcode | 3 + .../auxiliary_threshold_fhe_keys/info.bcode | 3 + .../integer_server_key.bcode | 3 + .../private_key_set.bcode | 3 + .../sns_key.bcode | 3 + .../hybrid_kem_ct_handle.bcode | 3 + .../data/0_14_0/kms/backup_ciphertext.bcode | 3 + .../data/0_14_0/kms/context_info.bcode | 3 + .../data/0_14_0/kms/crs_gen_metadata.bcode | 3 + .../crs_gen_metadata_with_extra_data.bcode | 3 + .../data/0_14_0/kms/designcryption_key.bcode | 3 + .../data/0_14_0/kms/hybrid_kem_ct.bcode | 3 + .../0_14_0/kms/internal_cus_context.bcode | 3 + .../internal_custodian_recovery_output.bcode | 3 + .../internal_custodian_setup_message.bcode | 3 + .../kms/internal_recovery_request.bcode | 3 + .../data/0_14_0/kms/key_gen_metadata.bcode | 3 + .../key_gen_metadata_with_extra_data.bcode | 3 + .../data/0_14_0/kms/kms_fhe_key_handles.bcode | 3 + .../data/0_14_0/kms/node_info.bcode | 3 + .../0_14_0/kms/operator_backup_output.bcode | 3 + .../data/0_14_0/kms/private_sig_key.bcode | 3 + .../data/0_14_0/kms/prss_setup_combined.bcode | 3 + .../data/0_14_0/kms/public_sig_key.bcode | 3 + .../data/0_14_0/kms/recovery_material.bcode | 3 + .../data/0_14_0/kms/signcryption_key.bcode | 3 + .../0_14_0/kms/signcryption_payload.bincode | Bin 0 -> 29 bytes .../data/0_14_0/kms/software_version.bcode | 3 + .../data/0_14_0/kms/threshold_fhe_keys.bcode | 3 + .../data/0_14_0/kms/typed_plaintext.bincode | Bin 0 -> 17 bytes .../data/0_14_0/kms/unified_ciphertext.bcode | 3 + .../0_14_0/kms/unified_signcryption.bcode | 3 + .../legacy_prss_set_128.bcode | 3 + .../legacy_prss_set_64.bcode | 3 + .../data/0_14_0/threshold-fhe/prf_key.bcode | 3 + .../0_14_0/threshold-fhe/prss_set_128.bcode | 3 + .../0_14_0/threshold-fhe/prss_set_64.bcode | 3 + .../threshold-fhe/prss_setup_rpoly_128.bcode | 3 + .../threshold-fhe/prss_setup_rpoly_64.bcode | 3 + .../threshold-fhe/release_pcr_values.bcode | 3 + .../data/0_14_0/threshold-fhe/share_128.bcode | 3 + .../data/0_14_0/threshold-fhe/share_64.bcode | 3 + backward-compatibility/data/kms-grpc.ron | 25 + backward-compatibility/data/kms.ron | 378 +- backward-compatibility/data/threshold-fhe.ron | 82 + .../generate-v0.11.0/Cargo.lock | 2 +- .../generate-v0.11.1/Cargo.lock | 2 +- .../generate-v0.13.0/Cargo.lock | 2 +- .../generate-v0.13.10/Cargo.lock | 2 +- .../generate-v0.13.20/Cargo.lock | 2 +- .../generate-v0.13.20/src/data_0_13.rs | 267 +- .../generate-v0.14.0/Cargo.lock | 8090 +++++++++++++++++ .../generate-v0.14.0/src/data_0_14.rs | 148 +- .../generate-v0.14.0/src/lib.rs | 2 +- .../generate-v0.14.0/src/main.rs | 6 +- docs/developer/backward_compatibility.md | 4 + 90 files changed, 8873 insertions(+), 387 deletions(-) delete mode 100644 backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/recovery_material.bcode create mode 100644 backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode create mode 100644 backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode create mode 100644 backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/app_key_blob.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode rename backward-compatibility/data/{0_13_20 => 0_14_0}/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode (100%) create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/context_info.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/designcryption_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/node_info.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/private_sig_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/public_sig_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/recovery_material.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/signcryption_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/signcryption_payload.bincode create mode 100644 backward-compatibility/data/0_14_0/kms/software_version.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/typed_plaintext.bincode create mode 100644 backward-compatibility/data/0_14_0/kms/unified_ciphertext.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/unified_signcryption.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/auxiliary_prss_set_128/legacy_prss_set_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/auxiliary_prss_set_64/legacy_prss_set_64.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prf_key.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_set_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_set_64.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_setup_rpoly_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_setup_rpoly_64.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/release_pcr_values.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/share_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/share_64.bcode create mode 100644 backward-compatibility/generate-v0.14.0/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index 12aa83646d..5e948fd64e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1763,7 +1763,7 @@ dependencies = [ [[package]] name = "backward-compatibility" -version = "0.13.20" +version = "0.14.0" dependencies = [ "bincode 1.3.3", "ron 0.10.1", @@ -3030,7 +3030,7 @@ dependencies = [ [[package]] name = "error-utils" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "tracing", @@ -3065,7 +3065,7 @@ dependencies = [ [[package]] name = "experiments" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "anyhow", @@ -3386,7 +3386,7 @@ checksum = "312d2295c7302019c395cfb90dacd00a82a2eabd700429bba9c7a3f38dbbe11b" [[package]] name = "generate-test-material" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "clap", @@ -4217,7 +4217,7 @@ dependencies = [ [[package]] name = "kms" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes", "aes-gcm", @@ -4313,7 +4313,7 @@ dependencies = [ [[package]] name = "kms-core-client" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "alloy-primitives", @@ -4359,7 +4359,7 @@ dependencies = [ [[package]] name = "kms-grpc" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -4387,7 +4387,7 @@ dependencies = [ [[package]] name = "kms-health-check" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "clap", @@ -4912,7 +4912,7 @@ dependencies = [ [[package]] name = "observability" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "axum", @@ -7358,7 +7358,7 @@ dependencies = [ [[package]] name = "test-utils" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "bc2wrap", @@ -7369,11 +7369,11 @@ dependencies = [ [[package]] name = "test-utils-cc" -version = "0.13.20-0" +version = "0.14.0-0" [[package]] name = "test-utils-service" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "quote", "syn 2.0.114", @@ -7544,7 +7544,7 @@ dependencies = [ [[package]] name = "thread-handles" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "error-utils", @@ -7574,7 +7574,7 @@ dependencies = [ [[package]] name = "threshold-algebra" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "anyhow", @@ -7601,7 +7601,7 @@ dependencies = [ [[package]] name = "threshold-bgv" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "anyhow", @@ -7629,7 +7629,7 @@ dependencies = [ [[package]] name = "threshold-execution" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes", "aes-prng", @@ -7677,7 +7677,7 @@ dependencies = [ [[package]] name = "threshold-hashing" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "bc2wrap", @@ -7687,7 +7687,7 @@ dependencies = [ [[package]] name = "threshold-networking" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "async-trait", @@ -7724,7 +7724,7 @@ dependencies = [ [[package]] name = "threshold-types" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 9099c1f42a..79da97c000 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ # backward-compatibility/generate-v0.13.0 - Data generation for v0.13.0 with old KMS version dependencies # backward-compatibility/generate-v0.13.10 - Data generation for v0.13.10 with old KMS version dependencies # backward-compatibility/generate-v0.13.20 - Data generation for v0.13.20 with old KMS version dependencies +# backward-compatibility/generate-v0.14.0 - Data generation for v0.14.0 with old KMS version dependencies # # The generate crates need to import old KMS versions (e.g., v0.11.0, v0.11.1) which conflict with the # current workspace dependencies, creating name conflicts as described in: @@ -37,7 +38,7 @@ members = [ # Note: It's not possible to only generate the lock file using specific features as the resolver # builds the graph as if all features are enabled: # https://doc.rust-lang.org/cargo/reference/resolver.html#features -exclude = ["backward-compatibility", "backward-compatibility/generate-v0.11.0", "backward-compatibility/generate-v0.11.1", "backward-compatibility/generate-v0.13.0", "backward-compatibility/generate-v0.13.10", "backward-compatibility/generate-v0.13.20"] +exclude = ["backward-compatibility", "backward-compatibility/generate-v0.11.0", "backward-compatibility/generate-v0.11.1", "backward-compatibility/generate-v0.13.0", "backward-compatibility/generate-v0.13.10", "backward-compatibility/generate-v0.13.20", "backward-compatibility/generate-v0.14.0"] [workspace.package] authors = ["Zama"] diff --git a/Makefile b/Makefile index 7993c565a4..44f92eadf7 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ clean-backward-compatibility-data: rm -rf backward-compatibility/data/0_13_0 rm -rf backward-compatibility/data/0_13_10 rm -rf backward-compatibility/data/0_13_20 + rm -rf backward-compatibility/data/0_14_0 generate-backward-compatibility-v0.11.0: cd backward-compatibility/generate-v0.11.0 && cargo run --release @@ -58,7 +59,10 @@ generate-backward-compatibility-v0.13.10: generate-backward-compatibility-v0.13.20: cd backward-compatibility/generate-v0.13.20 && cargo run --release -generate-backward-compatibility-all: clean-backward-compatibility-data generate-backward-compatibility-v0.11.0 generate-backward-compatibility-v0.11.1 generate-backward-compatibility-v0.13.0 generate-backward-compatibility-v0.13.10 generate-backward-compatibility-v0.13.20 +generate-backward-compatibility-v0.14.0: + cd backward-compatibility/generate-v0.14.0 && cargo run --release + +generate-backward-compatibility-all: clean-backward-compatibility-data generate-backward-compatibility-v0.11.0 generate-backward-compatibility-v0.11.1 generate-backward-compatibility-v0.13.0 generate-backward-compatibility-v0.13.10 generate-backward-compatibility-v0.13.20 generate-backward-compatibility-v0.14.0 @echo "Generated backward compatibility data for all versions" # Test material generation targets diff --git a/ai-docs/COMMANDS.md b/ai-docs/COMMANDS.md index 2206faa4e2..9a66e4d9ed 100644 --- a/ai-docs/COMMANDS.md +++ b/ai-docs/COMMANDS.md @@ -94,6 +94,7 @@ make generate-backward-compatibility-v0.11.1 make generate-backward-compatibility-v0.13.0 make generate-backward-compatibility-v0.13.10 make generate-backward-compatibility-v0.13.20 +make generate-backward-compatibility-v0.14.0 ``` Clean all generated BC data: diff --git a/backward-compatibility/ADDING_NEW_VERSIONS.md b/backward-compatibility/ADDING_NEW_VERSIONS.md index 36e14ed1e6..6452f8c9df 100644 --- a/backward-compatibility/ADDING_NEW_VERSIONS.md +++ b/backward-compatibility/ADDING_NEW_VERSIONS.md @@ -117,7 +117,10 @@ make test-backward-compatibility-local |----------------|--------------|--------------|------------------|--------| | `generate-v0.11.0` | `backward-compatibility-generate-v0-11-0` | v0.11.0 | serde 1.0.219, alloy 1.1.2, tfhe 1.3.2 | ✅ Active | | `generate-v0.11.1` | `backward-compatibility-generate-v0-11-1` | v0.11.1 | serde 1.0.226, alloy 1.3.1, tfhe 1.3.3 | ✅ Active | -| `generate-v0.12.0` | `backward-compatibility-generate-v0-12-0` | v0.12.0+ | TBD | 🚧 Future (when needed) | +| `generate-v0.13.0` | `backward-compatibility-generate-v0-13-0` | v0.13.0 | — | ✅ Active | +| `generate-v0.13.10` | `backward-compatibility-generate-v0-13-10` | v0.13.10 | — | ✅ Active | +| `generate-v0.13.20` | `backward-compatibility-generate-v0-13-20` | v0.13.20 | — | ✅ Active | +| `generate-v0.14.0` | `backward-compatibility-generate-v0-14-0` | v0.14.0 | tfhe-versionable 0.7.0, tfhe 1.6.1, alloy 1.4.1, serde 1.0.228 | ✅ Active | **Note**: v0.11.0 and v0.11.1 require separate generators due to incompatible alloy and tfhe versions. diff --git a/backward-compatibility/Cargo.toml b/backward-compatibility/Cargo.toml index f3cef7fa42..d8ecb45971 100644 --- a/backward-compatibility/Cargo.toml +++ b/backward-compatibility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "backward-compatibility" -version = "0.13.20" +version = "0.14.0" publish = false authors = ["Zama"] edition = "2021" diff --git a/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode b/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode index 4b468d6c29..859256079b 100644 --- a/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode +++ b/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2079954959214cb0402a05eddc27240ed4d2ddce6303134f601e109bd4f3eabf +oid sha256:922354a6e88322f5567e99dc6689258f40db225cc91876b74f2881e71507cdef size 482 diff --git a/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode b/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode index ba693728a4..376c1a3614 100644 --- a/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode +++ b/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9d8b7fb017c1af4401f357d39c4314780797f2fa28093f2aa19267ea2979f51 +oid sha256:c7e4f57268fea99a49d5cb877e2382aece2f1e45ea79ebb012e64fc907115afa size 505527 diff --git a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index d761bf957d..3e915b7200 100644 --- a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 +oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 size 468 diff --git a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode index c08bd87f6f..aff78c52fe 100644 --- a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62f8b355d53250052ce835b22a04b5911c2b196013e00fb446baf87927584134 +oid sha256:d11d0c555157f483446fd64c71c694019f4ffff92c8604ace43b8a828d952a43 size 245 diff --git a/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode index 01f8f8a85c..501fb29423 100644 --- a/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2190f3e6afd35d3c1da4fe9e058d90c4b6e25febe03de181343db0170465d2b0 +oid sha256:56a6f47fe169b963fdc1b33bc3a74245d66832b22f62261679bee85a0dc5013e size 11208 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode deleted file mode 100644 index 38cdf921d8..0000000000 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5a79b59689143dadc62d606abd3fe5921a14fc7971d620dd246645d8368374f -size 221 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode index c0670eafbe..44cd00f904 100644 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d17f1327cf70ca328c34ea554861058aad9dc723d4801405a1273fbd9af6645b +oid sha256:271029c25928bcf107d5843363b3d604fcc6ce289e63191e2d86c60d9dc392f8 size 992 diff --git a/backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode b/backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode deleted file mode 100644 index d3e042756e..0000000000 --- a/backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:131b45495e950de30f57d751f78f662d939fb50fa91265d5aaca4365b92b9bef -size 1665 diff --git a/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode index 0a44396d4c..a35ae27c47 100644 --- a/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode +++ b/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac0ded3ade3242ce472ecb8ff691834667b04d6c648f0535ff1028e627449ee2 +oid sha256:11575ae3f8530dde09f753f69c754bde1a07d7185290bf0725545675e877ea8f size 258 diff --git a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode index 397b91584f..a509ba13bc 100644 --- a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 +oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 size 11318 diff --git a/backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode b/backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode deleted file mode 100644 index 7c24373275..0000000000 --- a/backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9622e8a05c3c04d5f8d74a5a9f9460b6be883f061ef3e9e49252553f2e50b7b -size 1260 diff --git a/backward-compatibility/data/0_13_20/kms/recovery_material.bcode b/backward-compatibility/data/0_13_20/kms/recovery_material.bcode deleted file mode 100644 index 6365f46725..0000000000 --- a/backward-compatibility/data/0_13_20/kms/recovery_material.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7c3a25b30266ea83f46f55e42aa155f7216e069f9cf79613c4a06163770c1b24 -size 6482 diff --git a/backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode b/backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode new file mode 100644 index 0000000000..b2e9f64332 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:971e061b731ff27510e9b78027b92e5b3a22b1516c53019c14ae9e74d5d7a7c4 +size 8 diff --git a/backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode b/backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode new file mode 100644 index 0000000000..b62995ce4f --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20aef0af2bb62267e2f5c157abdc51d1ce6506e42478ae204f1fab5494907df1 +size 8 diff --git a/backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode b/backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode new file mode 100644 index 0000000000..439029a680 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d76555cde90e2b212e529fa05e5c428ea200ba637dd53f485817595423299ce0 +size 44 diff --git a/backward-compatibility/data/0_14_0/kms/app_key_blob.bcode b/backward-compatibility/data/0_14_0/kms/app_key_blob.bcode new file mode 100644 index 0000000000..fdb0e7f1cf --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/app_key_blob.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7411ad8b97e02c52a39389c59d226ae7023b645602abdfca152896fc94d7cb5b +size 88 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode new file mode 100644 index 0000000000..a4ac29fe9d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7baef0c10c9546e08c07e7e10b9ac5c8ef5438193a993aa1e50b0f1b4d0ce730 +size 116 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode new file mode 100644 index 0000000000..5b6ad3bd60 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e8d2cda4e6186846e6c81b978d8646d99805908fcada7fb1e4d69bc2ea4a50a +size 222 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode new file mode 100644 index 0000000000..80a9fd8578 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e9ad274fccc8176b8ca752b0775d7e5204ef04977f3110e03a967d5625463e8 +size 816 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode new file mode 100644 index 0000000000..d761bf957d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 +size 468 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode new file mode 100644 index 0000000000..992e387d7d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f47cd611b9ba112924afc627df465f83d64ff34266bb74b84f551350c84661d3 +size 11059 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode new file mode 100644 index 0000000000..32c4a8b118 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d +size 1 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode new file mode 100644 index 0000000000..daef644183 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a6baad25bd21e9d66fa8f0dbade36139963ed943bddf0d17301baa7bfed7b17 +size 4296 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode new file mode 100644 index 0000000000..65aa9880cb --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b705dbae3823bd53f081785cc16fd5c8882972cf1c4aef072805855e150153e7 +size 2612531 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode new file mode 100644 index 0000000000..46be201c75 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a70af30268a5a16d1e92329ff520c86ed3de334ce84c223cf0dc722f8b747d +size 44 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode new file mode 100644 index 0000000000..add992a846 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca00fd2c83f16696111d5b1664a7c01e5280e0797e34a7914f4ff4d3d9d83371 +size 571344 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode new file mode 100644 index 0000000000..54e23ac21b --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f636676db5e96976a8f40d0997fc194dd60f95597ef95a40e1f0105537054447 +size 363344 diff --git a/backward-compatibility/data/0_13_20/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode similarity index 100% rename from backward-compatibility/data/0_13_20/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode rename to backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode new file mode 100644 index 0000000000..32c4a8b118 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d +size 1 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode new file mode 100644 index 0000000000..a2b71017a4 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af5570f5a1810b7af78caf4bc70a660f0df51e42baf91d4de5b2328de0e83dfc +size 8 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode new file mode 100644 index 0000000000..0b14506e98 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24d4c40af16d1e88b3f487377e58650f1d00ba83190aaf79951d1cf9649ffd33 +size 105044 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode new file mode 100644 index 0000000000..78f5a76f23 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37d2a7d8179d03b407285a89155ceacf1b93632cb85cdddd97438502e089106a +size 72788 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode new file mode 100644 index 0000000000..7d5dd827cc --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92fcc1622e46fb575229a76e189587b92af92ca6a1a40f25f4e0e36dbaa0d693 +size 327865 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode new file mode 100644 index 0000000000..c9022a3505 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c507182c9fc8e903f237672321ea88b12dae401bfdaa54edb64c1058d023e0b +size 104 diff --git a/backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode b/backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode new file mode 100644 index 0000000000..60f47859b4 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58839ef61ee16b3dc704c7a9f0e2198d8b63e5447ad56ce44ea30b84bac54afe +size 160 diff --git a/backward-compatibility/data/0_14_0/kms/context_info.bcode b/backward-compatibility/data/0_14_0/kms/context_info.bcode new file mode 100644 index 0000000000..c184704cde --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/context_info.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc09fa4d730965ed9a3e566b71eab8c3386ec34f75cd9a0faf7d38f2caa2b29d +size 773 diff --git a/backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode new file mode 100644 index 0000000000..8a31fb1c98 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b75ed84a1486d89c47d446d5987105037d5f12714a8298a77bc3d15f701178fa +size 162 diff --git a/backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode new file mode 100644 index 0000000000..e2dcfa0875 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b79dafcc51162efedd41d3cfe3d5d5ce906d0122b89b8cca65a5f43741361e19 +size 174 diff --git a/backward-compatibility/data/0_14_0/kms/designcryption_key.bcode b/backward-compatibility/data/0_14_0/kms/designcryption_key.bcode new file mode 100644 index 0000000000..ccb5d6080a --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/designcryption_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b10c5bf4b215b2204709f5c7ee3f567a7072b321b514f2364ebaf5d3f1ba15ac +size 2541 diff --git a/backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode b/backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode new file mode 100644 index 0000000000..900bba1ed7 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4144bc45b0e0793bbdd028b76c8c8cd7eb8e3929b46d5b9e34fea316b2b6cac +size 50 diff --git a/backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode b/backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode new file mode 100644 index 0000000000..bed5902f24 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:588e8e4a618b8f85e340f9fb7a8e070808789514645e115a4418bcc7594e5b9a +size 5684 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode new file mode 100644 index 0000000000..ff92537351 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0728d5ceb78c452d0affe194733c43509bbf0886b1c2734258c31be77aaafb2e +size 144 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode new file mode 100644 index 0000000000..b7ddb0e715 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0c495b4c4bb470e419ddf637685bf31081d4f223180bb8628a4db6abf3e1f93 +size 992 diff --git a/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode new file mode 100644 index 0000000000..fc91546070 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a9ed66acac6beb2bcc673bd9dacc69eee174087655b20444cf4a9bcfb7d47fd +size 1588 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode new file mode 100644 index 0000000000..8b5c1b78a1 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:216516c2d9475a4e2bb098b47a7b0c00242bfcc7b0f6b9b48ffc031441fd6817 +size 246 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode new file mode 100644 index 0000000000..0a44396d4c --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac0ded3ade3242ce472ecb8ff691834667b04d6c648f0535ff1028e627449ee2 +size 258 diff --git a/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode new file mode 100644 index 0000000000..a509ba13bc --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 +size 11318 diff --git a/backward-compatibility/data/0_14_0/kms/node_info.bcode b/backward-compatibility/data/0_14_0/kms/node_info.bcode new file mode 100644 index 0000000000..363f0a5f6d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/node_info.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b753468d6ebf5f11b5fea788187f88f6857df52a7b89539c59c549d57e54237a +size 259 diff --git a/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode b/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode new file mode 100644 index 0000000000..acf33d1721 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6bcc99dc0d9dbfa8e2a36acfcc8c61c602ff5efb4c6f1e9212c2a73a5e82390 +size 1292 diff --git a/backward-compatibility/data/0_14_0/kms/private_sig_key.bcode b/backward-compatibility/data/0_14_0/kms/private_sig_key.bcode new file mode 100644 index 0000000000..46be201c75 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/private_sig_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a70af30268a5a16d1e92329ff520c86ed3de334ce84c223cf0dc722f8b747d +size 44 diff --git a/backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode b/backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode new file mode 100644 index 0000000000..9d49ac004f --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5aeb8e5ae63b5cb1c7b102c88afe14f1610b94de45262c89f288d62c2905c84d +size 934694 diff --git a/backward-compatibility/data/0_14_0/kms/public_sig_key.bcode b/backward-compatibility/data/0_14_0/kms/public_sig_key.bcode new file mode 100644 index 0000000000..803309c729 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/public_sig_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca62947f91974015736ebb245f3e3e74416f6d54c130a4c733f3a8cbde20f20a +size 45 diff --git a/backward-compatibility/data/0_14_0/kms/recovery_material.bcode b/backward-compatibility/data/0_14_0/kms/recovery_material.bcode new file mode 100644 index 0000000000..e0992faa43 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/recovery_material.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dab6df5aab012710bf4a270a23739db534d74aa51f402c47e66a738a153a2ea9 +size 6482 diff --git a/backward-compatibility/data/0_14_0/kms/signcryption_key.bcode b/backward-compatibility/data/0_14_0/kms/signcryption_key.bcode new file mode 100644 index 0000000000..1bc463d85d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/signcryption_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef6450d800773acdaed4163734882a117889436fa0738b63609fa36bdc5fcf19 +size 892 diff --git a/backward-compatibility/data/0_14_0/kms/signcryption_payload.bincode b/backward-compatibility/data/0_14_0/kms/signcryption_payload.bincode new file mode 100644 index 0000000000000000000000000000000000000000..3d998f4d15a2f7c391836229df41f62d71d7732a GIT binary patch literal 29 ZcmZQ&fB;4&W)@ZsAe#j$aBuCt_W%l816cq7 literal 0 HcmV?d00001 diff --git a/backward-compatibility/data/0_14_0/kms/software_version.bcode b/backward-compatibility/data/0_14_0/kms/software_version.bcode new file mode 100644 index 0000000000..b13a02364a --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/software_version.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0caaec795d048118c15c3462ec76e1d0ca0244f24b2fe3cbe6880fe33b7702e2 +size 42 diff --git a/backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode b/backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode new file mode 100644 index 0000000000..d8da2e2905 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5427a4bd62738a4d91b92e050526b3e2eee0e3a892835ab046607b37f2fac1cd +size 505726 diff --git a/backward-compatibility/data/0_14_0/kms/typed_plaintext.bincode b/backward-compatibility/data/0_14_0/kms/typed_plaintext.bincode new file mode 100644 index 0000000000000000000000000000000000000000..50b7c47b79702e4dc18ab4ba027ddb3cfe249b4e GIT binary patch literal 17 ScmZQ&fB;4&W)@ZsAR7Px alloy_sol_types_1_4_1::Eip712Domain { alloy_sol_types_1_4_1::eip712_domain!( name: "Authorization token", @@ -1022,119 +973,6 @@ impl KmsV0_13_20 { TestMetadataKMS::SoftwareVersion(SOFTWARE_VERSION_TEST) } - fn gen_recovery_material(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(RECOVERY_MATERIAL_TEST.state); - let backup_id: RequestId = RequestId::new_random(&mut rng); - let (operator_pk, operator_sk) = gen_sig_keys(&mut rng); - let mut commitments = BTreeMap::new(); - let mut cts = BTreeMap::new(); - for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { - let cus_role = Role::indexed_from_one(role_j); - let (custodian_pk, _) = gen_sig_keys(&mut rng); - let backup_material = BackupMaterial { - backup_id, - custodian_pk, - custodian_role: cus_role, - operator_pk: operator_pk.clone(), - shares: Vec::new(), - }; - let msg_digest = - safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) - .unwrap(); - commitments.insert(cus_role, msg_digest); - let mut payload = [0_u8; 32]; - rng.fill_bytes(&mut payload); - let cts_out = InnerOperatorBackupOutput { - signcryption: UnifiedSigncryption { - payload: payload.to_vec(), - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }, - }; - cts.insert(cus_role, cts_out); - } - - // Dummy payload; but needs to be a properly serialized payload - // This must be generated after the commitment stuff, since the test will regenerate the commitment stuff, - // but read the custodian context from disk - let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (_dec_key, enc_key) = encryption.keygen().unwrap(); - let (cus_pk, _) = gen_sig_keys(&mut rng); - let payload = CustodianSetupMessagePayload { - header: "header".to_string(), - random_value: [4_u8; 32], - timestamp: 0, - public_enc_key: enc_key.clone(), - verification_key: cus_pk.clone(), - }; - let mut payload_serial = Vec::new(); - safe_serialize(&payload, &mut payload_serial, SAFE_SER_SIZE_LIMIT).unwrap(); - let mut custodian_nodes = Vec::new(); - for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { - let setup_msg = CustodianSetupMessage { - custodian_role: role_j as u64, - name: format!("Custodian-{role_j}"), - payload: payload_serial.clone(), - }; - custodian_nodes.push(setup_msg); - } - let custodian_context = CustodianContext { - custodian_nodes, - custodian_context_id: Some(backup_id.into()), - threshold: 1, - }; - let internal_custodian_context = - InternalCustodianContext::new(custodian_context, enc_key).unwrap(); - store_versioned_auxiliary!( - &internal_custodian_context, - dir, - &RECOVERY_MATERIAL_TEST.test_filename, - &RECOVERY_MATERIAL_TEST.internal_cus_context_filename, - ); - let recovery_material = RecoveryValidationMaterial::new( - cts, - commitments, - internal_custodian_context, - &operator_sk, - kms_grpc_0_13_20::ContextId::from_bytes(RECOVERY_MATERIAL_TEST.mpc_context_id), - ) - .unwrap(); - store_versioned_test!( - &recovery_material, - dir, - &RECOVERY_MATERIAL_TEST.test_filename - ); - TestMetadataKMS::RecoveryValidationMaterial(RECOVERY_MATERIAL_TEST) - } - - fn gen_internal_recovery_request(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(INTERNAL_RECOVERY_REQUEST_TEST.state); - let backup_id: RequestId = RequestId::new_random(&mut rng); - let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (_dec_key, enc_key) = encryption.keygen().unwrap(); - let (verf_key, _) = gen_sig_keys(&mut rng); - let mut cts = BTreeMap::new(); - for role_j in 1..=INTERNAL_RECOVERY_REQUEST_TEST.amount { - let cur_role = Role::indexed_from_one(role_j as usize); - let mut payload = [0_u8; 32]; - rng.fill_bytes(&mut payload); - let signcryption = UnifiedSigncryption { - payload: payload.to_vec(), - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }; - cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); - } - let recovery_material = - InternalRecoveryRequest::new(enc_key, cts, backup_id, verf_key).unwrap(); - store_versioned_test!( - &recovery_material, - dir, - &INTERNAL_RECOVERY_REQUEST_TEST.test_filename - ); - TestMetadataKMS::InternalRecoveryRequest(INTERNAL_RECOVERY_REQUEST_TEST) - } - fn gen_internal_cus_context_handles(dir: &PathBuf) -> TestMetadataKMS { let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_CONTEXT_TEST.state); let context_id: RequestId = RequestId::new_random(&mut rng); @@ -1377,81 +1215,6 @@ impl KmsV0_13_20 { ); TestMetadataKMS::InternalCustodianSetupMessage(INTERNAL_CUS_SETUP_MSG_TEST) } - - fn gen_internal_cus_rec_out(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_REC_OUT_TEST.state); - let (operator_verification_key, _) = gen_sig_keys(&mut rng); - let mut buf = [0u8; 100]; - rng.fill_bytes(&mut buf); - let signcryption = UnifiedSigncryption { - payload: buf.to_vec(), - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }; - let icro = InternalCustodianRecoveryOutput { - signcryption, - custodian_role: Role::indexed_from_one(2), - operator_verification_key, - mpc_context_id: kms_grpc_0_13_20::RequestId::from_bytes( - INTERNAL_CUS_REC_OUT_TEST.mpc_context_id, - ), - }; - store_versioned_test!(&icro, dir, &INTERNAL_CUS_REC_OUT_TEST.test_filename); - TestMetadataKMS::InternalCustodianRecoveryOutput(INTERNAL_CUS_REC_OUT_TEST) - } - - fn gen_operator_backup_output(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(OPERATOR_BACKUP_OUTPUT_TEST.seed); - - let custodians: Vec<_> = (1..=OPERATOR_BACKUP_OUTPUT_TEST.custodian_count) - .map(|i| { - let (_verification_key, signing_key) = gen_sig_keys(&mut rng); - let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (private_key, public_key) = encryption.keygen().unwrap(); - Custodian::new( - Role::indexed_from_one(i), - signing_key, - public_key, - private_key, - ) - .unwrap() - }) - .collect(); - let custodian_messages: Vec<_> = custodians - .iter() - .enumerate() - .map(|(i, c)| { - c.generate_setup_message(&mut rng, format!("Custodian-{i}")) - .unwrap() - }) - .collect(); - - let operator = { - let (_verification_key, signing_key) = gen_sig_keys(&mut rng); - Operator::new_for_sharing( - custodian_messages, - signing_key, - OPERATOR_BACKUP_OUTPUT_TEST.custodian_threshold, - custodians.len(), - ) - .unwrap() - }; - let operator_backup_output = &operator - .secret_share_and_signcrypt( - &mut rng, - &OPERATOR_BACKUP_OUTPUT_TEST.plaintext, - RequestId::from_bytes(OPERATOR_BACKUP_OUTPUT_TEST.backup_id), - ) - .unwrap() - .ct_shares[&Role::indexed_from_one(1)]; - - store_versioned_test!( - operator_backup_output, - dir, - &OPERATOR_BACKUP_OUTPUT_TEST.test_filename - ); - TestMetadataKMS::OperatorBackupOutput(OPERATOR_BACKUP_OUTPUT_TEST) - } } struct DistributedDecryptionV0_13_20; @@ -1686,14 +1449,10 @@ impl KMSCoreVersion for V0_13_20 { KmsV0_13_20::gen_context_info(&dir), KmsV0_13_20::gen_node_info(&dir), KmsV0_13_20::gen_software_version(&dir), - KmsV0_13_20::gen_recovery_material(&dir), - KmsV0_13_20::gen_internal_recovery_request(&dir), KmsV0_13_20::gen_internal_cus_context_handles(&dir), KmsV0_13_20::gen_internal_cus_setup_msg(&dir), KmsV0_13_20::gen_kms_fhe_key_handles(&dir), KmsV0_13_20::gen_threshold_fhe_keys(&dir), - KmsV0_13_20::gen_internal_cus_rec_out(&dir), - KmsV0_13_20::gen_operator_backup_output(&dir), ] } diff --git a/backward-compatibility/generate-v0.14.0/Cargo.lock b/backward-compatibility/generate-v0.14.0/Cargo.lock new file mode 100644 index 0000000000..a335a8cb28 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/Cargo.lock @@ -0,0 +1,8090 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "aes-prng" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49cccd49cb7034d6ee7db9ac3549bb3fb38ff17179d93b726efb974cc9ddafa9" +dependencies = [ + "aes", + "byteorder", + "rand 0.8.5", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", + "serde", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "alloy-consensus" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f16daaf7e1f95f62c6c3bf8a3fc3d78b08ae9777810c0bb5e94966c7cd57ef0" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-trie", + "alloy-tx-macros", + "auto_impl", + "borsh", + "c-kzg", + "derive_more", + "either", + "k256", + "once_cell", + "rand 0.8.5", + "secp256k1", + "serde", + "serde_json", + "serde_with 3.20.0", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-consensus-any" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118998d9015332ab1b4720ae1f1e3009491966a0349938a1f43ff45a8a4c6299" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-dyn-abi" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdff496dd4e98a81f4861e66f7eaf5f2488971848bb42d9c892f871730245c8" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-type-parser", + "alloy-sol-types", + "itoa", + "serde", + "serde_json", + "winnow 0.7.15", +] + +[[package]] +name = "alloy-eip2124" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741bdd7499908b3aa0b159bba11e71c8cddd009a2c2eb7a06e825f1ec87900a5" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "crc", + "serde", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-eip2930" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9441120fa82df73e8959ae0e4ab8ade03de2aaae61be313fbf5746277847ce25" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "borsh", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2919c5a56a1007492da313e7a3b6d45ef5edc5d33416fdec63c0d7a2702a0d20" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "borsh", + "serde", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-eip7928" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b827a6d7784fe3eb3489d40699407a4cdcce74271421a01bdffe60cf573bb16" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "borsh", + "once_cell", + "serde", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-eips" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ef28c9fdad22d4eec52d894f5f2673a0895f1e5ef196734568e68c0f6caca8" +dependencies = [ + "alloy-eip2124", + "alloy-eip2930", + "alloy-eip7702", + "alloy-eip7928", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "auto_impl", + "borsh", + "c-kzg", + "derive_more", + "either", + "serde", + "serde_with 3.20.0", + "sha2", +] + +[[package]] +name = "alloy-json-abi" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-json-rpc" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422d110f1c40f1f8d0e5562b0b649c35f345fccb7093d9f02729943dcd1eef71" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "http 1.3.1", + "serde", + "serde_json", + "thiserror 2.0.12", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89924fdcfeee0e0fa42b1f10af42f92802b5d16be614a70897382565663bf7cf" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-types-any", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "derive_more", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-network-primitives" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb82711d59a43fdfd79727c99f270b974c784ec4eb5728a0d0d22f26716c87ef" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-primitives" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "foldhash 0.2.0", + "hashbrown 0.16.1", + "indexmap 2.14.0", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand 0.9.4", + "ruint", + "rustc-hash", + "serde", + "sha3", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36834a5c0a2fa56e171bf256c34d70fca07d0c0031583edea1c4946b7889c9e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "alloy-rpc-types-any" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3823026d1ed239a40f12364fac50726c8daf1b6ab8077a97212c5123910429ed" +dependencies = [ + "alloy-consensus-any", + "alloy-rpc-types-eth", + "alloy-serde", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c095f92c4e1ff4981d89e9aa02d5f98c762a1980ab66bec49c44be11349da2" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "itertools 0.14.0", + "serde", + "serde_json", + "serde_with 3.20.0", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-serde" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ece63b89294b8614ab3f483560c08d016930f842bf36da56bf0b764a15c11e" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb10ccd49d0248df51063fce6b716f68a315dd912d55b32178c883fd48b4021d" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "either", + "elliptic-curve 0.13.8", + "k256", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-signer-local" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4d992d44e6c414ece580294abbadb50e74cfd4eaa69787350a4dfd4b20eaa1b" +dependencies = [ + "alloy-consensus", + "alloy-network", + "alloy-primitives", + "alloy-signer", + "async-trait", + "k256", + "rand 0.8.5", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-sol-macro" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab81bab693da9bb79f7a95b64b394718259fdd7e41dceeced4cad57cb71c4f6a" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489f1620bb7e2483fb5819ed01ab6edc1d2f93939dce35a5695085a1afd1d699" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck", + "indexmap 2.14.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "sha3", + "syn 2.0.117", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56cef806ad22d4392c5fc83cf8f2089f988eb99c7067b4e0c6f1971fc1cca318" +dependencies = [ + "const-hex", + "dunce", + "heck", + "macro-string", + "proc-macro2", + "quote", + "syn 2.0.117", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6df77fea9d6a2a75c0ef8d2acbdfd92286cc599983d3175ccdc170d3433d249" +dependencies = [ + "serde", + "winnow 0.7.15", +] + +[[package]] +name = "alloy-sol-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", + "serde", +] + +[[package]] +name = "alloy-trie" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f14b5d9b2c2173980202c6ff470d96e7c5e202c65a9f67884ad565226df7fbb" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more", + "nybbles", + "serde", + "smallvec", + "thiserror 2.0.12", + "tracing", +] + +[[package]] +name = "alloy-tx-macros" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69722eddcdf1ce096c3ab66cf8116999363f734eb36fe94a148f4f71c85da84" +dependencies = [ + "darling 0.23.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arc-swap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +dependencies = [ + "rustversion", +] + +[[package]] +name = "ark-bls12-381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5" +dependencies = [ + "ark-ec", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-poly", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools 0.13.0", + "num-bigint", + "num-integer", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.117", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "rayon", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint", + "rayon", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", + "rayon", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "asn1-rs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror 2.0.12", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "async_cell" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447ab28afbb345f5408b120702a44e5529ebf90b1796ec76e9528df8e288e6c2" +dependencies = [ + "loom", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "attestation-doc-validation" +version = "0.10.0" +source = "git+https://github.com/mkmks/attestation-doc-validation.git?branch=timestamps#764b6814e6536eb8fa5c9cfa60c27b0e84176214" +dependencies = [ + "aes", + "aes-gcm", + "aws-nitro-enclaves-cose", + "aws-nitro-enclaves-nsm-api", + "base64 0.21.7", + "chrono", + "der 0.7.10", + "ecdsa 0.16.9", + "getrandom 0.2.17", + "hex", + "p256 0.13.2", + "p384", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_cbor", + "serde_with 2.3.3", + "sha2", + "thiserror 1.0.69", + "time", + "wasm-bindgen", + "webpki", + "x509-parser", +] + +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "aws-config" +version = "1.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96571e6996817bf3d58f6b569e4b9fd2e9d2fcf9f7424eed07b2ce9bb87535e5" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http 0.62.6", + "aws-smithy-json 0.61.9", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.3.1", + "ring", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-lc-rs" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "aws-nitro-enclaves-cose" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a94047bd9c3717c6ca3a145504c0e26b64a5e2d9eb9559b187748433fbc382" +dependencies = [ + "serde", + "serde_bytes", + "serde_cbor", + "serde_repr", + "serde_with 3.20.0", +] + +[[package]] +name = "aws-nitro-enclaves-nsm-api" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92c1f4471b33f6a7af9ea421b249ed18a11c71156564baf6293148fa6ad1b09" +dependencies = [ + "libc", + "log", + "nix", + "serde", + "serde_bytes", + "serde_cbor", +] + +[[package]] +name = "aws-runtime" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http 0.63.6", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "bytes-utils", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-kms" +version = "1.98.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c74fef3d08159467cad98300f33a2e3bd1a985d527ad66ab0ea83c95e3a615" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http 0.62.6", + "aws-smithy-json 0.61.9", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-s3" +version = "1.120.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06673901e961f20fa8d7da907da48f7ad6c1b383e3726c22bd418900f015abe1" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-checksums", + "aws-smithy-eventstream", + "aws-smithy-http 0.62.6", + "aws-smithy-json 0.61.9", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "bytes", + "fastrand", + "hex", + "hmac", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "lru", + "percent-encoding", + "regex-lite", + "sha2", + "tracing", + "url", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.96.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64a6eded248c6b453966e915d32aeddb48ea63ad17932682774eb026fbef5b1" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http 0.63.6", + "aws-smithy-json 0.62.5", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.98.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db96d720d3c622fcbe08bae1c4b04a72ce6257d8b0584cb5418da00ae20a344f" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http 0.63.6", + "aws-smithy-json 0.62.5", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.100.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fafbdda43b93f57f699c5dfe8328db590b967b8a820a13ccdd6687355dfcc7ca" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http 0.63.6", + "aws-smithy-json 0.62.5", + "aws-smithy-observability", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" +dependencies = [ + "aws-credential-types", + "aws-smithy-eventstream", + "aws-smithy-http 0.63.6", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "crypto-bigint 0.5.5", + "form_urlencoded", + "hex", + "hmac", + "http 0.2.12", + "http 1.3.1", + "p256 0.11.1", + "percent-encoding", + "ring", + "sha2", + "subtle", + "time", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-checksums" +version = "0.63.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23374b9170cbbcc6f5df8dc5ebb9b6c5c28a3c8f599f0e8b8b10eb6f4a5c6e74" +dependencies = [ + "aws-smithy-http 0.62.6", + "aws-smithy-types", + "bytes", + "crc-fast", + "hex", + "http 0.2.12", + "http-body 0.4.6", + "md-5", + "pin-project-lite", + "sha1", + "sha2", + "tracing", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf09d74e5e32f76b8762da505a3cd59303e367a664ca67295387baa8c1d7548" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.62.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826141069295752372f8203c17f28e30c464d22899a43a0c9fd9c458d469c88b" +dependencies = [ + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http" +version = "0.63.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http-client" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a2f165a7feee6f263028b899d0a181987f4fa7179a6411a32a439fba7c5f769" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.14", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper 1.9.0", + "hyper-rustls 0.24.2", + "hyper-rustls 0.27.7", + "hyper-util", + "pin-project-lite", + "rustls 0.21.12", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.2", + "tower", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.61.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fa1213db31ac95288d981476f78d05d9cbb0353d22cdf3472cc05bb02f6551" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-json" +version = "0.62.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9648b0bb82a2eedd844052c6ad2a1a822d1f8e3adee5fbf668366717e428856a" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-observability" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" +dependencies = [ + "aws-smithy-runtime-api", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http 0.63.6", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "pin-utils", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" +dependencies = [ + "aws-smithy-async", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.3.1", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-types" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b1117b3b2bbe166d11199b540ceed0d0f7676e36e7b962b5a437a9971eac75" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version 0.4.1", + "tracing", +] + +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.9.0", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "futures-core", + "getrandom 0.2.17", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", +] + +[[package]] +name = "backward-compatibility" +version = "0.14.0" +dependencies = [ + "bincode 1.3.3", + "ron 0.10.1", + "serde", + "strum 0.28.0", +] + +[[package]] +name = "backward-compatibility-generate-v0-14-0" +version = "0.14.0" +dependencies = [ + "aes-prng", + "alloy-primitives", + "alloy-sol-types", + "backward-compatibility", + "bc2wrap", + "bincode 2.0.1", + "cfg-if", + "itertools 0.14.0", + "kms", + "kms-grpc", + "rand 0.8.5", + "ron 0.10.1", + "serde", + "tfhe", + "tfhe-versionable", + "threshold-algebra", + "threshold-execution", + "threshold-networking", + "threshold-types", + "tokio", + "tokio-rustls 0.26.2", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bc2wrap" +version = "2.0.1" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "bincode 2.0.1", + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + +[[package]] +name = "bip39" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc" +dependencies = [ + "bitcoin_hashes", + "serde", + "unicode-normalization", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitcoin-io" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" + +[[package]] +name = "bitcoin_hashes" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +dependencies = [ + "serde_core", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "bitvec-nom2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d988fcc40055ceaa85edc55875a08f8abd29018582647fd82ad6128dba14a5f0" +dependencies = [ + "bitvec", + "nom 7.1.3", +] + +[[package]] +name = "blake3" +version = "1.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures 0.3.0", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "borsh" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +dependencies = [ + "borsh-derive", + "bytes", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +dependencies = [ + "serde", +] + +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + +[[package]] +name = "c-kzg" +version = "2.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6648ed1e4ea8e8a1a4a2c78e1cda29a3fd500bc622899c340d8525ea9a76b24a" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.2.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half 2.7.1", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "clap_lex" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "config" +version = "0.15.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30fa8254caad766fc03cb0ccae691e14bf3bd72bfff27f72802ce729551b3d6" +dependencies = [ + "async-trait", + "convert_case", + "json5", + "pathdiff", + "ron 0.12.1", + "rust-ini", + "serde-untagged", + "serde_core", + "serde_json", + "toml", + "winnow 0.7.15", + "yaml-rust2", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-hex" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d9a563d167a9cce0f94153382b33cb6eded6dfabff03c69ad65a28ea1514e0" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "proptest", + "serde_core", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc-fast" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" +dependencies = [ + "crc", + "digest 0.10.7", + "rustversion", + "spin 0.10.0", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "serde", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "der_derive", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "dyn-stack" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4713e43e2886ba72b8271aa66c93d722116acf7a75555cce11dcde84388fe8" +dependencies = [ + "bytemuck", + "dyn-stack-macros", +] + +[[package]] +name = "dyn-stack-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "serdect", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.1", + "generic-array", + "group 0.13.0", + "hkdf", + "pem-rfc7468", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-ordinalize" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-utils" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "tracing", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fragile" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8878864ba14bb86e818a412bfd6f18f9eabd4ec0f008a28e8f7eb61db532fcf9" +dependencies = [ + "futures-core", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + +[[package]] +name = "g2gen" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5a7e0eb46f83a20260b850117d204366674e85d3a908d90865c78df9a6b1dfc" +dependencies = [ + "g2poly", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "g2p" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "539e2644c030d3bf4cd208cb842d2ce2f80e82e6e8472390bcef83ceba0d80ad" +dependencies = [ + "g2gen", + "g2poly", +] + +[[package]] +name = "g2poly" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312d2295c7302019c395cfb90dacd00a82a2eabd700429bba9c7a3f38dbbe11b" + +[[package]] +name = "generator" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link 0.2.1", + "windows-result 0.4.1", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.14.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", + "indexmap 2.14.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", + "serde", + "serde_core", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-conservative" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hybrid-array" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2 0.4.14", + "http 1.3.1", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http 1.3.1", + "hyper 1.9.0", + "hyper-util", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.2", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper 1.9.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.9.0", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.3", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iam-rs" +version = "0.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8d5289fad8531c141b5ae939fa31034a7aebe36fd43ce2a7c5e983e1bdb8e2" +dependencies = [ + "chrono", + "ipnet", + "serde", + "serde_json", + "serde_with 3.20.0", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "iri-string" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "serdect", + "sha2", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures 0.2.17", +] + +[[package]] +name = "keccak-asm" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa468878266ad91431012b3e5ef1bf9b170eab22883503a318d46857afa4579a" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + +[[package]] +name = "kem" +version = "0.3.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8645470337db67b01a7f966decf7d0bafedbae74147d33e641c67a91df239f" +dependencies = [ + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "kms" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "aes", + "aes-gcm", + "aes-gcm-siv", + "aes-prng", + "alloy-dyn-abi", + "alloy-primitives", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types", + "anyhow", + "async_cell", + "attestation-doc-validation", + "aws-config", + "aws-nitro-enclaves-nsm-api", + "aws-sdk-kms", + "aws-sdk-s3", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bc2wrap", + "bincode 2.0.1", + "bip39", + "cbc", + "cfg-if", + "ciborium", + "clap", + "console_error_panic_hook", + "enum_dispatch", + "futures-util", + "getrandom 0.2.17", + "hex", + "http 0.2.12", + "hyper-rustls 0.24.2", + "iam-rs", + "itertools 0.14.0", + "k256", + "kms-grpc", + "ml-kem", + "nom 8.0.0", + "observability", + "p384", + "rand 0.8.5", + "rasn", + "rasn-cms", + "rayon", + "rcgen", + "rsa", + "rustls-webpki 0.103.9", + "serde", + "serde-wasm-bindgen", + "serde_json", + "signature 2.2.0", + "strum 0.27.1", + "strum_macros 0.27.1", + "test-utils", + "tfhe", + "tfhe-csprng", + "tfhe-versionable", + "thiserror 2.0.12", + "thread-handles", + "threshold-algebra", + "threshold-execution", + "threshold-hashing", + "threshold-networking", + "threshold-types", + "tokio", + "tokio-rustls 0.26.2", + "tokio-util", + "tonic", + "tonic-health", + "tonic-tls", + "tower", + "tower-http", + "tracing", + "trait-variant", + "url", + "validator", + "wasm-bindgen", + "x509-parser", + "zeroize", +] + +[[package]] +name = "kms-grpc" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "alloy-dyn-abi", + "alloy-primitives", + "alloy-sol-types", + "anyhow", + "bc2wrap", + "cfg-if", + "hex", + "prost", + "rand 0.8.5", + "serde", + "strum 0.27.1", + "strum_macros 0.27.1", + "tfhe", + "tfhe-versionable", + "thiserror 2.0.12", + "threshold-hashing", + "threshold-types", + "tonic", + "tonic-prost", + "tonic-prost-build", + "tracing", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "matrixmultiply" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "ml-kem" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcaee19a45f916d98f24a551cc9a2cdae705a040e66f3cbc4f3a282ea6a2e982" +dependencies = [ + "hybrid-array", + "kem", + "rand_core 0.6.4", + "sha3", + "zeroize", +] + +[[package]] +name = "mockall" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "nalgebra" +version = "0.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d43ddcacf343185dfd6de2ee786d9e8b1c2301622afab66b6c73baf9882abfd" +dependencies = [ + "approx", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits", + "rand 0.8.5", + "rand_distr", + "simba", + "typenum", +] + +[[package]] +name = "ndarray" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "portable-atomic", + "portable-atomic-util", + "rawpointer", + "serde", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "bytemuck", + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "nybbles" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d49ff0c0d00d4a502b39df9af3a525e1efeb14b9dabb5bb83335284c1309210" +dependencies = [ + "alloy-rlp", + "cfg-if", + "proptest", + "ruint", + "serde", + "smallvec", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.11.1", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", + "objc2-core-foundation", +] + +[[package]] +name = "observability" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "axum", + "config", + "http 1.3.1", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry-stdout", + "opentelemetry_sdk", + "prometheus", + "serde", + "serde_json", + "strum 0.27.1", + "strum_macros 0.27.1", + "sysinfo", + "test-utils", + "thiserror 2.0.12", + "tokio", + "tonic", + "tracing", + "tracing-appender", + "tracing-opentelemetry", + "tracing-subscriber", + "typed-builder", + "uuid", + "validator", +] + +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.12", + "tracing", +] + +[[package]] +name = "opentelemetry-http" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +dependencies = [ + "async-trait", + "bytes", + "http 1.3.1", + "opentelemetry", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" +dependencies = [ + "http 1.3.1", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "reqwest", + "thiserror 2.0.12", + "tokio", + "tonic", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost", + "tonic", + "tonic-prost", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" + +[[package]] +name = "opentelemetry-stdout" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc8887887e169414f637b18751487cce4e095be787d23fad13c454e2fb1b3811" +dependencies = [ + "chrono", + "opentelemetry", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "rand 0.9.4", + "thiserror 2.0.12", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64 0.22.1", + "serde_core", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap 2.14.0", +] + +[[package]] +name = "pin-project" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "spki 0.7.3", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "predicates" +version = "3.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" +dependencies = [ + "anstyle", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" + +[[package]] +name = "predicates-tree" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "procfs" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" +dependencies = [ + "bitflags 2.11.1", + "hex", + "procfs-core", + "rustix 0.38.44", +] + +[[package]] +name = "procfs-core" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" +dependencies = [ + "bitflags 2.11.1", + "hex", +] + +[[package]] +name = "prometheus" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "libc", + "memchr", + "parking_lot", + "procfs", + "protobuf", + "thiserror 2.0.12", +] + +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.11.1", + "num-traits", + "rand 0.9.4", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +dependencies = [ + "heck", + "itertools 0.14.0", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "pulldown-cmark", + "pulldown-cmark-to-cmark", + "regex", + "syn 2.0.117", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + +[[package]] +name = "protobuf" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror 1.0.69", +] + +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror 1.0.69", +] + +[[package]] +name = "pulldown-cmark" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" +dependencies = [ + "bitflags 2.11.1", + "memchr", + "unicase", +] + +[[package]] +name = "pulldown-cmark-to-cmark" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" +dependencies = [ + "pulldown-cmark", +] + +[[package]] +name = "pulp" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e205bb30d5b916c55e584c22201771bcf2bad9aabd5d4127f38387140c38632" +dependencies = [ + "bytemuck", + "cfg-if", + "libm", + "num-complex", + "paste", + "pulp-wasm-simd-flag", + "raw-cpuid", + "reborrow", + "version_check", +] + +[[package]] +name = "pulp-wasm-simd-flag" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e24eee682d89fb193496edf918a7f407d30175b2e785fe057e4392dfd182e0" + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", + "serde", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", + "serde", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "rasn" +version = "0.28.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00672f0ebff31e31b6d7e8db8b7c639b4a8ee9ae6afa206bc4e6acd706e6b2" +dependencies = [ + "bitvec", + "bitvec-nom2", + "bytes", + "cfg-if", + "chrono", + "either", + "nom 7.1.3", + "num-bigint", + "num-integer", + "num-traits", + "once_cell", + "rasn-derive", + "serde_json", + "snafu", + "xml-no-std", +] + +[[package]] +name = "rasn-cms" +version = "0.28.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b062f8fd7cd3f3273c923c79b326d4cae2c20df17536feb522d8720de415fbb6" +dependencies = [ + "rasn", + "rasn-pkix", +] + +[[package]] +name = "rasn-derive" +version = "0.28.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11dcd4dab09ceadedb3e2bedf340deb583f0e25bba9ad966b5655c2fb62b1392" +dependencies = [ + "proc-macro2", + "rasn-derive-impl", + "syn 2.0.117", +] + +[[package]] +name = "rasn-derive-impl" +version = "0.28.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f121c276d3f2fba8caabc870288de3f81abdb0bb94d5510651e58e1e00a7b9e7" +dependencies = [ + "either", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.117", + "uuid", +] + +[[package]] +name = "rasn-pkix" +version = "0.28.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8a385ace6c844d2389fdfe8c82637dd742d7b997a6fb5826dbb97f4539057e" +dependencies = [ + "rasn", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.11.1", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.14.7" +source = "git+https://github.com/zama-ai/rcgen.git#17504e6dd9c430784dd83a81db7a865b0db38e5d" +dependencies = [ + "aws-lc-rs", + "pem", + "rustls-pki-types", + "time", + "x509-parser", + "yasna", +] + +[[package]] +name = "reborrow" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" + +[[package]] +name = "redis" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc42f3a12fd4408ce64d8efef67048a924e543bd35c6591c0447fda9054695f" +dependencies = [ + "arc-swap", + "combine", + "itoa", + "num-bigint", + "percent-encoding", + "ryu", + "sha1_smol", + "socket2 0.5.10", + "url", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.11.1", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.9.0", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "ron" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" +dependencies = [ + "base64 0.22.1", + "bitflags 2.11.1", + "serde", + "serde_derive", + "unicode-ident", +] + +[[package]] +name = "ron" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +dependencies = [ + "bitflags 2.11.1", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "serde", + "sha2", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "ruint" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0298da754d1395046b0afdc2f20ee76d29a8ae310cd30ffa84ed42acba9cb12a" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rand 0.9.4", + "rlp", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.11.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.11.1", + "errno", + "libc", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.37" +source = "git+https://github.com/zama-ai/rustls.git?branch=rel-0.23#49aa4091eae6a73f575bebeae28d370acd74f8b6" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.103.9", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe 0.1.6", + "rustls-pemfile", + "schannel", + "security-framework 2.11.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework 3.7.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "git+https://github.com/zama-ai/webpki.git?branch=rel-0.103#9558707f39b97060b527966de76943e7ed40a022" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.10", + "generic-array", + "pkcs8 0.10.2", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "secp256k1-sys", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.11.1", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.11.1", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.3", + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap 1.9.3", + "serde", + "serde_json", + "serde_with_macros 2.3.3", + "time", +] + +[[package]] +name = "serde_with" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +dependencies = [ + "base64 0.22.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros 3.20.0", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_with_macros" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +dependencies = [ + "darling 0.23.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3-asm" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cbb88c189d6352cc8ae96a39d19c7ecad8f7330b29461187f2587fdc2988d5" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simba" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "snafu" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.10", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "statrs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" +dependencies = [ + "approx", + "nalgebra", + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +dependencies = [ + "strum_macros 0.27.1", +] + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros 0.28.0", +] + +[[package]] +name = "strum_macros" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.117", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f425ae0b12e2f5ae65542e00898d500d4d318b4baf09f40fd0d410454e9947" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "sysinfo" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "windows", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix 1.1.4", + "windows-sys 0.59.0", +] + +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + +[[package]] +name = "test-utils" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "bc2wrap", + "serde", + "tokio", + "tracing-subscriber", +] + +[[package]] +name = "tfhe" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c15298cfa418ee5cb50446ebeea88dc44378a35b0d6c66eabdd3b7953b239e85" +dependencies = [ + "aligned-vec", + "bincode 1.3.3", + "blake3", + "bytemuck", + "dyn-stack", + "itertools 0.14.0", + "paste", + "pulp", + "rand_core 0.6.4", + "rayon", + "serde", + "sha3", + "strum 0.27.1", + "tfhe-csprng", + "tfhe-fft", + "tfhe-ntt", + "tfhe-safe-serialize", + "tfhe-versionable", + "tfhe-zk-pok", +] + +[[package]] +name = "tfhe-csprng" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d688adceee1ea2545ed78b8242165f0cece293f965cc4a1f7755e5cfca23b5f" +dependencies = [ + "aes", + "getrandom 0.2.17", + "libc", + "rayon", + "serde", + "tfhe-versionable", +] + +[[package]] +name = "tfhe-fft" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960a6a2ef1869320837e3d45ab60bbc031c045005eb2578b20fe074a982c2e56" +dependencies = [ + "aligned-vec", + "bytemuck", + "dyn-stack", + "js-sys", + "num-complex", + "pulp", + "serde", +] + +[[package]] +name = "tfhe-ntt" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10650c743ade46b166c698c8349902ed5986784a7db418c51f810bea25f09e3d" +dependencies = [ + "aligned-vec", + "bytemuck", + "pulp", +] + +[[package]] +name = "tfhe-safe-serialize" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0603167ceb9c52247b80ea6e944bb0a4f2b45ce4e1f413d97af5df6dee443ff" +dependencies = [ + "bincode 1.3.3", + "serde", + "tfhe-versionable", +] + +[[package]] +name = "tfhe-versionable" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb27ae7e1d5bc7e4662881834ad35f9fe04c6df4d4cf3cadfa84e23da5e9deb" +dependencies = [ + "aligned-vec", + "num-complex", + "serde", + "tfhe-versionable-derive", +] + +[[package]] +name = "tfhe-versionable-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085ba3a819d9931325c08ff7430864f941c7b05b0b87d1b0086336cea8f658ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tfhe-zk-pok" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a48b03b8f098ab3f335d300239c12a16fcbfaa1a37433a7802453e4017ae0ddf" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff 0.5.0", + "ark-poly", + "getrandom 0.2.17", + "itertools 0.14.0", + "num-bigint", + "rand 0.8.5", + "rayon", + "serde", + "sha3", + "tfhe-safe-serialize", + "tfhe-versionable", + "zeroize", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "thread-handles" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "error-utils", + "futures", + "rayon", + "tokio", + "tracing", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "threshold-algebra" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "error-utils", + "g2p", + "itertools 0.14.0", + "ndarray", + "rand 0.8.5", + "serde", + "sha3", + "statrs", + "strum 0.27.1", + "tfhe-versionable", + "threshold-hashing", + "threshold-types", + "tracing", + "zeroize", +] + +[[package]] +name = "threshold-execution" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "aes", + "aes-prng", + "anyhow", + "async-trait", + "bc2wrap", + "cfg-if", + "clap", + "const_format", + "derive_more", + "error-utils", + "futures", + "futures-util", + "itertools 0.14.0", + "mockall", + "ndarray", + "num-integer", + "num-traits", + "rand 0.8.5", + "rayon", + "redis", + "serde", + "sha3", + "statrs", + "strum 0.27.1", + "tempfile", + "test-utils", + "tfhe", + "tfhe-csprng", + "tfhe-versionable", + "tfhe-zk-pok", + "thread-handles", + "threshold-algebra", + "threshold-hashing", + "threshold-networking", + "threshold-types", + "tokio", + "tonic", + "tracing", + "zeroize", +] + +[[package]] +name = "threshold-hashing" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "bc2wrap", + "serde", + "sha3", +] + +[[package]] +name = "threshold-networking" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "async-trait", + "attestation-doc-validation", + "backoff", + "bc2wrap", + "clap", + "dashmap", + "error-utils", + "futures-util", + "hex", + "hyper-rustls 0.27.7", + "observability", + "oid-registry", + "prost", + "rcgen", + "serde", + "sha2", + "tfhe-versionable", + "threshold-types", + "tokio", + "tokio-rustls 0.26.2", + "tonic", + "tonic-prost", + "tonic-prost-build", + "tonic-tls", + "tower", + "tracing", + "x509-parser", +] + +[[package]] +name = "threshold-types" +version = "0.13.20-0" +source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +dependencies = [ + "anyhow", + "async-trait", + "serde", + "tfhe-versionable", + "threshold-hashing", + "zeroize", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "js-sys", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.3", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls 0.23.37", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.15", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.2", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.2", +] + +[[package]] +name = "tonic" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +dependencies = [ + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2 0.4.14", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.9.0", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2 0.6.3", + "sync_wrapper", + "tokio", + "tokio-rustls 0.26.2", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tonic-health" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" +dependencies = [ + "prost", + "tokio", + "tokio-stream", + "tonic", + "tonic-prost", +] + +[[package]] +name = "tonic-prost" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tonic-prost-build" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.117", + "tempfile", + "tonic-build", +] + +[[package]] +name = "tonic-tls" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf5cb6ddbfdc22fd0cb2ce16072d210a0240d8ad94f8695ac5d917465da479d" +dependencies = [ + "async-stream", + "futures", + "hyper 1.9.0", + "hyper-util", + "socket2 0.6.3", + "tokio", + "tokio-rustls 0.26.2", + "tonic", + "tower", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 2.14.0", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.11.1", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror 1.0.69", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +dependencies = [ + "js-sys", + "opentelemetry", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typed-builder" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce63bcaf7e9806c206f7d7b9c1f38e0dce8bb165a80af0898161058b19248534" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60d8d828da2a3d759d3519cdf29a5bac49c77d039ad36d0782edadbf9cd5415b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "rand 0.9.4", + "wasm-bindgen", +] + +[[package]] +name = "validator" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa" +dependencies = [ + "idna", + "once_cell", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca" +dependencies = [ + "darling 0.20.11", + "once_cell", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "serde", + "serde_json", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring", + "untrusted 0.9.0", +] + +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x509-parser" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3e137310115a65136898d2079f003ce33331a6c4b0d51f1531d1be082b6425" +dependencies = [ + "asn1-rs", + "aws-lc-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror 2.0.12", + "time", +] + +[[package]] +name = "xml-no-std" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd223bc94c615fc02bf2f4bbc22a4a9bfe489c2add3ec10b1038df3aca44cac7" + +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + +[[package]] +name = "yaml-rust2" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2462ea039c445496d8793d052e13787f2b90e750b833afee748e601c17621ed9" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] diff --git a/backward-compatibility/generate-v0.14.0/src/data_0_14.rs b/backward-compatibility/generate-v0.14.0/src/data_0_14.rs index ba2752fe84..e20bf88026 100644 --- a/backward-compatibility/generate-v0.14.0/src/data_0_14.rs +++ b/backward-compatibility/generate-v0.14.0/src/data_0_14.rs @@ -3,14 +3,14 @@ //! for kms-core v0.14.0 use aes_prng::AesRng; -use algebra_0_13_20::{ +use algebra_0_14_0::{ galois_rings::degree_4::{ResiduePolyF4Z128, ResiduePolyF4Z64}, sharing::share::Share, }; -use kms_0_13_20::backup::custodian::{ +use kms_0_14_0::backup::custodian::{ Custodian, CustodianSetupMessagePayload, InternalCustodianContext, }; -use kms_0_13_20::backup::{ +use kms_0_14_0::backup::{ custodian::{InternalCustodianRecoveryOutput, InternalCustodianSetupMessage}, operator::{ BackupMaterial, InnerOperatorBackupOutput, InternalRecoveryRequest, Operator, @@ -18,8 +18,8 @@ use kms_0_13_20::backup::{ }, BackupCiphertext, }; -use kms_0_13_20::consts::SAFE_SER_SIZE_LIMIT; -use kms_0_13_20::cryptography::{ +use kms_0_14_0::consts::SAFE_SER_SIZE_LIMIT; +use kms_0_14_0::cryptography::{ encryption::{Encryption, PkeScheme, PkeSchemeType, UnifiedCipher}, hybrid_ml_kem::HybridKemCt, signatures::{compute_eip712_signature, gen_sig_keys, SigningSchemeType}, @@ -27,16 +27,16 @@ use kms_0_13_20::cryptography::{ Signcrypt, UnifiedSigncryption, UnifiedSigncryptionKeyOwned, UnifiedUnsigncryptionKeyOwned, }, }; -use kms_0_13_20::engine::base::{ +use kms_0_14_0::engine::base::{ safe_serialize_hash_element_versioned, CrsGenMetadata, KeyGenMetadataInner, KmsFheKeyHandles, }; -use kms_0_13_20::engine::centralized::central_kms::generate_client_fhe_key; -use kms_0_13_20::engine::context::{ContextInfo, NodeInfo, SoftwareVersion}; -use kms_0_13_20::engine::threshold::service::session::PRSSSetupCombined; -use kms_0_13_20::engine::threshold::service::{PublicKeyMaterial, ThresholdFheKeys}; -use kms_0_13_20::util::key_setup::FhePublicKey; -use kms_0_13_20::vault::keychain::AppKeyBlob; -use kms_grpc_0_13_20::{ +use kms_0_14_0::engine::centralized::central_kms::generate_client_fhe_key; +use kms_0_14_0::engine::context::{ContextInfo, NodeInfo, SoftwareVersion}; +use kms_0_14_0::engine::threshold::service::session::PRSSSetupCombined; +use kms_0_14_0::engine::threshold::service::{PublicKeyMaterial, ThresholdFheKeys}; +use kms_0_14_0::util::key_setup::FhePublicKey; +use kms_0_14_0::vault::keychain::AppKeyBlob; +use kms_grpc_0_14_0::{ kms::v1::{CustodianContext, CustodianSetupMessage, TypedPlaintext}, rpc_types::{PrivDataType, PubDataType, SignedPubDataHandleInternal}, solidity_types::{ @@ -70,9 +70,9 @@ use tfhe_1_6_1::{ ServerKey, Tag, }; use tfhe_versionable_0_7::Upgrade; -use threshold_execution_0_13_20::small_execution::prf::PrfKey; -use threshold_execution_0_13_20::tfhe_internals::public_keysets::FhePubKeySet; -use threshold_execution_0_13_20::{ +use threshold_execution_0_14_0::small_execution::prf::PrfKey; +use threshold_execution_0_14_0::tfhe_internals::public_keysets::FhePubKeySet; +use threshold_execution_0_14_0::{ small_execution::prss::{PrssSet, PrssSetV0}, tests::helper::testing::{get_dummy_prss_setup, get_networkless_base_session_for_parties}, tfhe_internals::{ @@ -80,8 +80,8 @@ use threshold_execution_0_13_20::{ test_feature::insecure_initialize_key_material, }, }; -use threshold_networking_0_13_20::tls::ReleasePCRValues; -use threshold_types_0_13_20::role::Role; +use threshold_networking_0_14_0::tls::ReleasePCRValues; +use threshold_types_0_14_0::role::Role; use tokio::runtime::Runtime; use backward_compatibility::parameters::{ @@ -103,7 +103,7 @@ use backward_compatibility::{ KMS_MODULE_NAME, }; -use kms_0_13_20::cryptography::signcryption::SigncryptionPayload; +use kms_0_14_0::cryptography::signcryption::SigncryptionPayload; use crate::generate::{ store_versioned_auxiliary_05, store_versioned_test_05, KMSCoreVersion, TEST_DKG_PARAMS_SNS, @@ -542,11 +542,11 @@ fn dummy_domain() -> alloy_sol_types_1_4_1::Eip712Domain { ) } -pub struct V0_13_20; +pub struct V0_14_0; -struct KmsV0_13_20; +struct KmsV0_14_0; -impl KmsV0_13_20 { +impl KmsV0_14_0 { fn gen_private_sig_key(dir: &PathBuf) -> TestMetadataKMS { let mut rng = AesRng::seed_from_u64(PRIVATE_SIG_KEY_TEST.state); let (_, private_sig_key) = gen_sig_keys(&mut rng); @@ -1033,6 +1033,7 @@ impl KmsV0_13_20 { let (custodian_pk, _) = gen_sig_keys(&mut rng); let backup_material = BackupMaterial { backup_id, + mpc_context_id: kms_grpc_0_14_0::ContextId::from_bytes([9u8; 32]), custodian_pk, custodian_role: cus_role, operator_pk: operator_pk.clone(), @@ -1096,7 +1097,7 @@ impl KmsV0_13_20 { commitments, internal_custodian_context, &operator_sk, - kms_grpc_0_13_20::ContextId::from_bytes(RECOVERY_MATERIAL_TEST.mpc_context_id), + kms_grpc_0_14_0::ContextId::from_bytes(RECOVERY_MATERIAL_TEST.mpc_context_id), ) .unwrap(); store_versioned_test!( @@ -1125,8 +1126,9 @@ impl KmsV0_13_20 { }; cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); } - let recovery_material = - InternalRecoveryRequest::new(enc_key, cts, backup_id, verf_key).unwrap(); + let _ = backup_id; + let _ = verf_key; + let recovery_material = InternalRecoveryRequest::new(enc_key, cts).unwrap(); store_versioned_test!( &recovery_material, dir, @@ -1254,8 +1256,8 @@ impl KmsV0_13_20 { // NOTE: kms_fhe_key_handles.public_key_info is a HashMap // so generation is not deterministic - let key_id = kms_grpc_0_13_20::RequestId::zeros(); - let preproc_id = kms_grpc_0_13_20::RequestId::zeros(); + let key_id = kms_grpc_0_14_0::RequestId::zeros(); + let preproc_id = kms_grpc_0_14_0::RequestId::zeros(); let kms_fhe_key_handles = KmsFheKeyHandles::new( &private_sig_key, client_key, @@ -1342,7 +1344,7 @@ impl KmsV0_13_20 { let threshold_fhe_keys = ThresholdFheKeys::new( std::sync::Arc::new(private_key_set), public_material, - kms_0_13_20::engine::base::KeyGenMetadata::LegacyV0(info), + kms_0_14_0::engine::base::KeyGenMetadata::LegacyV0(info), ); store_versioned_test!( @@ -1388,13 +1390,10 @@ impl KmsV0_13_20 { pke_type: PkeSchemeType::MlKem512, signing_type: SigningSchemeType::Ecdsa256k1, }; + let _ = operator_verification_key; let icro = InternalCustodianRecoveryOutput { signcryption, custodian_role: Role::indexed_from_one(2), - operator_verification_key, - mpc_context_id: kms_grpc_0_13_20::RequestId::from_bytes( - INTERNAL_CUS_REC_OUT_TEST.mpc_context_id, - ), }; store_versioned_test!(&icro, dir, &INTERNAL_CUS_REC_OUT_TEST.test_filename); TestMetadataKMS::InternalCustodianRecoveryOutput(INTERNAL_CUS_REC_OUT_TEST) @@ -1441,6 +1440,7 @@ impl KmsV0_13_20 { &mut rng, &OPERATOR_BACKUP_OUTPUT_TEST.plaintext, RequestId::from_bytes(OPERATOR_BACKUP_OUTPUT_TEST.backup_id), + kms_grpc_0_14_0::ContextId::from_bytes([9u8; 32]), ) .unwrap() .ct_shares[&Role::indexed_from_one(1)]; @@ -1454,9 +1454,9 @@ impl KmsV0_13_20 { } } -struct DistributedDecryptionV0_13_20; +struct DistributedDecryptionV0_14_0; -impl DistributedDecryptionV0_13_20 { +impl DistributedDecryptionV0_14_0 { fn gen_prss_setup_rpoly_64(dir: &PathBuf) -> TestMetadataDD { let role = Role::indexed_from_one(PRSS_SETUP_RPOLY_64_TEST.role_i); let base_session = get_networkless_base_session_for_parties( @@ -1614,9 +1614,9 @@ impl DistributedDecryptionV0_13_20 { } } -struct KmsGrpcV0_13_20; +struct KmsGrpcV0_14_0; -impl KmsGrpcV0_13_20 { +impl KmsGrpcV0_14_0 { fn gen_signed_pub_data_handle_internal(dir: &PathBuf) -> TestMetadataKmsGrpc { let signed_pub_data_handle_internal = SignedPubDataHandleInternal::new( SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.key_handle.to_string(), @@ -1667,33 +1667,33 @@ impl KMSCoreVersion for V0_14_0 { create_dir_all(&dir).unwrap(); vec![ - KmsV0_13_20::gen_private_sig_key(&dir), - KmsV0_13_20::gen_public_sig_key(&dir), - KmsV0_13_20::gen_app_key_blob(&dir), - KmsV0_13_20::gen_key_gen_metadata(&dir), - KmsV0_13_20::gen_crs_metadata(&dir), - KmsV0_13_20::gen_key_gen_metadata_with_extra_data(&dir), - KmsV0_13_20::gen_crs_metadata_with_extra_data(&dir), - KmsV0_13_20::gen_typed_plaintext(&dir), - KmsV0_13_20::gen_signcryption_payload(&dir), - KmsV0_13_20::gen_signcryption_key(&dir), - KmsV0_13_20::gen_designcryption_key(&dir), - KmsV0_13_20::gen_unified_signcryption(&dir), - KmsV0_13_20::gen_backup_ciphertext(&dir), - KmsV0_13_20::gen_unified_cipher(&dir), - KmsV0_13_20::gen_hybrid_kem_ct(&dir), - KmsV0_13_20::gen_prss_setup_combined(&dir), - KmsV0_13_20::gen_context_info(&dir), - KmsV0_13_20::gen_node_info(&dir), - KmsV0_13_20::gen_software_version(&dir), - KmsV0_13_20::gen_recovery_material(&dir), - KmsV0_13_20::gen_internal_recovery_request(&dir), - KmsV0_13_20::gen_internal_cus_context_handles(&dir), - KmsV0_13_20::gen_internal_cus_setup_msg(&dir), - KmsV0_13_20::gen_kms_fhe_key_handles(&dir), - KmsV0_13_20::gen_threshold_fhe_keys(&dir), - KmsV0_13_20::gen_internal_cus_rec_out(&dir), - KmsV0_13_20::gen_operator_backup_output(&dir), + KmsV0_14_0::gen_private_sig_key(&dir), + KmsV0_14_0::gen_public_sig_key(&dir), + KmsV0_14_0::gen_app_key_blob(&dir), + KmsV0_14_0::gen_key_gen_metadata(&dir), + KmsV0_14_0::gen_crs_metadata(&dir), + KmsV0_14_0::gen_key_gen_metadata_with_extra_data(&dir), + KmsV0_14_0::gen_crs_metadata_with_extra_data(&dir), + KmsV0_14_0::gen_typed_plaintext(&dir), + KmsV0_14_0::gen_signcryption_payload(&dir), + KmsV0_14_0::gen_signcryption_key(&dir), + KmsV0_14_0::gen_designcryption_key(&dir), + KmsV0_14_0::gen_unified_signcryption(&dir), + KmsV0_14_0::gen_backup_ciphertext(&dir), + KmsV0_14_0::gen_unified_cipher(&dir), + KmsV0_14_0::gen_hybrid_kem_ct(&dir), + KmsV0_14_0::gen_prss_setup_combined(&dir), + KmsV0_14_0::gen_context_info(&dir), + KmsV0_14_0::gen_node_info(&dir), + KmsV0_14_0::gen_software_version(&dir), + KmsV0_14_0::gen_recovery_material(&dir), + KmsV0_14_0::gen_internal_recovery_request(&dir), + KmsV0_14_0::gen_internal_cus_context_handles(&dir), + KmsV0_14_0::gen_internal_cus_setup_msg(&dir), + KmsV0_14_0::gen_kms_fhe_key_handles(&dir), + KmsV0_14_0::gen_threshold_fhe_keys(&dir), + KmsV0_14_0::gen_internal_cus_rec_out(&dir), + KmsV0_14_0::gen_operator_backup_output(&dir), ] } @@ -1702,14 +1702,14 @@ impl KMSCoreVersion for V0_14_0 { create_dir_all(&dir).unwrap(); vec![ - DistributedDecryptionV0_13_20::gen_prss_setup_rpoly_64(&dir), - DistributedDecryptionV0_13_20::gen_prss_setup_rpoly_128(&dir), - DistributedDecryptionV0_13_20::gen_prss_set_64(&dir), - DistributedDecryptionV0_13_20::gen_prss_set_128(&dir), - DistributedDecryptionV0_13_20::gen_share_64(&dir), - DistributedDecryptionV0_13_20::gen_share_128(&dir), - DistributedDecryptionV0_13_20::gen_prf_key(&dir), - DistributedDecryptionV0_13_20::gen_release_pcr_values(&dir), + DistributedDecryptionV0_14_0::gen_prss_setup_rpoly_64(&dir), + DistributedDecryptionV0_14_0::gen_prss_setup_rpoly_128(&dir), + DistributedDecryptionV0_14_0::gen_prss_set_64(&dir), + DistributedDecryptionV0_14_0::gen_prss_set_128(&dir), + DistributedDecryptionV0_14_0::gen_share_64(&dir), + DistributedDecryptionV0_14_0::gen_share_128(&dir), + DistributedDecryptionV0_14_0::gen_prf_key(&dir), + DistributedDecryptionV0_14_0::gen_release_pcr_values(&dir), ] } @@ -1718,9 +1718,9 @@ impl KMSCoreVersion for V0_14_0 { create_dir_all(&dir).unwrap(); vec![ - KmsGrpcV0_13_20::gen_signed_pub_data_handle_internal(&dir), - KmsGrpcV0_13_20::gen_pub_data_type(&dir), - KmsGrpcV0_13_20::gen_priv_data_type(&dir), + KmsGrpcV0_14_0::gen_signed_pub_data_handle_internal(&dir), + KmsGrpcV0_14_0::gen_pub_data_type(&dir), + KmsGrpcV0_14_0::gen_priv_data_type(&dir), ] } } diff --git a/backward-compatibility/generate-v0.14.0/src/lib.rs b/backward-compatibility/generate-v0.14.0/src/lib.rs index 6a8eb286f2..a07a7d51b1 100644 --- a/backward-compatibility/generate-v0.14.0/src/lib.rs +++ b/backward-compatibility/generate-v0.14.0/src/lib.rs @@ -3,5 +3,5 @@ //! This crate is separate from `backward-compatibility` to isolate version-specific //! dependencies (like old KMS versions) from the test loading and execution logic. -pub mod data_0_13; +pub mod data_0_14; pub mod generate; diff --git a/backward-compatibility/generate-v0.14.0/src/main.rs b/backward-compatibility/generate-v0.14.0/src/main.rs index 9e2aaf50a9..64d5de52d2 100644 --- a/backward-compatibility/generate-v0.14.0/src/main.rs +++ b/backward-compatibility/generate-v0.14.0/src/main.rs @@ -4,8 +4,8 @@ use backward_compatibility::{ data_dir, TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc, Testcase, DISTRIBUTED_DECRYPTION_MODULE_NAME, KMS_GRPC_MODULE_NAME, KMS_MODULE_NAME, PRNG_SEED, }; -use backward_compatibility_generate_v0_13_20::{ - data_0_13::V0_13_20, +use backward_compatibility_generate_v0_14_0::{ + data_0_14::V0_14_0, generate::{store_metadata, KMSCoreVersion}, }; @@ -55,7 +55,7 @@ fn gen_all_data() -> (KmsTestcases, KmsGrpcTestcases, DdTe } fn main() { - let (kms_testcases, kms_grpc_testcases, dd_testcases) = gen_all_data::(); + let (kms_testcases, kms_grpc_testcases, dd_testcases) = gen_all_data::(); // Use module name as the filename prefix store_metadata(&kms_testcases, data_dir().join("kms.ron")); diff --git a/docs/developer/backward_compatibility.md b/docs/developer/backward_compatibility.md index 0de00ecf41..cc0516913e 100644 --- a/docs/developer/backward_compatibility.md +++ b/docs/developer/backward_compatibility.md @@ -36,6 +36,7 @@ However, this does not allow changes to be made to the test metadata scheme itse - `backward-compatibility/generate-v0.13.0` - For KMS v0.13.0 - `backward-compatibility/generate-v0.13.10` - For KMS v0.13.10 - `backward-compatibility/generate-v0.13.20` - For KMS v0.13.20 +- `backward-compatibility/generate-v0.14.0` - For KMS v0.14.0 Each generator uses the exact dependencies from its target KMS version. @@ -63,6 +64,9 @@ make generate-backward-compatibility-v0.13.10 # Generate only v0.13.20 data make generate-backward-compatibility-v0.13.20 +# Generate only v0.14.0 data +make generate-backward-compatibility-v0.14.0 + ``` WARNING: Generating for specific versions removes previously generated data from the `.ron` files, effectively ignoring other versions in the tests! Thus, changes based on generating a specific version should NEVER be committed to the repo. From f8140ae343711eec7befa9f6b05d6016b54605b1 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 16:36:55 +0200 Subject: [PATCH 08/29] fix: broken test --- .../tests/integration/integration_test.rs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/core-client/tests/integration/integration_test.rs b/core-client/tests/integration/integration_test.rs index c7513d7f4d..e6f31ece5d 100644 --- a/core-client/tests/integration/integration_test.rs +++ b/core-client/tests/integration/integration_test.rs @@ -1829,12 +1829,12 @@ fn extract_seed_phrase(out: Output) -> String { .to_string() } -/// Native implementation: Initialize custodian backup using isolated config +/// Native implementation: Initialize custodian backup using isolated config. async fn custodian_backup_init( config_path: &Path, test_path: &Path, operator_recovery_resp_paths: Vec, -) -> String { +) { let config = cmd_config( config_path, CCCommand::CustodianRecoveryInit(RecoveryInitParameters { @@ -1843,10 +1843,10 @@ async fn custodian_backup_init( }), 200, ); - run_cmd(&config, test_path, "backup init") + let results = execute_cmd(&config, test_path) .await - .unwrap() - .to_string() + .expect("backup init: execute_cmd failed"); + assert_eq!(results.len(), 1, "backup init: expected 1 result"); } /// Native implementation: Re-encrypt custodian backups using kms-custodian binary directly @@ -2199,20 +2199,19 @@ async fn test_centralized_custodian_backup() -> Result<()> { create_dir_all(operator_recovery_resp_path.parent().unwrap())?; // Initialize custodian backup - let init_backup_id = custodian_backup_init( + custodian_backup_init( &config_path, temp_path, vec![operator_recovery_resp_path.clone()], ) .await; - assert_eq!(cus_backup_id, init_backup_id); // Re-encrypt with custodian keys let recovery_output_paths = custodian_reencrypt( temp_path, 1, amount_custodians, - init_backup_id.parse()?, + RequestId::from_str(&cus_backup_id)?, *DEFAULT_MPC_CONTEXT, &seeds, &[operator_recovery_resp_path], @@ -2596,20 +2595,19 @@ async fn test_threshold_custodian_backup() -> Result<()> { } // Initialize custodian backup - let init_backup_id = custodian_backup_init( + custodian_backup_init( &config_path, temp_path, operator_recovery_resp_paths.clone(), ) .await; - assert_eq!(cus_backup_id, init_backup_id); // Re-encrypt with custodian keys let recovery_output_paths = custodian_reencrypt( temp_path, amount_operators, amount_custodians, - init_backup_id.parse()?, + RequestId::from_str(&cus_backup_id)?, *DEFAULT_MPC_CONTEXT, &seeds, &operator_recovery_resp_paths, From e2634ccface94fd4efbd42241f89fef7c8531702 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 17:12:25 +0200 Subject: [PATCH 09/29] docs: enhanced details on backup --- docs/guides/backup.md | 133 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 2 deletions(-) diff --git a/docs/guides/backup.md b/docs/guides/backup.md index 2cea80e584..2f0c08c17e 100644 --- a/docs/guides/backup.md +++ b/docs/guides/backup.md @@ -54,7 +54,8 @@ $ kms-backup decrypt --seed-phrase --rando Observe that the `randomness` supplied is used along with entropy of the current system to do re-encryption, and thus the command is *not* idempotent. IMPORTANT: IT IS NOT POSSIBLE FOR THE CUSTODIAN TO VALIDATE THE AUTHENTICITY OF A REQUEST! HENCE IT IS PARAMOUNT THAT IT IS VALIDATED OUT-OF-BOUNDS, E.G. THROUGH A DIGEST ON A BLOCKCHAIN. -Run the CLI tool with the `decrypt` command in order decrypt a backup, and then reencrypt it under a supplied operator keyset. More specifically: + +Run the CLI tool with the `decrypt` command in order to decrypt a backup, and then reencrypt it under a supplied operator keyset. More specifically: ```{bash} $ cargo run --bin kms-custodian decrypt --seed-phrase --randomness --custodian-role <1-indexed role of the custodian> --recovery-request-path --operator-verf-key --output-path ``` @@ -65,4 +66,132 @@ For example: $ cargo run --bin kms-custodian decrypt --seed-phrase "stick essence exhaust bunker meat orchard wolf timber tackle gesture video cheap" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-1 ``` -IMPORTANT: IT IS NOT POSSIBLE FOR THE CUSTODIAN TO VALIDATE THE AUTHENTICITY OF A REQUEST! HENCE IT IS PARAMOUNT THAT IT IS VALIDATED OUT-OF-BOUNDS, E.G. THROUGH A DIGEST ON A BLOCKCHAIN. +--- + +## Protocol details + +The rest of this document is background material for readers who want to understand what the CLI commands do under the hood. It is not required to use the tool. + +The custodian-based backup protocol provides disaster recovery for KMS operators by Shamir-sharing a per-context backup encryption key across `n` offline custodians, tolerating up to `t` corruptions (`t < n/2`). At recovery time, `t + 1` honest custodians cooperate with the recovering operator to reconstruct the backup decryption key, which is then used to decrypt the operator's private key material from the backup vault. + +The alternative backup mode — wrapping the same key under an AWS KMS CMK — is documented in [ai-docs/ARCHITECTURE.md](../../ai-docs/ARCHITECTURE.md#backup-and-recovery). + +### Parties + +| Party | What it does | +|---|---| +| **Custodian `B_j`** (`j = 1..n`) | Human-held, offline party. Owns a long-term signing key `sk^{S_j}` and a post-quantum encryption key `sk^{E_j}`, both deterministically derived from a BIP39 seed phrase. Stores nothing online beyond its public-key half published in the `CustodianSetupMessage`. Re-signcrypts its share of the backup key on request. | +| **Operator `P_i`** (KMS node) | Online KMS server. Holds a long-term signing key `sk^{P_i}`, a TFHE FHE secret key, and other private material that needs backing up. Receives `NewCustodianContext` and, later, `CustodianRecoveryInit` / `CustodianBackupRecovery` gRPC calls from the core-client. | +| **core-client** | The CLI that drives every gRPC call into the KMS for custodian-based backup. It bundles the operator-bound RPCs (`NewCustodianContext`, `CustodianRecoveryInit`, `CustodianBackupRecovery`, `RestoreFromBackup`) and shuttles the resulting `RecoveryRequest` / `InternalCustodianRecoveryOutput` files between the operator and the custodians out-of-band. Documented in [docs/guides/core_client.md](core_client.md). | +| **Recovering operator `P_i'`** | A fresh operator process replacing `P_i` after the latter's private storage was lost. Reads only the public storage and the backup vault; coordinates with custodians (via the core-client) to rebuild private state. | + +### Data components + +All names below match the Rust/proto types so you can grep for them. + +| Component | Where it lives | Carries | +|---|---|---| +| [`CustodianSetupMessage`](../../core/grpc/proto/kms.v1.proto) | gRPC + custodian's `--path` file | `{ custodian_role, name, payload }`. `payload` is a versioned [`CustodianSetupMessagePayload`](../../core/service/src/backup/custodian.rs) `{ header, random_value, timestamp, public_enc_key = pk^{E_j}, verification_key = pk^{S_j} }`. | +| [`CustodianContext`](../../core/grpc/proto/kms.v1.proto) | Argument to `NewCustodianContext` RPC | `{ custodian_nodes: [CustodianSetupMessage], custodian_context_id, threshold }`. | +| [`InternalCustodianContext`](../../core/service/src/backup/custodian.rs) | Operator's private storage (replicated through the backup vault) | `{ threshold, context_id, custodian_nodes, backup_enc_key }`. `backup_enc_key = pk^{B}` is the per-context public key whose secret half is Shamir-shared to the custodians. | +| [`BackupMaterial`](../../core/service/src/backup/operator.rs) | Plaintext payload **inside** every operator→custodian signcryption | `{ backup_id (= custodian_context_id), mpc_context_id, custodian_pk = pk^{S_j}, custodian_role, operator_pk, shares: Vec }`. Authenticates the binding between operator, custodian, and context. | +| [`OperatorBackupOutput`](../../core/grpc/proto/kms.v1.proto) | gRPC value | A signcryption `(payload, pke_type, signing_type)`. Plaintext is `BackupMaterial`. Created with `(sk^{P_i}, pk^{E_j})` and the custodian's verf-key ID as `receiver_id`. | +| [`RecoveryValidationMaterial`](../../core/service/src/backup/operator.rs) | Operator's **public** storage at `custodian_context_id` | Operator-signed `{ cts: BTreeMap, commitments: BTreeMap, custodian_context: InternalCustodianContext, mpc_context }`. Lets the recovering operator re-fetch the original signcryptions and verify them against the operator-signed commitments. | +| `BackupCiphertext` | Backup vault | Long-term private material (signing key, threshold FHE keys, custodian context, …) encrypted under `pk^{B}` (`backup_enc_key`). Tagged with `RequestId` + `PrivDataType` — see [ARCHITECTURE.md](../../ai-docs/ARCHITECTURE.md#backup-and-recovery). | +| [`RecoveryRequest`](../../core/grpc/proto/kms.v1.proto) | Result of `CustodianRecoveryInit` (operator → core-client → custodian's `--recovery-request-path`) | `{ ephem_op_enc_key = pk^{e_i}, cts: map }`. Carries (a) the operator's ephemeral encryption key for this recovery session and (b) the same signcrypted shares the operator stored at backup time. | +| [`InternalCustodianRecoveryOutput`](../../core/service/src/backup/custodian.rs) | Custodian's `--output-path` file → core-client | `{ signcryption, custodian_role }`. The signcryption is the **custodian → recovering-operator** envelope, made with `(sk^{S_j}, pk^{e_i})` over the same `BackupMaterial`. | +| [`CustodianRecoveryOutput`](../../core/grpc/proto/kms.v1.proto) | gRPC payload | Wire form of `InternalCustodianRecoveryOutput`: `{ backup_output, custodian_role }`. | +| [`CustodianRecoveryRequest`](../../core/grpc/proto/kms.v1.proto) | core-client → operator gRPC | `{ custodian_context_id, custodian_recovery_outputs: [CustodianRecoveryOutput] }`. | + +### Protocol overview + +The diagram below shows every message that crosses a party boundary in the six phases. Internal computation (how each party builds or validates a message) is described in the prose under each phase; here we focus only on which object is sent where. + +```mermaid +sequenceDiagram + autonumber + participant Cus as Custodian B_j (air-gapped) + participant Cli as core-client + participant Op as Operator P_i / P_i' + participant Pub as Public storage + participant Vault as Backup vault + + rect rgba(200, 230, 255, 0.25) + Note over Cus, Vault: Phase 1 — Custodian setup + Cus->>Cli: CustodianSetupMessage (file, out-of-band) + end + + rect rgba(220, 240, 220, 0.25) + Note over Cus, Vault: Phase 2 — Custodian context creation + Cli->>Op: NewCustodianContextRequest + Op->>Pub: RecoveryValidationMaterial + Op->>Vault: BackupCiphertext (InternalCustodianContext) + end + + rect rgba(245, 235, 200, 0.25) + Note over Cus, Vault: Phase 3 — Ongoing backup + Op->>Vault: BackupCiphertext (continuous, per PrivDataType write) + end + + rect rgba(255, 220, 220, 0.25) + Note over Cus, Vault: Phase 4 — Recovery init + Cli->>Op: CustodianRecoveryInitRequest + Pub-->>Op: RecoveryValidationMaterial + Op-->>Cli: RecoveryRequest + end + + rect rgba(230, 220, 245, 0.25) + Note over Cus, Vault: Phase 5 — Custodian re-encryption + Cli->>Cus: RecoveryRequest (+ operator verf-key, out-of-band) + Cus-->>Cli: InternalCustodianRecoveryOutput + end + + rect rgba(220, 245, 240, 0.25) + Note over Cus, Vault: Phase 6 — Recovery finalization + Cli->>Op: CustodianRecoveryRequest + Pub-->>Op: RecoveryValidationMaterial + Cli->>Op: RestoreFromBackup + Vault-->>Op: BackupCiphertext (per PrivDataType, in a loop) + end +``` + +### Phase 1 — Custodian setup (offline, one-time per custodian) + +Corresponds to [`kms-custodian generate`](#custodian-setup). A future custodian boots the air-gapped machine and runs the command. Keys are deterministically derived from system entropy mixed with a user-supplied `--randomness` string; the matching BIP39 seed phrase is printed to stdout **once** and must be copied onto paper. + +The seed phrase is the only durable secret the custodian holds. `sk^{E_j}` and `sk^{S_j}` are re-derived from it whenever the custodian participates in a recovery. + +### Phase 2 — Custodian context creation (online, one-time per context) + +The core-client gathers `n` `CustodianSetupMessage`s (from each custodian's `--path` file), picks a corruption threshold `t < n/2`, and issues a `NewCustodianContext` gRPC call to every operator in the KMS cluster. Each operator, independently: generates a per-context backup keypair `(sk^{B}, pk^{B})`, Shamir-shares `sk^{B}` into `n` shares, builds and signcrypts one `BackupMaterial` per custodian role, computes a commitment over each `BackupMaterial`, packages everything into a signed `RecoveryValidationMaterial` (written to public storage at `request_id = custodian_context_id`), and encrypts the resulting `InternalCustodianContext` into a `BackupCiphertext` for the backup vault. After secret-sharing, the operator drops `sk^{B}` and installs `pk^{B}` in its `SecretSharing` keychain. + +Notes: +- The Shamir threshold encoded inside `RecoveryValidationMaterial.custodian_context.threshold` is the **recovery** threshold (`t + 1` shares needed). `Operator::new_for_sharing` enforces `t < n/2`. +- `sk^{B}` is **only** held in memory during this RPC. After secret-sharing it, the operator drops it. +- The commitment `c_j = H(BackupMaterial_j)` is what the recovering operator later checks against the decrypted material — it lets a single signature on `RecoveryValidationMaterial` authenticate every share at once, without making the encrypted plaintext public. + +### Phase 3 — Ongoing backup (whenever the operator writes private material) + +When the operator writes any `PrivDataType` (signing key, threshold FHE keys, custodian context itself, etc.) into private storage, the `SecretSharing` keychain wraps the bytes under `pk^{B}` and stores the resulting `BackupCiphertext` in the backup vault, tagged with the originating `RequestId` and `PrivDataType`. The custodians never see this material — only `pk^{B}` matters here. + +This phase is invisible to custodians and to the core-client. It runs continuously for the life of the operator. + +### Phase 4 — Recovery init (operator's private storage is gone) + +The recovering operator boots against the same **public** storage and backup vault but with empty private storage. It calls `CustodianRecoveryInit`, generates an ephemeral encryption keypair `(sk^{e_i}, pk^{e_i})` pinned in process memory, reads `RecoveryValidationMaterial` from public storage at `ctx_id`, verifies the operator's signature on it, and returns a `RecoveryRequest` to the core-client (which writes it to disk for later distribution to the custodians). + +The recovering operator has the same long-term signing key as the original (recovered out of band from public storage), so `RecoveryValidationMaterial`'s signature still verifies. + +`sk^{e_i}` lives only in process memory; restarting the server discards it. `overwrite_ephemeral_key=true` lets a stuck recovery be re-initiated. + +### Phase 5 — Custodian re-encryption (offline, manual) + +Corresponds to [`kms-custodian decrypt`](#recovery-decryption-of-backup). The core-client (or operator's human operator) distributes the `RecoveryRequest` and the recovering operator's verification key out-of-band to each custodian's air-gapped machine. The custodian boots, types in the seed phrase, and runs the command: re-derives `(sk^{E_j}, sk^{S_j})` from the seed phrase, unsigncrypts its share of `BackupMaterial` from `cts[j]`, sanity-checks the metadata inside and then re-signcrypts the same `BackupMaterial` to the operator's ephemeral key `pk^{e_i}`, and writes the resulting `InternalCustodianRecoveryOutput` to `--output-path`. + +The custodian's only cryptographic obligation is "decrypt your share and re-signcrypt it for the operator's ephemeral key". The custodian can't (and isn't asked to) judge whether this request is legitimate — see the warning at the top of the [Recovery](#recovery-decryption-of-backup) section. + +### Phase 6 — Recovery finalization (operator reconstructs) + +The core-client collects `t + 1` (or more) custodian output files and sends them, in a single `CustodianRecoveryRequest`, to every operator in the cluster. The recovering operator re-reads `RecoveryValidationMaterial` from public storage and validates each `CustodianRecoveryOutput`, and once at least `t + 1` shares pass — Shamir-reconstructs `sk^{B}` and installs it in the `SecretSharing` keychain. A subsequent `RestoreFromBackup` call then iterates every `BackupCiphertext` in the backup vault, decrypts each with `sk^{B}`, and writes the plaintext into the now-empty private storage. + +After Phase 6 the recovering operator's private storage is repopulated and the node resumes normal service. The operator-side commands that drive Phases 4 and 6 are documented in [docs/guides/core_client.md](core_client.md). From 22e1be2c69eb60dd83bc9f74f56d90abb985e774 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 17:46:46 +0200 Subject: [PATCH 10/29] chore: added bound check to encryption --- core/service/src/vault/keychain/mod.rs | 53 +++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/core/service/src/vault/keychain/mod.rs b/core/service/src/vault/keychain/mod.rs index 24675db6bc..0b38b5fe25 100644 --- a/core/service/src/vault/keychain/mod.rs +++ b/core/service/src/vault/keychain/mod.rs @@ -184,6 +184,11 @@ pub fn encrypt_under_data_key( ) -> anyhow::Result> { let cipher = Aes256GcmSiv::new_from_slice(key) .map_err(|_| anyhow_error_and_log("Invalid data key length: must be 256 bits"))?; + if iv.len() != 12 { + return Err(anyhow_error_and_log( + "Invalid IV length: must be exactly 96 bits for AES GCM", + )); + } #[allow(deprecated)] let nonce = Nonce::from_slice(iv); let auth_tag = cipher @@ -202,6 +207,16 @@ pub fn decrypt_under_data_key( #[allow(deprecated)] let cipher = Aes256GcmSiv::new_from_slice(key) .map_err(|_| anyhow_error_and_log("Invalid data key length: must be 256 bits"))?; + if iv.len() != 12 { + return Err(anyhow_error_and_log( + "Invalid IV length: must be exactly 96 bits for AES GCM", + )); + } + if auth_tag.len() != 16 { + return Err(anyhow_error_and_log( + "Invalid auth tag length: must be exactly 128 bits for AES GCM", + )); + } #[allow(deprecated)] let nonce = Nonce::from_slice(iv); cipher @@ -215,11 +230,47 @@ pub mod tests { use super::{ RootKeyMeasurements, awskms::{canonicalize_iam_policy, make_root_key_policy}, - verify_root_key_measurements, + decrypt_under_data_key, encrypt_under_data_key, verify_root_key_measurements, }; use iam_rs::{IAMPolicy, IAMVersion}; use threshold_networking::tls::ReleasePCRValues; + /// Sunshine test: a plaintext encrypted with a valid 32-byte key and + /// 12-byte IV must decrypt back to the original bytes. + #[test] + fn test_encrypt_decrypt_under_data_key_roundtrip() { + let key = [0x42u8; 32]; + let iv = [0xABu8; 12]; + let plaintext = b"hello world, this is a secret payload".to_vec(); + + let mut buf = plaintext.clone(); + let auth_tag = encrypt_under_data_key(&mut buf, &key, &iv) + .expect("encryption should succeed with a 32-byte key and 12-byte IV"); + assert_ne!(buf, plaintext, "ciphertext must differ from plaintext"); + + decrypt_under_data_key(&mut buf, &key, &iv, &auth_tag) + .expect("decryption should succeed with the same key, IV and auth tag"); + assert_eq!(buf, plaintext, "decrypted bytes must match the plaintext"); + } + + #[test] + fn test_encrypt_under_data_key_rejects_invalid_iv() { + let key = [0u8; 32]; + let invalid_iv_lens = (0..12).chain([13usize, 16, 24, 32, 64]); + for iv_len in invalid_iv_lens { + let iv = vec![0u8; iv_len]; + let mut buf = b"some payload".to_vec(); + let err = encrypt_under_data_key(&mut buf, &key, &iv).expect_err(&format!( + "encryption should reject an IV of length {iv_len}" + )); + assert!( + err.to_string().contains("IV length"), + "error should mention IV length, got: {err}" + ); + } + } + + #[test] fn test_verify_root_key_measurements() { let good_pcr_values = ReleasePCRValues { From eb74a55e1312f383fdb0ae254ca33d5b792746ef Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 18:23:08 +0200 Subject: [PATCH 11/29] chore: self review --- .claude/settings.json | 114 +++++++++--------- .../generate-v0.14.0/src/data_0_14.rs | 6 - core-client/src/backup.rs | 6 - core/grpc/proto/kms.v1.proto | 3 - core/grpc/src/identifiers.rs | 8 -- core/service/src/backup/custodian.rs | 9 +- core/service/src/backup/operator.rs | 6 +- core/service/src/engine/backup_operator.rs | 5 +- core/service/src/vault/keychain/mod.rs | 1 - 9 files changed, 67 insertions(+), 91 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index bc0d1e93c6..38460779c4 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,55 +1,61 @@ { - "sandbox": { - "enabled": true - }, - "permissions": { - "deny": [ - "Read(**/target/**)", - "Read(./.env)", - "Read(./.env.*)", - "Read(**/*.pem)", - "Read(**/*.key)", - "Read(**/*.cert)", - "Read(**/*.p12)", - "Read(**/*.pfx)", - "Read(**/secrets.*)", - "Read(**/credentials.*)", - "Read(./secrets/**)", - "Read(./keys/**)", - "Read(./.github/secrets/**)", - "Edit(**/.ssh/**)", - "Read(**/.ssh/**)", - "Bash(rm -rf *)", - "Bash(rm -fr *)", - "Bash(sudo *)", - "Bash(mkfs *)", - "Bash(dd *)", - "Bash(curl *|bash*)", - "Bash(wget *|bash*)", - "Bash(git push --force*)", - "Bash(git push *--force*)", - "Bash(git reset --hard*)", - "Edit(~/.bashrc)", - "Edit(~/.zshrc)", - "Edit(~/.ssh/**)", - "Read(~/.ssh/**)", - "Read(~/.gnupg/**)", - "Read(~/.aws/**)", - "Read(~/.azure/**)", - "Read(~/.config/gh/**)", - "Read(~/.git-credentials)", - "Read(~/.docker/config.json)", - "Read(~/.kube/**)", - "Read(~/.npmrc)", - "Read(~/.npm/**)", - "Read(~/.pypirc)", - "Read(~/.gem/credentials)", - "Read(~/Library/Keychains/**)", - "Read(~/Library/Application Support/**/metamask*/**)", - "Read(~/Library/Application Support/**/electrum*/**)", - "Read(~/Library/Application Support/**/exodus*/**)", - "Read(~/Library/Application Support/**/phantom*/**)", - "Read(~/Library/Application Support/**/solflare*/**)" - ] - } -} \ No newline at end of file + "permissions": { + "allow": [ + "Read(//Users/jot2re/Code/tech-spec/architecture/completed_intercomponent_flows/**)" + ], + "deny": [ + "Read(**/target/**)", + "Read(./.env)", + "Read(./.env.*)", + "Read(**/*.pem)", + "Read(**/*.key)", + "Read(**/*.cert)", + "Read(**/*.p12)", + "Read(**/*.pfx)", + "Read(**/secrets.*)", + "Read(**/credentials.*)", + "Read(./secrets/**)", + "Read(./keys/**)", + "Read(./.github/secrets/**)", + "Edit(**/.ssh/**)", + "Read(**/.ssh/**)", + "Bash(rm -rf *)", + "Bash(rm -fr *)", + "Bash(sudo *)", + "Bash(mkfs *)", + "Bash(dd *)", + "Bash(curl *|bash*)", + "Bash(wget *|bash*)", + "Bash(git push --force*)", + "Bash(git push *--force*)", + "Bash(git reset --hard*)", + "Edit(~/.bashrc)", + "Edit(~/.zshrc)", + "Edit(~/.ssh/**)", + "Read(~/.ssh/**)", + "Read(~/.gnupg/**)", + "Read(~/.aws/**)", + "Read(~/.azure/**)", + "Read(~/.config/gh/**)", + "Read(~/.git-credentials)", + "Read(~/.docker/config.json)", + "Read(~/.kube/**)", + "Read(~/.npmrc)", + "Read(~/.npm/**)", + "Read(~/.pypirc)", + "Read(~/.gem/credentials)", + "Read(~/Library/Keychains/**)", + "Read(~/Library/Application Support/**/metamask*/**)", + "Read(~/Library/Application Support/**/electrum*/**)", + "Read(~/Library/Application Support/**/exodus*/**)", + "Read(~/Library/Application Support/**/phantom*/**)", + "Read(~/Library/Application Support/**/solflare*/**)" + ], + "additionalDirectories": [ + "/Users/jot2re/Code/tech-spec/architecture/completed_intercomponent_flows" + ] + }, + "sandbox": { + "enabled": true + } +} diff --git a/backward-compatibility/generate-v0.14.0/src/data_0_14.rs b/backward-compatibility/generate-v0.14.0/src/data_0_14.rs index e20bf88026..a15f439b12 100644 --- a/backward-compatibility/generate-v0.14.0/src/data_0_14.rs +++ b/backward-compatibility/generate-v0.14.0/src/data_0_14.rs @@ -1110,10 +1110,8 @@ impl KmsV0_14_0 { fn gen_internal_recovery_request(dir: &PathBuf) -> TestMetadataKMS { let mut rng = AesRng::seed_from_u64(INTERNAL_RECOVERY_REQUEST_TEST.state); - let backup_id: RequestId = RequestId::new_random(&mut rng); let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); let (_dec_key, enc_key) = encryption.keygen().unwrap(); - let (verf_key, _) = gen_sig_keys(&mut rng); let mut cts = BTreeMap::new(); for role_j in 1..=INTERNAL_RECOVERY_REQUEST_TEST.amount { let cur_role = Role::indexed_from_one(role_j as usize); @@ -1126,8 +1124,6 @@ impl KmsV0_14_0 { }; cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); } - let _ = backup_id; - let _ = verf_key; let recovery_material = InternalRecoveryRequest::new(enc_key, cts).unwrap(); store_versioned_test!( &recovery_material, @@ -1382,7 +1378,6 @@ impl KmsV0_14_0 { fn gen_internal_cus_rec_out(dir: &PathBuf) -> TestMetadataKMS { let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_REC_OUT_TEST.state); - let (operator_verification_key, _) = gen_sig_keys(&mut rng); let mut buf = [0u8; 100]; rng.fill_bytes(&mut buf); let signcryption = UnifiedSigncryption { @@ -1390,7 +1385,6 @@ impl KmsV0_14_0 { pke_type: PkeSchemeType::MlKem512, signing_type: SigningSchemeType::Ecdsa256k1, }; - let _ = operator_verification_key; let icro = InternalCustodianRecoveryOutput { signcryption, custodian_role: Role::indexed_from_one(2), diff --git a/core-client/src/backup.rs b/core-client/src/backup.rs index 7c6c882723..45f814bbd6 100644 --- a/core-client/src/backup.rs +++ b/core-client/src/backup.rs @@ -129,12 +129,6 @@ pub(crate) async fn do_custodian_recovery_init( } /// Send every custodian recovery output to every operator. -/// -/// We no longer carry an `operator_verification_key` hint on the wire or in the on-disk -/// `InternalCustodianRecoveryOutput`. Each operator's `filter_custodian_data` will skip outputs not -/// addressed to it: they fail `validate_signcryption` because the signcryption's `receiver_id` was -/// bound to a specific operator at backup time. Bandwidth is `N × M` outputs (operators × custodians), -/// which is sub-megabyte even at the upper end of typical KMS sizes. pub(crate) async fn do_custodian_backup_recovery( core_endpoints: &HashMap>, custodian_context_id: RequestId, diff --git a/core/grpc/proto/kms.v1.proto b/core/grpc/proto/kms.v1.proto index 307b4c29d9..b8520fc582 100644 --- a/core/grpc/proto/kms.v1.proto +++ b/core/grpc/proto/kms.v1.proto @@ -660,9 +660,6 @@ message CustodianRecoveryInitRequest { } // The data constructed by a single custodian to help a single operator recover their private master decryption key. -// -// `custodian_role` is kept in the clear here purely as a lookup hint — the custodian role is also part of the `BackupMaterial` -// payload which is what is validated. message CustodianRecoveryOutput { OperatorBackupOutput backup_output = 1; // The 1-indexed role of the custodian (lookup hint; authenticated copy lives in the signcrypted BackupMaterial) diff --git a/core/grpc/src/identifiers.rs b/core/grpc/src/identifiers.rs index a08e77419d..d0c501cf1d 100644 --- a/core/grpc/src/identifiers.rs +++ b/core/grpc/src/identifiers.rs @@ -383,14 +383,6 @@ macro_rules! impl_identifiers { } } - impl<'a> From<&'a $type> for v1::RequestId { - fn from(id: &'a $type) -> Self { - v1::RequestId { - request_id: id.to_string(), - } - } - } - // Additional reverse conversion implementations impl From<$type> for String { fn from(id: $type) -> Self { diff --git a/core/service/src/backup/custodian.rs b/core/service/src/backup/custodian.rs index f1b19bb4fe..e9cda9f2d9 100644 --- a/core/service/src/backup/custodian.rs +++ b/core/service/src/backup/custodian.rs @@ -38,10 +38,7 @@ pub enum InternalCustodianRecoveryOutputVersioned { /// This is the message that a custodian sends to an operator after starting recovery. /// -/// All operator-facing context — operator long-term verification key, custodian role binding, MPC -/// context, custodian context — lives inside the signcrypted `BackupMaterial` payload carried by -/// `signcryption`. The plaintext `custodian_role` here is a lookup hint only: the operator uses it -/// to pick which custodian's verification key to plug into the unsigncryption. +/// The payload of the signcryption is a `BackupMaterial` that contains the decrypted backup share for an operator. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Versionize)] #[versionize(InternalCustodianRecoveryOutputVersioned)] pub struct InternalCustodianRecoveryOutput { @@ -342,13 +339,13 @@ impl Custodian { return Err(BackupError::CustodianRecoveryError); } // check the decrypted result - if let Err(mismatch) = backup_material.check_expected_metadata( + if let Err(e) = backup_material.check_expected_metadata( &self.signing_key.verf_key(), self.role, &operator_verification_key.verf_key_id(), ) { tracing::error!( - "Backup material did not match expected metadata ({mismatch:?}) for operator: {}", + "Backup material did not match expected metadata ({e:?}) for operator: {}", operator_verification_key.address() ); return Err(BackupError::CustodianRecoveryError); diff --git a/core/service/src/backup/operator.rs b/core/service/src/backup/operator.rs index b3e90a1ede..8dcd8e49bf 100644 --- a/core/service/src/backup/operator.rs +++ b/core/service/src/backup/operator.rs @@ -681,16 +681,16 @@ impl Operator { ); return Err(RecoverySkipReason::MpcContextIdMismatch); } - if let Err(mismatch) = backup_material.check_expected_metadata( + if let Err(e) = backup_material.check_expected_metadata( custodian_verf_key, output.custodian_role, &operator_id, ) { tracing::warn!( - "Metadata check ({mismatch:?}) failed for custodian role {}", + "Metadata check ({e:?}) failed for custodian role {}", output.custodian_role ); - return Err(mismatch); + return Err(e); } let actual_commitment = safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index a236c960c1..f2bbffdabf 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -188,8 +188,6 @@ where ephemeral_enc_key, ) .await?; - // `filter_custodian_data` already enforces `len() >= threshold + 1` - Ok((validated_rec, operator)) } } @@ -1198,8 +1196,7 @@ mod tests { } /// Build the recovering `Operator` from a `RecoveryValidationMaterial` for tests that call - /// `filter_custodian_data` directly. Mirrors what - /// `validate_custodian_backup_recovery_request` does in production. + /// `filter_custodian_data` directly. fn build_operator_from_recovery_material( recovery_material: &RecoveryValidationMaterial, verf_key: &PublicSigKey, diff --git a/core/service/src/vault/keychain/mod.rs b/core/service/src/vault/keychain/mod.rs index 0b38b5fe25..e7eb09fd86 100644 --- a/core/service/src/vault/keychain/mod.rs +++ b/core/service/src/vault/keychain/mod.rs @@ -270,7 +270,6 @@ pub mod tests { } } - #[test] fn test_verify_root_key_measurements() { let good_pcr_values = ReleasePCRValues { From f48a0bb925a0effbd46082d341d15bf2aca15c78 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 12 May 2026 18:34:23 +0200 Subject: [PATCH 12/29] chore: revert change --- .claude/settings.json | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 38460779c4..3782b15dd0 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,8 +1,8 @@ { + "sandbox": { + "enabled": true + }, "permissions": { - "allow": [ - "Read(//Users/jot2re/Code/tech-spec/architecture/completed_intercomponent_flows/**)" - ], "deny": [ "Read(**/target/**)", "Read(./.env)", @@ -50,12 +50,6 @@ "Read(~/Library/Application Support/**/exodus*/**)", "Read(~/Library/Application Support/**/phantom*/**)", "Read(~/Library/Application Support/**/solflare*/**)" - ], - "additionalDirectories": [ - "/Users/jot2re/Code/tech-spec/architecture/completed_intercomponent_flows" ] - }, - "sandbox": { - "enabled": true } -} +} \ No newline at end of file From fe68d6e8dc4630e72fe459df46d24b534ca901ec Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Wed, 13 May 2026 10:14:54 +0200 Subject: [PATCH 13/29] test: added tests --- core/service/src/backup/operator.rs | 60 +++++++++++++++++++++ core/service/src/backup/tests.rs | 82 ++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 2 deletions(-) diff --git a/core/service/src/backup/operator.rs b/core/service/src/backup/operator.rs index 8dcd8e49bf..7d066729c2 100644 --- a/core/service/src/backup/operator.rs +++ b/core/service/src/backup/operator.rs @@ -1248,6 +1248,66 @@ mod tests { ); } + #[test] + fn check_expected_metadata_sunshine_and_mismatches() { + let mut rng = AesRng::seed_from_u64(101); + let (custodian_verf_key, _) = gen_sig_keys(&mut rng); + let (operator_verf_key, _) = gen_sig_keys(&mut rng); + let (other_custodian_verf_key, _) = gen_sig_keys(&mut rng); + let (other_operator_verf_key, _) = gen_sig_keys(&mut rng); + + let custodian_role = Role::indexed_from_one(2); + let backup_id = derive_request_id("check_expected_metadata").unwrap(); + + let material = BackupMaterial { + backup_id, + mpc_context_id: *DEFAULT_MPC_CONTEXT, + custodian_pk: custodian_verf_key.clone(), + custodian_role, + operator_pk: operator_verf_key.clone(), + shares: Vec::new(), + }; + + // Sunshine: every metadata field matches the expected routing parameters. + material + .check_expected_metadata( + &custodian_verf_key, + custodian_role, + &operator_verf_key.verf_key_id(), + ) + .expect("metadata that matches the routing parameters should validate"); + + // Custodian role mismatch. + assert_eq!( + material.check_expected_metadata( + &custodian_verf_key, + Role::indexed_from_one(3), + &operator_verf_key.verf_key_id(), + ), + Err(RecoverySkipReason::CustodianRoleMismatchInPayload), + ); + + // Custodian verification key mismatch. + assert_eq!( + material.check_expected_metadata( + &other_custodian_verf_key, + custodian_role, + &operator_verf_key.verf_key_id(), + ), + Err(RecoverySkipReason::CustodianKeyMismatchInPayload), + ); + + // Operator (recipient) id mismatch — defends against a share routed to the wrong operator. + assert_eq!( + material.check_expected_metadata( + &custodian_verf_key, + custodian_role, + &other_operator_verf_key.verf_key_id(), + ), + Err(RecoverySkipReason::OperatorMismatchInPayload), + ); + } + #[test] fn operator_new_fails_with_not_enough() { let mut rng = AesRng::seed_from_u64(8); diff --git a/core/service/src/backup/tests.rs b/core/service/src/backup/tests.rs index 5f24a9c022..1ecd7f356d 100644 --- a/core/service/src/backup/tests.rs +++ b/core/service/src/backup/tests.rs @@ -1,4 +1,8 @@ -use super::{custodian, error::BackupError, operator::Operator}; +use super::{ + custodian, + error::{BackupError, RecoverySkipReason}, + operator::Operator, +}; use crate::{ backup::{ custodian::{ @@ -19,7 +23,7 @@ use crate::{ }; use aes_prng::AesRng; use itertools::Itertools; -use kms_grpc::{RequestId, kms::v1::CustodianContext}; +use kms_grpc::{ContextId, RequestId, kms::v1::CustodianContext}; use proptest::prelude::*; use rand::{SeedableRng, rngs::OsRng}; use std::collections::BTreeMap; @@ -518,6 +522,80 @@ fn full_flow_malicious_operator() { } } +/// Negative test for the `mpc_context_id` binding added to `BackupMaterial`. +#[test] +fn verify_and_recover_rejects_mpc_context_mismatch() { + let mut rng = AesRng::seed_from_u64(1338); + let backup_id = derive_request_id(std::stringify!( + verify_and_recover_rejects_mpc_context_mismatch + )) + .unwrap(); + let operator_count = 4usize; + let custodian_count = 3usize; + let custodian_threshold = 1usize; + + let (setup_msgs, mnemonics) = generate_setup_messages(&mut rng, custodian_count); + let (mut operators, payload_for_custodians) = operator_handle_init( + &mut rng, + &setup_msgs, + &backup_id, + operator_count, + custodian_threshold, + custodian_count, + ); + + // An MPC context ID different from the default one + let wrong_mpc_context = ContextId::from_bytes([0x99u8; crate::consts::ID_LENGTH]); + for op_state in operators.values_mut() { + let original_payload = op_state.1.payload.clone(); + let (_, sk) = gen_sig_keys(&mut rng); + // Change the validation material to contain the wrong context id + op_state.1 = RecoveryValidationMaterial::new( + original_payload.cts, + original_payload.commitments, + original_payload.custodian_context, + &sk, + wrong_mpc_context, + ) + .unwrap(); + } + + let backups = custodian_recover( + &mut rng, + &mnemonics, + &payload_for_custodians, + custodian_threshold, + ); + assert_eq!(backups.len(), operator_count); + + for (op_addr, (operator, validation_material, dec_key, enc_key)) in &operators { + let reencs: Vec<_> = backups + .get(op_addr) + .expect("custodian recovery outputs for each operator") + .values() + .cloned() + .collect(); + let err = operator + .verify_and_recover(&reencs, validation_material, dec_key, enc_key) + .expect_err("expected RecoveryThresholdNotMet due to mpc_context_id mismatch"); + match err { + BackupError::RecoveryThresholdNotMet { + received, skipped, .. + } => { + assert_eq!(received, 0, "no share should validate"); + assert!( + !skipped.is_empty() + && skipped + .iter() + .all(|r| *r == RecoverySkipReason::MpcContextIdMismatch), + "expected every skip reason to be MpcContextIdMismatch, got: {skipped:?}" + ); + } + other => panic!("unexpected BackupError variant: {other}"), + } + } +} + fn generate_setup_messages( rng: &mut AesRng, custodian_count: usize, From 4611416432ab0ca3e20e54daf89adfbe1945c6eb Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Wed, 13 May 2026 10:20:04 +0200 Subject: [PATCH 14/29] chore: self review changes --- .claude/settings.json | 106 +++++++++--------- .../tests/backward_compatibility_kms.rs | 4 - 2 files changed, 53 insertions(+), 57 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 3782b15dd0..bc0d1e93c6 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,55 +1,55 @@ { - "sandbox": { - "enabled": true - }, - "permissions": { - "deny": [ - "Read(**/target/**)", - "Read(./.env)", - "Read(./.env.*)", - "Read(**/*.pem)", - "Read(**/*.key)", - "Read(**/*.cert)", - "Read(**/*.p12)", - "Read(**/*.pfx)", - "Read(**/secrets.*)", - "Read(**/credentials.*)", - "Read(./secrets/**)", - "Read(./keys/**)", - "Read(./.github/secrets/**)", - "Edit(**/.ssh/**)", - "Read(**/.ssh/**)", - "Bash(rm -rf *)", - "Bash(rm -fr *)", - "Bash(sudo *)", - "Bash(mkfs *)", - "Bash(dd *)", - "Bash(curl *|bash*)", - "Bash(wget *|bash*)", - "Bash(git push --force*)", - "Bash(git push *--force*)", - "Bash(git reset --hard*)", - "Edit(~/.bashrc)", - "Edit(~/.zshrc)", - "Edit(~/.ssh/**)", - "Read(~/.ssh/**)", - "Read(~/.gnupg/**)", - "Read(~/.aws/**)", - "Read(~/.azure/**)", - "Read(~/.config/gh/**)", - "Read(~/.git-credentials)", - "Read(~/.docker/config.json)", - "Read(~/.kube/**)", - "Read(~/.npmrc)", - "Read(~/.npm/**)", - "Read(~/.pypirc)", - "Read(~/.gem/credentials)", - "Read(~/Library/Keychains/**)", - "Read(~/Library/Application Support/**/metamask*/**)", - "Read(~/Library/Application Support/**/electrum*/**)", - "Read(~/Library/Application Support/**/exodus*/**)", - "Read(~/Library/Application Support/**/phantom*/**)", - "Read(~/Library/Application Support/**/solflare*/**)" - ] - } + "sandbox": { + "enabled": true + }, + "permissions": { + "deny": [ + "Read(**/target/**)", + "Read(./.env)", + "Read(./.env.*)", + "Read(**/*.pem)", + "Read(**/*.key)", + "Read(**/*.cert)", + "Read(**/*.p12)", + "Read(**/*.pfx)", + "Read(**/secrets.*)", + "Read(**/credentials.*)", + "Read(./secrets/**)", + "Read(./keys/**)", + "Read(./.github/secrets/**)", + "Edit(**/.ssh/**)", + "Read(**/.ssh/**)", + "Bash(rm -rf *)", + "Bash(rm -fr *)", + "Bash(sudo *)", + "Bash(mkfs *)", + "Bash(dd *)", + "Bash(curl *|bash*)", + "Bash(wget *|bash*)", + "Bash(git push --force*)", + "Bash(git push *--force*)", + "Bash(git reset --hard*)", + "Edit(~/.bashrc)", + "Edit(~/.zshrc)", + "Edit(~/.ssh/**)", + "Read(~/.ssh/**)", + "Read(~/.gnupg/**)", + "Read(~/.aws/**)", + "Read(~/.azure/**)", + "Read(~/.config/gh/**)", + "Read(~/.git-credentials)", + "Read(~/.docker/config.json)", + "Read(~/.kube/**)", + "Read(~/.npmrc)", + "Read(~/.npm/**)", + "Read(~/.pypirc)", + "Read(~/.gem/credentials)", + "Read(~/Library/Keychains/**)", + "Read(~/Library/Application Support/**/metamask*/**)", + "Read(~/Library/Application Support/**/electrum*/**)", + "Read(~/Library/Application Support/**/exodus*/**)", + "Read(~/Library/Application Support/**/phantom*/**)", + "Read(~/Library/Application Support/**/solflare*/**)" + ] + } } \ No newline at end of file diff --git a/core/service/tests/backward_compatibility_kms.rs b/core/service/tests/backward_compatibility_kms.rs index 941b5de067..e4813bff3f 100644 --- a/core/service/tests/backward_compatibility_kms.rs +++ b/core/service/tests/backward_compatibility_kms.rs @@ -895,10 +895,8 @@ fn test_internal_recovery_request( let original_versionized: InternalRecoveryRequest = load_and_unversionize(dir, test, format)?; let mut rng = AesRng::seed_from_u64(test.state); - let backup_id: RequestId = RequestId::new_random(&mut rng); let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); let (_dec_key, enc_key) = encryption.keygen().unwrap(); - let (verf_key, _) = gen_sig_keys(&mut rng); let mut cts = BTreeMap::new(); for role_j in 1..=test.amount { let cur_role = Role::indexed_from_one(role_j as usize); @@ -911,8 +909,6 @@ fn test_internal_recovery_request( }; cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); } - let _ = backup_id; - let _ = verf_key; let new_versionized = InternalRecoveryRequest::new(enc_key, cts).unwrap(); if original_versionized != new_versionized { From 30fe6a4f367f23241e8b78a36ebb818279f38d1c Mon Sep 17 00:00:00 2001 From: Tore <33345641+jot2re@users.noreply.github.com> Date: Fri, 15 May 2026 10:52:16 +0200 Subject: [PATCH 15/29] Update docs/guides/backup.md Co-authored-by: Daniel Demmler --- docs/guides/backup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/backup.md b/docs/guides/backup.md index 2f0c08c17e..57b02dd362 100644 --- a/docs/guides/backup.md +++ b/docs/guides/backup.md @@ -80,7 +80,7 @@ The alternative backup mode — wrapping the same key under an AWS KMS CMK — i | Party | What it does | |---|---| -| **Custodian `B_j`** (`j = 1..n`) | Human-held, offline party. Owns a long-term signing key `sk^{S_j}` and a post-quantum encryption key `sk^{E_j}`, both deterministically derived from a BIP39 seed phrase. Stores nothing online beyond its public-key half published in the `CustodianSetupMessage`. Re-signcrypts its share of the backup key on request. | +| **Custodian `B_j`** (`j = 1..n`) | Human-held, offline party. Owns a long-term signing key `sk^{S_j}` and a post-quantum encryption key `sk^{E_j}`, both deterministically derived from a BIP39 seed phrase. Stores nothing online beyond its public-key published in the `CustodianSetupMessage`. Re-signcrypts its share of the backup key on request. | | **Operator `P_i`** (KMS node) | Online KMS server. Holds a long-term signing key `sk^{P_i}`, a TFHE FHE secret key, and other private material that needs backing up. Receives `NewCustodianContext` and, later, `CustodianRecoveryInit` / `CustodianBackupRecovery` gRPC calls from the core-client. | | **core-client** | The CLI that drives every gRPC call into the KMS for custodian-based backup. It bundles the operator-bound RPCs (`NewCustodianContext`, `CustodianRecoveryInit`, `CustodianBackupRecovery`, `RestoreFromBackup`) and shuttles the resulting `RecoveryRequest` / `InternalCustodianRecoveryOutput` files between the operator and the custodians out-of-band. Documented in [docs/guides/core_client.md](core_client.md). | | **Recovering operator `P_i'`** | A fresh operator process replacing `P_i` after the latter's private storage was lost. Reads only the public storage and the backup vault; coordinates with custodians (via the core-client) to rebuild private state. | From 28145a17bc92b6a33f2986e0eb4b40e48a3ee8ae Mon Sep 17 00:00:00 2001 From: Tore <33345641+jot2re@users.noreply.github.com> Date: Fri, 15 May 2026 10:52:29 +0200 Subject: [PATCH 16/29] Update docs/guides/backup.md Co-authored-by: Daniel Demmler --- docs/guides/backup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/backup.md b/docs/guides/backup.md index 57b02dd362..2158f1b3ef 100644 --- a/docs/guides/backup.md +++ b/docs/guides/backup.md @@ -81,7 +81,7 @@ The alternative backup mode — wrapping the same key under an AWS KMS CMK — i | Party | What it does | |---|---| | **Custodian `B_j`** (`j = 1..n`) | Human-held, offline party. Owns a long-term signing key `sk^{S_j}` and a post-quantum encryption key `sk^{E_j}`, both deterministically derived from a BIP39 seed phrase. Stores nothing online beyond its public-key published in the `CustodianSetupMessage`. Re-signcrypts its share of the backup key on request. | -| **Operator `P_i`** (KMS node) | Online KMS server. Holds a long-term signing key `sk^{P_i}`, a TFHE FHE secret key, and other private material that needs backing up. Receives `NewCustodianContext` and, later, `CustodianRecoveryInit` / `CustodianBackupRecovery` gRPC calls from the core-client. | +| **Operator `P_i`** (KMS node) | Online KMS server. Holds a long-term signing key `sk^{P_i}`, a TFHE secret key, and other private material that needs backing up. Receives `NewCustodianContext` and, later, `CustodianRecoveryInit` / `CustodianBackupRecovery` gRPC calls from the core-client. | | **core-client** | The CLI that drives every gRPC call into the KMS for custodian-based backup. It bundles the operator-bound RPCs (`NewCustodianContext`, `CustodianRecoveryInit`, `CustodianBackupRecovery`, `RestoreFromBackup`) and shuttles the resulting `RecoveryRequest` / `InternalCustodianRecoveryOutput` files between the operator and the custodians out-of-band. Documented in [docs/guides/core_client.md](core_client.md). | | **Recovering operator `P_i'`** | A fresh operator process replacing `P_i` after the latter's private storage was lost. Reads only the public storage and the backup vault; coordinates with custodians (via the core-client) to rebuild private state. | From 34b6082bd3deca0adc6d8a8df9d1c9782af81990 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 15 May 2026 11:07:40 +0200 Subject: [PATCH 17/29] docs: updated docs according to review --- docs/guides/backup.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/guides/backup.md b/docs/guides/backup.md index 2158f1b3ef..0a48dddc1b 100644 --- a/docs/guides/backup.md +++ b/docs/guides/backup.md @@ -83,7 +83,7 @@ The alternative backup mode — wrapping the same key under an AWS KMS CMK — i | **Custodian `B_j`** (`j = 1..n`) | Human-held, offline party. Owns a long-term signing key `sk^{S_j}` and a post-quantum encryption key `sk^{E_j}`, both deterministically derived from a BIP39 seed phrase. Stores nothing online beyond its public-key published in the `CustodianSetupMessage`. Re-signcrypts its share of the backup key on request. | | **Operator `P_i`** (KMS node) | Online KMS server. Holds a long-term signing key `sk^{P_i}`, a TFHE secret key, and other private material that needs backing up. Receives `NewCustodianContext` and, later, `CustodianRecoveryInit` / `CustodianBackupRecovery` gRPC calls from the core-client. | | **core-client** | The CLI that drives every gRPC call into the KMS for custodian-based backup. It bundles the operator-bound RPCs (`NewCustodianContext`, `CustodianRecoveryInit`, `CustodianBackupRecovery`, `RestoreFromBackup`) and shuttles the resulting `RecoveryRequest` / `InternalCustodianRecoveryOutput` files between the operator and the custodians out-of-band. Documented in [docs/guides/core_client.md](core_client.md). | -| **Recovering operator `P_i'`** | A fresh operator process replacing `P_i` after the latter's private storage was lost. Reads only the public storage and the backup vault; coordinates with custodians (via the core-client) to rebuild private state. | +| **Recovering operator `P_i'`** | A fresh operator recovers the content of the private storage of a previous operator. Reads only the public storage and the backup vault; coordinates with custodians (via the core-client) to rebuild private state. | ### Data components @@ -157,13 +157,13 @@ sequenceDiagram ### Phase 1 — Custodian setup (offline, one-time per custodian) -Corresponds to [`kms-custodian generate`](#custodian-setup). A future custodian boots the air-gapped machine and runs the command. Keys are deterministically derived from system entropy mixed with a user-supplied `--randomness` string; the matching BIP39 seed phrase is printed to stdout **once** and must be copied onto paper. +Corresponds to [`kms-custodian generate`](#custodian-setup). A future custodian boots the air-gapped machine and runs the command. Keys are derived from system entropy mixed with a user-supplied `--randomness` string; the matching BIP39 seed phrase is printed to stdout **once** and must be copied onto paper. The seed phrase is the only durable secret the custodian holds. `sk^{E_j}` and `sk^{S_j}` are re-derived from it whenever the custodian participates in a recovery. ### Phase 2 — Custodian context creation (online, one-time per context) -The core-client gathers `n` `CustodianSetupMessage`s (from each custodian's `--path` file), picks a corruption threshold `t < n/2`, and issues a `NewCustodianContext` gRPC call to every operator in the KMS cluster. Each operator, independently: generates a per-context backup keypair `(sk^{B}, pk^{B})`, Shamir-shares `sk^{B}` into `n` shares, builds and signcrypts one `BackupMaterial` per custodian role, computes a commitment over each `BackupMaterial`, packages everything into a signed `RecoveryValidationMaterial` (written to public storage at `request_id = custodian_context_id`), and encrypts the resulting `InternalCustodianContext` into a `BackupCiphertext` for the backup vault. After secret-sharing, the operator drops `sk^{B}` and installs `pk^{B}` in its `SecretSharing` keychain. +The core-client gathers `n` `CustodianSetupMessage`s (from each custodian's `--path` file), picks a corruption threshold `t < n/2`, and issues a `NewCustodianContext` gRPC call to every operator in the KMS cluster. Each operator, independently: generates a per-context backup keypair `(sk^{B}, pk^{B})`, Shamir-shares `sk^{B}` into `n` shares, builds and signcrypts one `BackupMaterial` per custodian role, computes a commitment over each `BackupMaterial`, packages everything into a signed `RecoveryValidationMaterial` (written to the operator's own public storage at `request_id = custodian_context_id`), and encrypts the resulting `InternalCustodianContext` into a `BackupCiphertext` for the backup vault. After secret-sharing, the operator drops `sk^{B}` and installs `pk^{B}` in its `SecretSharing` keychain. Notes: - The Shamir threshold encoded inside `RecoveryValidationMaterial.custodian_context.threshold` is the **recovery** threshold (`t + 1` shares needed). `Operator::new_for_sharing` enforces `t < n/2`. @@ -188,10 +188,10 @@ The recovering operator has the same long-term signing key as the original (reco Corresponds to [`kms-custodian decrypt`](#recovery-decryption-of-backup). The core-client (or operator's human operator) distributes the `RecoveryRequest` and the recovering operator's verification key out-of-band to each custodian's air-gapped machine. The custodian boots, types in the seed phrase, and runs the command: re-derives `(sk^{E_j}, sk^{S_j})` from the seed phrase, unsigncrypts its share of `BackupMaterial` from `cts[j]`, sanity-checks the metadata inside and then re-signcrypts the same `BackupMaterial` to the operator's ephemeral key `pk^{e_i}`, and writes the resulting `InternalCustodianRecoveryOutput` to `--output-path`. -The custodian's only cryptographic obligation is "decrypt your share and re-signcrypt it for the operator's ephemeral key". The custodian can't (and isn't asked to) judge whether this request is legitimate — see the warning at the top of the [Recovery](#recovery-decryption-of-backup) section. +The custodian's only cryptographic obligation is "decrypt your share and re-signcrypt it for the operator's ephemeral key". The custodian can't (and isn't asked to) judge whether this request is legitimate — see the warning at the top of the [Recovery](#recovery-decryption-of-backup) section. Furthermore, observe that the way the custodian receives the operator's recovery request and material, is through an out-of-band channel (e.g. Slack and/or Signal). ### Phase 6 — Recovery finalization (operator reconstructs) -The core-client collects `t + 1` (or more) custodian output files and sends them, in a single `CustodianRecoveryRequest`, to every operator in the cluster. The recovering operator re-reads `RecoveryValidationMaterial` from public storage and validates each `CustodianRecoveryOutput`, and once at least `t + 1` shares pass — Shamir-reconstructs `sk^{B}` and installs it in the `SecretSharing` keychain. A subsequent `RestoreFromBackup` call then iterates every `BackupCiphertext` in the backup vault, decrypts each with `sk^{B}`, and writes the plaintext into the now-empty private storage. +For each operator that needs recovery, their core-client collects `t + 1` (or more) custodian output files and sends them, in a single `CustodianRecoveryRequest`, and sends this to the KMS core. The recovering operator re-reads `RecoveryValidationMaterial` from public storage and validates each `CustodianRecoveryOutput`, and once at least `t + 1` shares pass — Shamir-reconstructs `sk^{B}` and installs it in the `SecretSharing` keychain. A subsequent `RestoreFromBackup` call then iterates every `BackupCiphertext` in the backup vault, decrypts each with `sk^{B}`, and writes the plaintext into the now-empty private storage. After Phase 6 the recovering operator's private storage is repopulated and the node resumes normal service. The operator-side commands that drive Phases 4 and 6 are documented in [docs/guides/core_client.md](core_client.md). From 47ea30616cbb29cce14a3c04f7a325ce1a07f39d Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 15 May 2026 11:52:45 +0200 Subject: [PATCH 18/29] chore: handled copilot's review --- core/service/src/backup/error.rs | 1 + core/service/src/backup/operator.rs | 2 +- core/service/src/engine/backup_operator.rs | 3 ++- core/service/src/vault/keychain/mod.rs | 6 +++--- core/service/tests/backward_compatibility_kms.rs | 2 -- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/service/src/backup/error.rs b/core/service/src/backup/error.rs index 3f8b37fc08..b9b2c46ac1 100644 --- a/core/service/src/backup/error.rs +++ b/core/service/src/backup/error.rs @@ -33,6 +33,7 @@ pub enum RecoverySkipReason { CustodianRoleMismatchInPayload, CustodianKeyMismatchInPayload, OperatorMismatchInPayload, + MissingCommitment, CommitmentMismatch, } diff --git a/core/service/src/backup/operator.rs b/core/service/src/backup/operator.rs index 7d066729c2..670bacecea 100644 --- a/core/service/src/backup/operator.rs +++ b/core/service/src/backup/operator.rs @@ -706,7 +706,7 @@ impl Operator { "No stored commitment for custodian role {}", output.custodian_role ); - RecoverySkipReason::MissingVerificationKey + RecoverySkipReason::MissingCommitment })?; if actual_commitment.as_slice() != expected_commitment { tracing::warn!( diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index f2bbffdabf..77dca2d27c 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -527,7 +527,8 @@ async fn filter_custodian_data( ephemeral_dec_key: &UnifiedPrivateEncKey, ephemeral_enc_key: &UnifiedPublicEncKey, ) -> anyhow::Result> { - let outputs_len = custodian_recovery_outputs.len(); + // Use the number of custodian nodes that was part of the context, not the amount we have received from + let outputs_len = recovery_material.custodian_context().custodian_nodes.len(); let mut parsed_custodian_rec: HashMap = HashMap::new(); let mut skip_reasons: Vec = Vec::new(); diff --git a/core/service/src/vault/keychain/mod.rs b/core/service/src/vault/keychain/mod.rs index e7eb09fd86..fb2dd6e3e2 100644 --- a/core/service/src/vault/keychain/mod.rs +++ b/core/service/src/vault/keychain/mod.rs @@ -186,7 +186,7 @@ pub fn encrypt_under_data_key( .map_err(|_| anyhow_error_and_log("Invalid data key length: must be 256 bits"))?; if iv.len() != 12 { return Err(anyhow_error_and_log( - "Invalid IV length: must be exactly 96 bits for AES GCM", + "Invalid IV length: must be exactly 96 bits for AES-256-GCM-SIV", )); } #[allow(deprecated)] @@ -209,12 +209,12 @@ pub fn decrypt_under_data_key( .map_err(|_| anyhow_error_and_log("Invalid data key length: must be 256 bits"))?; if iv.len() != 12 { return Err(anyhow_error_and_log( - "Invalid IV length: must be exactly 96 bits for AES GCM", + "Invalid IV length: must be exactly 96 bits for AES-256-GCM-SIV", )); } if auth_tag.len() != 16 { return Err(anyhow_error_and_log( - "Invalid auth tag length: must be exactly 128 bits for AES GCM", + "Invalid auth tag length: must be exactly 128 bits for AES-256-GCM-SIV", )); } #[allow(deprecated)] diff --git a/core/service/tests/backward_compatibility_kms.rs b/core/service/tests/backward_compatibility_kms.rs index e4813bff3f..27a2ff1492 100644 --- a/core/service/tests/backward_compatibility_kms.rs +++ b/core/service/tests/backward_compatibility_kms.rs @@ -979,7 +979,6 @@ fn test_internal_custodian_recovery_output( let original_versionized: InternalCustodianRecoveryOutput = load_and_unversionize(dir, test, format)?; let mut rng = AesRng::seed_from_u64(test.state); - let (operator_verification_key, _sk) = gen_sig_keys(&mut rng); let mut buf = [0u8; 100]; rng.fill_bytes(&mut buf); let signcryption = UnifiedSigncryption { @@ -988,7 +987,6 @@ fn test_internal_custodian_recovery_output( signing_type: SigningSchemeType::Ecdsa256k1, }; - let _ = operator_verification_key; let new_versionized = InternalCustodianRecoveryOutput { signcryption, custodian_role: Role::indexed_from_one(2), From c4ffc72894c73d032169d8981f70c5eaca1e51f1 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 15 May 2026 12:15:28 +0200 Subject: [PATCH 19/29] chore: setup new backwards compatibility tests --- Cargo.lock | 38 +- Cargo.toml | 5 +- Makefile | 6 +- ai-docs/COMMANDS.md | 1 + backward-compatibility/ADDING_NEW_VERSIONS.md | 5 +- backward-compatibility/Cargo.lock | 154 -- backward-compatibility/Cargo.toml | 2 +- .../data/0_11_0/kms/kms_fhe_key_handles.bcode | 2 +- .../data/0_11_1/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_0/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_10/kms/key_gen_metadata.bcode | 2 +- .../0_13_10/kms/kms_fhe_key_handles.bcode | 2 +- .../0_13_20/kms/signcryption_payload.bincode | Bin 29 -> 0 bytes .../data/0_13_20/kms/typed_plaintext.bincode | Bin 17 -> 0 bytes backward-compatibility/data/kms-grpc.ron | 6 +- backward-compatibility/data/kms.ron | 54 +- backward-compatibility/data/threshold-fhe.ron | 16 +- .../generate-v0.11.0/Cargo.lock | 2 +- .../generate-v0.11.1/Cargo.lock | 2 +- .../generate-v0.13.0/Cargo.lock | 2 +- .../generate-v0.13.10/Cargo.lock | 2 +- .../generate-v0.13.20/Cargo.lock | 1429 ++++++++++------- .../generate-v0.13.20/src/data_0_13.rs | 267 +-- docs/developer/backward_compatibility.md | 4 + 26 files changed, 926 insertions(+), 1083 deletions(-) delete mode 100644 backward-compatibility/Cargo.lock delete mode 100644 backward-compatibility/data/0_13_20/kms/signcryption_payload.bincode delete mode 100644 backward-compatibility/data/0_13_20/kms/typed_plaintext.bincode diff --git a/Cargo.lock b/Cargo.lock index 12aa83646d..5e948fd64e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1763,7 +1763,7 @@ dependencies = [ [[package]] name = "backward-compatibility" -version = "0.13.20" +version = "0.14.0" dependencies = [ "bincode 1.3.3", "ron 0.10.1", @@ -3030,7 +3030,7 @@ dependencies = [ [[package]] name = "error-utils" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "tracing", @@ -3065,7 +3065,7 @@ dependencies = [ [[package]] name = "experiments" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "anyhow", @@ -3386,7 +3386,7 @@ checksum = "312d2295c7302019c395cfb90dacd00a82a2eabd700429bba9c7a3f38dbbe11b" [[package]] name = "generate-test-material" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "clap", @@ -4217,7 +4217,7 @@ dependencies = [ [[package]] name = "kms" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes", "aes-gcm", @@ -4313,7 +4313,7 @@ dependencies = [ [[package]] name = "kms-core-client" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "alloy-primitives", @@ -4359,7 +4359,7 @@ dependencies = [ [[package]] name = "kms-grpc" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -4387,7 +4387,7 @@ dependencies = [ [[package]] name = "kms-health-check" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "clap", @@ -4912,7 +4912,7 @@ dependencies = [ [[package]] name = "observability" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "axum", @@ -7358,7 +7358,7 @@ dependencies = [ [[package]] name = "test-utils" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "bc2wrap", @@ -7369,11 +7369,11 @@ dependencies = [ [[package]] name = "test-utils-cc" -version = "0.13.20-0" +version = "0.14.0-0" [[package]] name = "test-utils-service" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "quote", "syn 2.0.114", @@ -7544,7 +7544,7 @@ dependencies = [ [[package]] name = "thread-handles" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "error-utils", @@ -7574,7 +7574,7 @@ dependencies = [ [[package]] name = "threshold-algebra" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "anyhow", @@ -7601,7 +7601,7 @@ dependencies = [ [[package]] name = "threshold-bgv" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes-prng", "anyhow", @@ -7629,7 +7629,7 @@ dependencies = [ [[package]] name = "threshold-execution" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "aes", "aes-prng", @@ -7677,7 +7677,7 @@ dependencies = [ [[package]] name = "threshold-hashing" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "bc2wrap", @@ -7687,7 +7687,7 @@ dependencies = [ [[package]] name = "threshold-networking" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "async-trait", @@ -7724,7 +7724,7 @@ dependencies = [ [[package]] name = "threshold-types" -version = "0.13.20-0" +version = "0.14.0-0" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 00e4acae49..79da97c000 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ # backward-compatibility/generate-v0.13.0 - Data generation for v0.13.0 with old KMS version dependencies # backward-compatibility/generate-v0.13.10 - Data generation for v0.13.10 with old KMS version dependencies # backward-compatibility/generate-v0.13.20 - Data generation for v0.13.20 with old KMS version dependencies +# backward-compatibility/generate-v0.14.0 - Data generation for v0.14.0 with old KMS version dependencies # # The generate crates need to import old KMS versions (e.g., v0.11.0, v0.11.1) which conflict with the # current workspace dependencies, creating name conflicts as described in: @@ -37,14 +38,14 @@ members = [ # Note: It's not possible to only generate the lock file using specific features as the resolver # builds the graph as if all features are enabled: # https://doc.rust-lang.org/cargo/reference/resolver.html#features -exclude = ["backward-compatibility", "backward-compatibility/generate-v0.11.0", "backward-compatibility/generate-v0.11.1", "backward-compatibility/generate-v0.13.0", "backward-compatibility/generate-v0.13.10", "backward-compatibility/generate-v0.13.20"] +exclude = ["backward-compatibility", "backward-compatibility/generate-v0.11.0", "backward-compatibility/generate-v0.11.1", "backward-compatibility/generate-v0.13.0", "backward-compatibility/generate-v0.13.10", "backward-compatibility/generate-v0.13.20", "backward-compatibility/generate-v0.14.0"] [workspace.package] authors = ["Zama"] publish = true edition = "2024" license = "BSD-3-Clause-Clear" -version = "0.13.20-0" +version = "0.14.0-0" repository = "https://github.com/zama-ai/kms" description = "Key Management System for the Zama Protocol." diff --git a/Makefile b/Makefile index 7993c565a4..44f92eadf7 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ clean-backward-compatibility-data: rm -rf backward-compatibility/data/0_13_0 rm -rf backward-compatibility/data/0_13_10 rm -rf backward-compatibility/data/0_13_20 + rm -rf backward-compatibility/data/0_14_0 generate-backward-compatibility-v0.11.0: cd backward-compatibility/generate-v0.11.0 && cargo run --release @@ -58,7 +59,10 @@ generate-backward-compatibility-v0.13.10: generate-backward-compatibility-v0.13.20: cd backward-compatibility/generate-v0.13.20 && cargo run --release -generate-backward-compatibility-all: clean-backward-compatibility-data generate-backward-compatibility-v0.11.0 generate-backward-compatibility-v0.11.1 generate-backward-compatibility-v0.13.0 generate-backward-compatibility-v0.13.10 generate-backward-compatibility-v0.13.20 +generate-backward-compatibility-v0.14.0: + cd backward-compatibility/generate-v0.14.0 && cargo run --release + +generate-backward-compatibility-all: clean-backward-compatibility-data generate-backward-compatibility-v0.11.0 generate-backward-compatibility-v0.11.1 generate-backward-compatibility-v0.13.0 generate-backward-compatibility-v0.13.10 generate-backward-compatibility-v0.13.20 generate-backward-compatibility-v0.14.0 @echo "Generated backward compatibility data for all versions" # Test material generation targets diff --git a/ai-docs/COMMANDS.md b/ai-docs/COMMANDS.md index 2206faa4e2..9a66e4d9ed 100644 --- a/ai-docs/COMMANDS.md +++ b/ai-docs/COMMANDS.md @@ -94,6 +94,7 @@ make generate-backward-compatibility-v0.11.1 make generate-backward-compatibility-v0.13.0 make generate-backward-compatibility-v0.13.10 make generate-backward-compatibility-v0.13.20 +make generate-backward-compatibility-v0.14.0 ``` Clean all generated BC data: diff --git a/backward-compatibility/ADDING_NEW_VERSIONS.md b/backward-compatibility/ADDING_NEW_VERSIONS.md index 36e14ed1e6..6452f8c9df 100644 --- a/backward-compatibility/ADDING_NEW_VERSIONS.md +++ b/backward-compatibility/ADDING_NEW_VERSIONS.md @@ -117,7 +117,10 @@ make test-backward-compatibility-local |----------------|--------------|--------------|------------------|--------| | `generate-v0.11.0` | `backward-compatibility-generate-v0-11-0` | v0.11.0 | serde 1.0.219, alloy 1.1.2, tfhe 1.3.2 | ✅ Active | | `generate-v0.11.1` | `backward-compatibility-generate-v0-11-1` | v0.11.1 | serde 1.0.226, alloy 1.3.1, tfhe 1.3.3 | ✅ Active | -| `generate-v0.12.0` | `backward-compatibility-generate-v0-12-0` | v0.12.0+ | TBD | 🚧 Future (when needed) | +| `generate-v0.13.0` | `backward-compatibility-generate-v0-13-0` | v0.13.0 | — | ✅ Active | +| `generate-v0.13.10` | `backward-compatibility-generate-v0-13-10` | v0.13.10 | — | ✅ Active | +| `generate-v0.13.20` | `backward-compatibility-generate-v0-13-20` | v0.13.20 | — | ✅ Active | +| `generate-v0.14.0` | `backward-compatibility-generate-v0-14-0` | v0.14.0 | tfhe-versionable 0.7.0, tfhe 1.6.1, alloy 1.4.1, serde 1.0.228 | ✅ Active | **Note**: v0.11.0 and v0.11.1 require separate generators due to incompatible alloy and tfhe versions. diff --git a/backward-compatibility/Cargo.lock b/backward-compatibility/Cargo.lock deleted file mode 100644 index 072fdd863d..0000000000 --- a/backward-compatibility/Cargo.lock +++ /dev/null @@ -1,154 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "backward-compatibility" -version = "0.13.1" -dependencies = [ - "bincode", - "ron", - "semver", - "serde", - "strum", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" -dependencies = [ - "serde_core", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "proc-macro2" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ron" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" -dependencies = [ - "base64", - "bitflags", - "serde", - "serde_derive", - "unicode-ident", -] - -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" - -[[patch.unused]] -name = "rcgen" -version = "0.14.0" -source = "git+https://github.com/mkmks/rcgen.git?branch=k256#d3239ab9a4e632c75bea0b09da1389d44b411e13" diff --git a/backward-compatibility/Cargo.toml b/backward-compatibility/Cargo.toml index f3cef7fa42..d8ecb45971 100644 --- a/backward-compatibility/Cargo.toml +++ b/backward-compatibility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "backward-compatibility" -version = "0.13.20" +version = "0.14.0" publish = false authors = ["Zama"] edition = "2021" diff --git a/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode index c1ba2d0934..5d41e2eafc 100644 --- a/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8db11b1373de6d643aea6dc9117eb41ddb3f24671290b58e7a38368ec6d202bf +oid sha256:e8d74ed16cbbb34018f8cc03b234818f7d2fd0b6255b47fb09db0d9af8845343 size 11428 diff --git a/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode index 2859334bb1..e30c1ff159 100644 --- a/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78dcf61f269be47abe065d2f0b249ad076adf613284f90b9f1163f075133b6fb +oid sha256:5ab1ea78f19d679845dbea16d39dc5d02311736a66efc7dc86284eddfec94180 size 11199 diff --git a/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index d761bf957d..3e915b7200 100644 --- a/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 +oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 size 468 diff --git a/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode index 501fb29423..01f8f8a85c 100644 --- a/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56a6f47fe169b963fdc1b33bc3a74245d66832b22f62261679bee85a0dc5013e +oid sha256:2190f3e6afd35d3c1da4fe9e058d90c4b6e25febe03de181343db0170465d2b0 size 11208 diff --git a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index d761bf957d..3e915b7200 100644 --- a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 +oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 size 468 diff --git a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode index c08bd87f6f..aff78c52fe 100644 --- a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62f8b355d53250052ce835b22a04b5911c2b196013e00fb446baf87927584134 +oid sha256:d11d0c555157f483446fd64c71c694019f4ffff92c8604ace43b8a828d952a43 size 245 diff --git a/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode index 01f8f8a85c..501fb29423 100644 --- a/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2190f3e6afd35d3c1da4fe9e058d90c4b6e25febe03de181343db0170465d2b0 +oid sha256:56a6f47fe169b963fdc1b33bc3a74245d66832b22f62261679bee85a0dc5013e size 11208 diff --git a/backward-compatibility/data/0_13_20/kms/signcryption_payload.bincode b/backward-compatibility/data/0_13_20/kms/signcryption_payload.bincode deleted file mode 100644 index 3d998f4d15a2f7c391836229df41f62d71d7732a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 ZcmZQ&fB;4&W)@ZsAe#j$aBuCt_W%l816cq7 diff --git a/backward-compatibility/data/0_13_20/kms/typed_plaintext.bincode b/backward-compatibility/data/0_13_20/kms/typed_plaintext.bincode deleted file mode 100644 index 50b7c47b79702e4dc18ab4ba027ddb3cfe249b4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 ScmZQ&fB;4&W)@ZsAR7Px alloy_sol_types_1_4_1::Eip712Domain { alloy_sol_types_1_4_1::eip712_domain!( name: "Authorization token", @@ -1022,119 +973,6 @@ impl KmsV0_13_20 { TestMetadataKMS::SoftwareVersion(SOFTWARE_VERSION_TEST) } - fn gen_recovery_material(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(RECOVERY_MATERIAL_TEST.state); - let backup_id: RequestId = RequestId::new_random(&mut rng); - let (operator_pk, operator_sk) = gen_sig_keys(&mut rng); - let mut commitments = BTreeMap::new(); - let mut cts = BTreeMap::new(); - for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { - let cus_role = Role::indexed_from_one(role_j); - let (custodian_pk, _) = gen_sig_keys(&mut rng); - let backup_material = BackupMaterial { - backup_id, - custodian_pk, - custodian_role: cus_role, - operator_pk: operator_pk.clone(), - shares: Vec::new(), - }; - let msg_digest = - safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) - .unwrap(); - commitments.insert(cus_role, msg_digest); - let mut payload = [0_u8; 32]; - rng.fill_bytes(&mut payload); - let cts_out = InnerOperatorBackupOutput { - signcryption: UnifiedSigncryption { - payload: payload.to_vec(), - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }, - }; - cts.insert(cus_role, cts_out); - } - - // Dummy payload; but needs to be a properly serialized payload - // This must be generated after the commitment stuff, since the test will regenerate the commitment stuff, - // but read the custodian context from disk - let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (_dec_key, enc_key) = encryption.keygen().unwrap(); - let (cus_pk, _) = gen_sig_keys(&mut rng); - let payload = CustodianSetupMessagePayload { - header: "header".to_string(), - random_value: [4_u8; 32], - timestamp: 0, - public_enc_key: enc_key.clone(), - verification_key: cus_pk.clone(), - }; - let mut payload_serial = Vec::new(); - safe_serialize(&payload, &mut payload_serial, SAFE_SER_SIZE_LIMIT).unwrap(); - let mut custodian_nodes = Vec::new(); - for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { - let setup_msg = CustodianSetupMessage { - custodian_role: role_j as u64, - name: format!("Custodian-{role_j}"), - payload: payload_serial.clone(), - }; - custodian_nodes.push(setup_msg); - } - let custodian_context = CustodianContext { - custodian_nodes, - custodian_context_id: Some(backup_id.into()), - threshold: 1, - }; - let internal_custodian_context = - InternalCustodianContext::new(custodian_context, enc_key).unwrap(); - store_versioned_auxiliary!( - &internal_custodian_context, - dir, - &RECOVERY_MATERIAL_TEST.test_filename, - &RECOVERY_MATERIAL_TEST.internal_cus_context_filename, - ); - let recovery_material = RecoveryValidationMaterial::new( - cts, - commitments, - internal_custodian_context, - &operator_sk, - kms_grpc_0_13_20::ContextId::from_bytes(RECOVERY_MATERIAL_TEST.mpc_context_id), - ) - .unwrap(); - store_versioned_test!( - &recovery_material, - dir, - &RECOVERY_MATERIAL_TEST.test_filename - ); - TestMetadataKMS::RecoveryValidationMaterial(RECOVERY_MATERIAL_TEST) - } - - fn gen_internal_recovery_request(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(INTERNAL_RECOVERY_REQUEST_TEST.state); - let backup_id: RequestId = RequestId::new_random(&mut rng); - let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (_dec_key, enc_key) = encryption.keygen().unwrap(); - let (verf_key, _) = gen_sig_keys(&mut rng); - let mut cts = BTreeMap::new(); - for role_j in 1..=INTERNAL_RECOVERY_REQUEST_TEST.amount { - let cur_role = Role::indexed_from_one(role_j as usize); - let mut payload = [0_u8; 32]; - rng.fill_bytes(&mut payload); - let signcryption = UnifiedSigncryption { - payload: payload.to_vec(), - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }; - cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); - } - let recovery_material = - InternalRecoveryRequest::new(enc_key, cts, backup_id, verf_key).unwrap(); - store_versioned_test!( - &recovery_material, - dir, - &INTERNAL_RECOVERY_REQUEST_TEST.test_filename - ); - TestMetadataKMS::InternalRecoveryRequest(INTERNAL_RECOVERY_REQUEST_TEST) - } - fn gen_internal_cus_context_handles(dir: &PathBuf) -> TestMetadataKMS { let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_CONTEXT_TEST.state); let context_id: RequestId = RequestId::new_random(&mut rng); @@ -1377,81 +1215,6 @@ impl KmsV0_13_20 { ); TestMetadataKMS::InternalCustodianSetupMessage(INTERNAL_CUS_SETUP_MSG_TEST) } - - fn gen_internal_cus_rec_out(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_REC_OUT_TEST.state); - let (operator_verification_key, _) = gen_sig_keys(&mut rng); - let mut buf = [0u8; 100]; - rng.fill_bytes(&mut buf); - let signcryption = UnifiedSigncryption { - payload: buf.to_vec(), - pke_type: PkeSchemeType::MlKem512, - signing_type: SigningSchemeType::Ecdsa256k1, - }; - let icro = InternalCustodianRecoveryOutput { - signcryption, - custodian_role: Role::indexed_from_one(2), - operator_verification_key, - mpc_context_id: kms_grpc_0_13_20::RequestId::from_bytes( - INTERNAL_CUS_REC_OUT_TEST.mpc_context_id, - ), - }; - store_versioned_test!(&icro, dir, &INTERNAL_CUS_REC_OUT_TEST.test_filename); - TestMetadataKMS::InternalCustodianRecoveryOutput(INTERNAL_CUS_REC_OUT_TEST) - } - - fn gen_operator_backup_output(dir: &PathBuf) -> TestMetadataKMS { - let mut rng = AesRng::seed_from_u64(OPERATOR_BACKUP_OUTPUT_TEST.seed); - - let custodians: Vec<_> = (1..=OPERATOR_BACKUP_OUTPUT_TEST.custodian_count) - .map(|i| { - let (_verification_key, signing_key) = gen_sig_keys(&mut rng); - let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); - let (private_key, public_key) = encryption.keygen().unwrap(); - Custodian::new( - Role::indexed_from_one(i), - signing_key, - public_key, - private_key, - ) - .unwrap() - }) - .collect(); - let custodian_messages: Vec<_> = custodians - .iter() - .enumerate() - .map(|(i, c)| { - c.generate_setup_message(&mut rng, format!("Custodian-{i}")) - .unwrap() - }) - .collect(); - - let operator = { - let (_verification_key, signing_key) = gen_sig_keys(&mut rng); - Operator::new_for_sharing( - custodian_messages, - signing_key, - OPERATOR_BACKUP_OUTPUT_TEST.custodian_threshold, - custodians.len(), - ) - .unwrap() - }; - let operator_backup_output = &operator - .secret_share_and_signcrypt( - &mut rng, - &OPERATOR_BACKUP_OUTPUT_TEST.plaintext, - RequestId::from_bytes(OPERATOR_BACKUP_OUTPUT_TEST.backup_id), - ) - .unwrap() - .ct_shares[&Role::indexed_from_one(1)]; - - store_versioned_test!( - operator_backup_output, - dir, - &OPERATOR_BACKUP_OUTPUT_TEST.test_filename - ); - TestMetadataKMS::OperatorBackupOutput(OPERATOR_BACKUP_OUTPUT_TEST) - } } struct DistributedDecryptionV0_13_20; @@ -1686,14 +1449,10 @@ impl KMSCoreVersion for V0_13_20 { KmsV0_13_20::gen_context_info(&dir), KmsV0_13_20::gen_node_info(&dir), KmsV0_13_20::gen_software_version(&dir), - KmsV0_13_20::gen_recovery_material(&dir), - KmsV0_13_20::gen_internal_recovery_request(&dir), KmsV0_13_20::gen_internal_cus_context_handles(&dir), KmsV0_13_20::gen_internal_cus_setup_msg(&dir), KmsV0_13_20::gen_kms_fhe_key_handles(&dir), KmsV0_13_20::gen_threshold_fhe_keys(&dir), - KmsV0_13_20::gen_internal_cus_rec_out(&dir), - KmsV0_13_20::gen_operator_backup_output(&dir), ] } diff --git a/docs/developer/backward_compatibility.md b/docs/developer/backward_compatibility.md index 0de00ecf41..cc0516913e 100644 --- a/docs/developer/backward_compatibility.md +++ b/docs/developer/backward_compatibility.md @@ -36,6 +36,7 @@ However, this does not allow changes to be made to the test metadata scheme itse - `backward-compatibility/generate-v0.13.0` - For KMS v0.13.0 - `backward-compatibility/generate-v0.13.10` - For KMS v0.13.10 - `backward-compatibility/generate-v0.13.20` - For KMS v0.13.20 +- `backward-compatibility/generate-v0.14.0` - For KMS v0.14.0 Each generator uses the exact dependencies from its target KMS version. @@ -63,6 +64,9 @@ make generate-backward-compatibility-v0.13.10 # Generate only v0.13.20 data make generate-backward-compatibility-v0.13.20 +# Generate only v0.14.0 data +make generate-backward-compatibility-v0.14.0 + ``` WARNING: Generating for specific versions removes previously generated data from the `.ron` files, effectively ignoring other versions in the tests! Thus, changes based on generating a specific version should NEVER be committed to the repo. From 45c9197cef36c3b01782f37fe59f18b336c770da Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 15 May 2026 12:21:58 +0200 Subject: [PATCH 20/29] chore: added missing files --- .../data/0_14_0/kms-grpc/priv_data_type.bcode | 3 + .../data/0_14_0/kms-grpc/pub_data_type.bcode | 3 + .../signed_pub_data_handle_internal.bcode | 3 + .../data/0_14_0/kms/app_key_blob.bcode | 3 + .../unified_ciphertext_handle.bcode | 3 + .../legacy_crs_gen_metadata.bcode | 3 + .../unified_enc_key_handle.bcode | 3 + .../legacy_key_gen_metadata.bcode | 3 + .../client_key_handle.bcode | 3 + .../decompression_key.bcode | 3 + .../public_key_handle.bcode | 3 + .../server_key_handle.bcode | 3 + .../sig_key_handle.bcode | 3 + .../prss_setup_128.bcode | 3 + .../prss_setup_64.bcode | 3 + .../internal_cus_context_handle.bcode | 3 + .../decompression_key.bcode | 3 + .../auxiliary_threshold_fhe_keys/info.bcode | 3 + .../integer_server_key.bcode | 3 + .../private_key_set.bcode | 3 + .../sns_key.bcode | 3 + .../hybrid_kem_ct_handle.bcode | 3 + .../data/0_14_0/kms/backup_ciphertext.bcode | 3 + .../data/0_14_0/kms/context_info.bcode | 3 + .../data/0_14_0/kms/crs_gen_metadata.bcode | 3 + .../crs_gen_metadata_with_extra_data.bcode | 3 + .../data/0_14_0/kms/designcryption_key.bcode | 3 + .../data/0_14_0/kms/hybrid_kem_ct.bcode | 3 + .../0_14_0/kms/internal_cus_context.bcode | 3 + .../internal_custodian_recovery_output.bcode | 3 + .../internal_custodian_setup_message.bcode | 3 + .../kms/internal_recovery_request.bcode | 3 + .../data/0_14_0/kms/key_gen_metadata.bcode | 3 + .../key_gen_metadata_with_extra_data.bcode | 3 + .../data/0_14_0/kms/kms_fhe_key_handles.bcode | 3 + .../data/0_14_0/kms/node_info.bcode | 3 + .../0_14_0/kms/operator_backup_output.bcode | 3 + .../data/0_14_0/kms/private_sig_key.bcode | 3 + .../data/0_14_0/kms/prss_setup_combined.bcode | 3 + .../data/0_14_0/kms/public_sig_key.bcode | 3 + .../data/0_14_0/kms/recovery_material.bcode | 3 + .../data/0_14_0/kms/signcryption_key.bcode | 3 + .../0_14_0/kms/signcryption_payload.bincode | Bin 0 -> 29 bytes .../data/0_14_0/kms/software_version.bcode | 3 + .../data/0_14_0/kms/threshold_fhe_keys.bcode | 3 + .../data/0_14_0/kms/typed_plaintext.bincode | Bin 0 -> 17 bytes .../data/0_14_0/kms/unified_ciphertext.bcode | 3 + .../0_14_0/kms/unified_signcryption.bcode | 3 + .../legacy_prss_set_128.bcode | 3 + .../legacy_prss_set_64.bcode | 3 + .../data/0_14_0/threshold-fhe/prf_key.bcode | 3 + .../0_14_0/threshold-fhe/prss_set_128.bcode | 3 + .../0_14_0/threshold-fhe/prss_set_64.bcode | 3 + .../threshold-fhe/prss_setup_rpoly_128.bcode | 3 + .../threshold-fhe/prss_setup_rpoly_64.bcode | 3 + .../threshold-fhe/release_pcr_values.bcode | 3 + .../data/0_14_0/threshold-fhe/share_128.bcode | 3 + .../data/0_14_0/threshold-fhe/share_64.bcode | 3 + .../generate-v0.14.0/Cargo.lock | 8090 +++++++++++++++++ .../generate-v0.14.0/Cargo.toml | 63 + .../generate-v0.14.0/src/data_0_14.rs | 1724 ++++ .../generate-v0.14.0/src/generate.rs | 174 + .../generate-v0.14.0/src/lib.rs | 7 + .../generate-v0.14.0/src/main.rs | 64 + 64 files changed, 10290 insertions(+) create mode 100644 backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode create mode 100644 backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode create mode 100644 backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/app_key_blob.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/context_info.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/designcryption_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/node_info.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/private_sig_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/public_sig_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/recovery_material.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/signcryption_key.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/signcryption_payload.bincode create mode 100644 backward-compatibility/data/0_14_0/kms/software_version.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/typed_plaintext.bincode create mode 100644 backward-compatibility/data/0_14_0/kms/unified_ciphertext.bcode create mode 100644 backward-compatibility/data/0_14_0/kms/unified_signcryption.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/auxiliary_prss_set_128/legacy_prss_set_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/auxiliary_prss_set_64/legacy_prss_set_64.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prf_key.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_set_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_set_64.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_setup_rpoly_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/prss_setup_rpoly_64.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/release_pcr_values.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/share_128.bcode create mode 100644 backward-compatibility/data/0_14_0/threshold-fhe/share_64.bcode create mode 100644 backward-compatibility/generate-v0.14.0/Cargo.lock create mode 100644 backward-compatibility/generate-v0.14.0/Cargo.toml create mode 100644 backward-compatibility/generate-v0.14.0/src/data_0_14.rs create mode 100644 backward-compatibility/generate-v0.14.0/src/generate.rs create mode 100644 backward-compatibility/generate-v0.14.0/src/lib.rs create mode 100644 backward-compatibility/generate-v0.14.0/src/main.rs diff --git a/backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode b/backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode new file mode 100644 index 0000000000..b2e9f64332 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:971e061b731ff27510e9b78027b92e5b3a22b1516c53019c14ae9e74d5d7a7c4 +size 8 diff --git a/backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode b/backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode new file mode 100644 index 0000000000..b62995ce4f --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20aef0af2bb62267e2f5c157abdc51d1ce6506e42478ae204f1fab5494907df1 +size 8 diff --git a/backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode b/backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode new file mode 100644 index 0000000000..439029a680 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d76555cde90e2b212e529fa05e5c428ea200ba637dd53f485817595423299ce0 +size 44 diff --git a/backward-compatibility/data/0_14_0/kms/app_key_blob.bcode b/backward-compatibility/data/0_14_0/kms/app_key_blob.bcode new file mode 100644 index 0000000000..fdb0e7f1cf --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/app_key_blob.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7411ad8b97e02c52a39389c59d226ae7023b645602abdfca152896fc94d7cb5b +size 88 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode new file mode 100644 index 0000000000..a4ac29fe9d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7baef0c10c9546e08c07e7e10b9ac5c8ef5438193a993aa1e50b0f1b4d0ce730 +size 116 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode new file mode 100644 index 0000000000..5b6ad3bd60 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e8d2cda4e6186846e6c81b978d8646d99805908fcada7fb1e4d69bc2ea4a50a +size 222 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode new file mode 100644 index 0000000000..80a9fd8578 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e9ad274fccc8176b8ca752b0775d7e5204ef04977f3110e03a967d5625463e8 +size 816 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode new file mode 100644 index 0000000000..3e915b7200 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +size 468 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode new file mode 100644 index 0000000000..992e387d7d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f47cd611b9ba112924afc627df465f83d64ff34266bb74b84f551350c84661d3 +size 11059 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode new file mode 100644 index 0000000000..32c4a8b118 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d +size 1 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode new file mode 100644 index 0000000000..daef644183 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a6baad25bd21e9d66fa8f0dbade36139963ed943bddf0d17301baa7bfed7b17 +size 4296 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode new file mode 100644 index 0000000000..65aa9880cb --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b705dbae3823bd53f081785cc16fd5c8882972cf1c4aef072805855e150153e7 +size 2612531 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode new file mode 100644 index 0000000000..46be201c75 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a70af30268a5a16d1e92329ff520c86ed3de334ce84c223cf0dc722f8b747d +size 44 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode new file mode 100644 index 0000000000..add992a846 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca00fd2c83f16696111d5b1664a7c01e5280e0797e34a7914f4ff4d3d9d83371 +size 571344 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode new file mode 100644 index 0000000000..54e23ac21b --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f636676db5e96976a8f40d0997fc194dd60f95597ef95a40e1f0105537054447 +size 363344 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode new file mode 100644 index 0000000000..3720877b3a --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83edb0410c16b0df4692bc269140625188b9168cec607eaabafbec2e3d27f068 +size 5714 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode new file mode 100644 index 0000000000..32c4a8b118 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d +size 1 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode new file mode 100644 index 0000000000..a2b71017a4 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af5570f5a1810b7af78caf4bc70a660f0df51e42baf91d4de5b2328de0e83dfc +size 8 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode new file mode 100644 index 0000000000..0b14506e98 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24d4c40af16d1e88b3f487377e58650f1d00ba83190aaf79951d1cf9649ffd33 +size 105044 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode new file mode 100644 index 0000000000..78f5a76f23 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37d2a7d8179d03b407285a89155ceacf1b93632cb85cdddd97438502e089106a +size 72788 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode new file mode 100644 index 0000000000..7d5dd827cc --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92fcc1622e46fb575229a76e189587b92af92ca6a1a40f25f4e0e36dbaa0d693 +size 327865 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode new file mode 100644 index 0000000000..c9022a3505 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c507182c9fc8e903f237672321ea88b12dae401bfdaa54edb64c1058d023e0b +size 104 diff --git a/backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode b/backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode new file mode 100644 index 0000000000..60f47859b4 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58839ef61ee16b3dc704c7a9f0e2198d8b63e5447ad56ce44ea30b84bac54afe +size 160 diff --git a/backward-compatibility/data/0_14_0/kms/context_info.bcode b/backward-compatibility/data/0_14_0/kms/context_info.bcode new file mode 100644 index 0000000000..c184704cde --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/context_info.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc09fa4d730965ed9a3e566b71eab8c3386ec34f75cd9a0faf7d38f2caa2b29d +size 773 diff --git a/backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode new file mode 100644 index 0000000000..8a31fb1c98 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b75ed84a1486d89c47d446d5987105037d5f12714a8298a77bc3d15f701178fa +size 162 diff --git a/backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode new file mode 100644 index 0000000000..e2dcfa0875 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b79dafcc51162efedd41d3cfe3d5d5ce906d0122b89b8cca65a5f43741361e19 +size 174 diff --git a/backward-compatibility/data/0_14_0/kms/designcryption_key.bcode b/backward-compatibility/data/0_14_0/kms/designcryption_key.bcode new file mode 100644 index 0000000000..ccb5d6080a --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/designcryption_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b10c5bf4b215b2204709f5c7ee3f567a7072b321b514f2364ebaf5d3f1ba15ac +size 2541 diff --git a/backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode b/backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode new file mode 100644 index 0000000000..900bba1ed7 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4144bc45b0e0793bbdd028b76c8c8cd7eb8e3929b46d5b9e34fea316b2b6cac +size 50 diff --git a/backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode b/backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode new file mode 100644 index 0000000000..bed5902f24 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:588e8e4a618b8f85e340f9fb7a8e070808789514645e115a4418bcc7594e5b9a +size 5684 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode new file mode 100644 index 0000000000..38cdf921d8 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5a79b59689143dadc62d606abd3fe5921a14fc7971d620dd246645d8368374f +size 221 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode new file mode 100644 index 0000000000..5211d9920d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a9ab09b84a90d3da3098160d0f4b12240daa900965bb71a3de9368130091187 +size 992 diff --git a/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode new file mode 100644 index 0000000000..d3e042756e --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:131b45495e950de30f57d751f78f662d939fb50fa91265d5aaca4365b92b9bef +size 1665 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode new file mode 100644 index 0000000000..5d440827de --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66e3bc33dbc047674bf0163868f3d73ad86962c6fb07c4bf1db7c704ea4722b0 +size 246 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode new file mode 100644 index 0000000000..0a44396d4c --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac0ded3ade3242ce472ecb8ff691834667b04d6c648f0535ff1028e627449ee2 +size 258 diff --git a/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode new file mode 100644 index 0000000000..397b91584f --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 +size 11318 diff --git a/backward-compatibility/data/0_14_0/kms/node_info.bcode b/backward-compatibility/data/0_14_0/kms/node_info.bcode new file mode 100644 index 0000000000..363f0a5f6d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/node_info.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b753468d6ebf5f11b5fea788187f88f6857df52a7b89539c59c549d57e54237a +size 259 diff --git a/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode b/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode new file mode 100644 index 0000000000..7c24373275 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9622e8a05c3c04d5f8d74a5a9f9460b6be883f061ef3e9e49252553f2e50b7b +size 1260 diff --git a/backward-compatibility/data/0_14_0/kms/private_sig_key.bcode b/backward-compatibility/data/0_14_0/kms/private_sig_key.bcode new file mode 100644 index 0000000000..46be201c75 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/private_sig_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a70af30268a5a16d1e92329ff520c86ed3de334ce84c223cf0dc722f8b747d +size 44 diff --git a/backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode b/backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode new file mode 100644 index 0000000000..9d49ac004f --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5aeb8e5ae63b5cb1c7b102c88afe14f1610b94de45262c89f288d62c2905c84d +size 934694 diff --git a/backward-compatibility/data/0_14_0/kms/public_sig_key.bcode b/backward-compatibility/data/0_14_0/kms/public_sig_key.bcode new file mode 100644 index 0000000000..803309c729 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/public_sig_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca62947f91974015736ebb245f3e3e74416f6d54c130a4c733f3a8cbde20f20a +size 45 diff --git a/backward-compatibility/data/0_14_0/kms/recovery_material.bcode b/backward-compatibility/data/0_14_0/kms/recovery_material.bcode new file mode 100644 index 0000000000..6365f46725 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/recovery_material.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c3a25b30266ea83f46f55e42aa155f7216e069f9cf79613c4a06163770c1b24 +size 6482 diff --git a/backward-compatibility/data/0_14_0/kms/signcryption_key.bcode b/backward-compatibility/data/0_14_0/kms/signcryption_key.bcode new file mode 100644 index 0000000000..1bc463d85d --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/signcryption_key.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef6450d800773acdaed4163734882a117889436fa0738b63609fa36bdc5fcf19 +size 892 diff --git a/backward-compatibility/data/0_14_0/kms/signcryption_payload.bincode b/backward-compatibility/data/0_14_0/kms/signcryption_payload.bincode new file mode 100644 index 0000000000000000000000000000000000000000..3d998f4d15a2f7c391836229df41f62d71d7732a GIT binary patch literal 29 ZcmZQ&fB;4&W)@ZsAe#j$aBuCt_W%l816cq7 literal 0 HcmV?d00001 diff --git a/backward-compatibility/data/0_14_0/kms/software_version.bcode b/backward-compatibility/data/0_14_0/kms/software_version.bcode new file mode 100644 index 0000000000..b13a02364a --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/software_version.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0caaec795d048118c15c3462ec76e1d0ca0244f24b2fe3cbe6880fe33b7702e2 +size 42 diff --git a/backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode b/backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode new file mode 100644 index 0000000000..d8da2e2905 --- /dev/null +++ b/backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5427a4bd62738a4d91b92e050526b3e2eee0e3a892835ab046607b37f2fac1cd +size 505726 diff --git a/backward-compatibility/data/0_14_0/kms/typed_plaintext.bincode b/backward-compatibility/data/0_14_0/kms/typed_plaintext.bincode new file mode 100644 index 0000000000000000000000000000000000000000..50b7c47b79702e4dc18ab4ba027ddb3cfe249b4e GIT binary patch literal 17 ScmZQ&fB;4&W)@ZsAR7Px { + store_versioned_test_05($msg, $dir, $test_filename) + }; +} + +// Macro to store a versioned auxiliary data associated to a test +macro_rules! store_versioned_auxiliary { + ($msg:expr, $dir:expr, $test_name:expr, $filename:expr $(,)? ) => { + store_versioned_auxiliary_05($msg, $dir, $test_name, $filename) + }; +} + +fn convert_dkg_params_sns(value: DKGParamsSnSTest) -> DKGParamsSnS { + DKGParamsSnS { + regular_params: convert_dkg_params_regular(value.regular_params), + sns_params: convert_sns_parameters(value.sns_params), + sns_compression_params: Some(convert_sns_compression_parameters( + value.sns_compression_parameters, + )), + } +} + +// Parameters `dedicated_compact_public_key_parameters` and `compression_decompression_parameters` +// are set to None because they are optional tfhe-rs types, which means their backward compatibility +// is already tested. +fn convert_dkg_params_regular(value: DKGParamsRegularTest) -> DKGParamsRegular { + DKGParamsRegular { + dkg_mode: DkgMode::Z128, + sec: value.sec, + ciphertext_parameters: convert_classic_pbs_parameters(value.ciphertext_parameters), + dedicated_compact_public_key_parameters: None, + compression_decompression_parameters: None, + secret_key_deviations: None, + cpk_re_randomization_ksk_params: None, + } +} + +fn convert_classic_pbs_parameters(value: ClassicPBSParametersTest) -> ClassicPBSParameters { + ClassicPBSParameters { + lwe_dimension: LweDimension(value.lwe_dimension), + glwe_dimension: GlweDimension(value.glwe_dimension), + polynomial_size: PolynomialSize(value.polynomial_size), + lwe_noise_distribution: DynamicDistribution::TUniform(TUniform::new( + value.lwe_noise_gaussian, + )), + glwe_noise_distribution: DynamicDistribution::TUniform(TUniform::new(0)), + pbs_base_log: DecompositionBaseLog(value.pbs_base_log), + pbs_level: DecompositionLevelCount(value.pbs_level), + ks_base_log: DecompositionBaseLog(value.ks_base_log), + ks_level: DecompositionLevelCount(value.ks_level), + message_modulus: MessageModulus(value.message_modulus), + carry_modulus: CarryModulus(value.carry_modulus), + max_noise_level: MaxNoiseLevel::new(value.max_noise_level), + log2_p_fail: value.log2_p_fail, + ciphertext_modulus: CiphertextModulus::new_native(), + encryption_key_choice: { + match &*value.encryption_key_choice { + "big" => EncryptionKeyChoice::Big, + "small" => EncryptionKeyChoice::Small, + _ => panic!("Invalid encryption key choice"), + } + }, + // no need to test this as it's from tfhe-rs + modulus_switch_noise_reduction_params: + tfhe_1_6_1::shortint::prelude::ModulusSwitchType::Standard, + } +} + +fn convert_sns_parameters(value: SwitchAndSquashParametersTest) -> NoiseSquashingParameters { + NoiseSquashingParameters::Classic(NoiseSquashingClassicParameters { + glwe_dimension: GlweDimension(value.glwe_dimension), + glwe_noise_distribution: DynamicDistribution::new_t_uniform(value.glwe_noise_distribution), + polynomial_size: PolynomialSize(value.polynomial_size), + decomp_base_log: DecompositionBaseLog(value.pbs_base_log), + decomp_level_count: DecompositionLevelCount(value.pbs_level), + ciphertext_modulus: CiphertextModulus::::new_native(), + modulus_switch_noise_reduction_params: + tfhe_1_6_1::shortint::prelude::ModulusSwitchType::Standard, + message_modulus: MessageModulus(value.message_modulus), + carry_modulus: CarryModulus(value.carry_modulus), + }) +} + +fn convert_sns_compression_parameters( + value: SwitchAndSquashCompressionParametersTest, +) -> NoiseSquashingCompressionParameters { + NoiseSquashingCompressionParameters { + packing_ks_level: DecompositionLevelCount(value.packing_ks_level), + packing_ks_base_log: DecompositionBaseLog(value.packing_ks_base_log), + packing_ks_polynomial_size: PolynomialSize(value.packing_ks_polynomial_size), + packing_ks_glwe_dimension: GlweDimension(value.packing_ks_glwe_dimension), + lwe_per_glwe: LweCiphertextCount(value.lwe_per_glwe), + packing_ks_key_noise_distribution: DynamicDistribution::new_t_uniform( + value.packing_ks_key_noise_distribution, + ), + ciphertext_modulus: CiphertextModulus::::new_native(), + message_modulus: MessageModulus(value.message_modulus), + carry_modulus: CarryModulus(value.carry_modulus), + } +} + +// Distributed Decryption test +const PRSS_SETUP_RPOLY_64_TEST: PRSSSetupTest = PRSSSetupTest { + test_filename: Cow::Borrowed("prss_setup_rpoly_64"), + amount: 10, + threshold: 3, + role_i: 1, + residue_poly_size: 64, +}; + +// Distributed Decryption test +const PRSS_SETUP_RPOLY_128_TEST: PRSSSetupTest = PRSSSetupTest { + test_filename: Cow::Borrowed("prss_setup_rpoly_128"), + amount: 10, + threshold: 3, + role_i: 1, + residue_poly_size: 128, +}; + +// Distributed Decryption test +const PRF_KEY_TEST: PrfKeyTest = PrfKeyTest { + test_filename: Cow::Borrowed("prf_key"), + seed: 100, +}; + +// Distributed Decryption test +const PRSS_SET_64_TEST: PrssSetTest = PrssSetTest { + test_filename: Cow::Borrowed("prss_set_64"), + legacy_filename: Cow::Borrowed("legacy_prss_set_64"), + amount_parties: 7, + amount_points: 7, + residue_poly_size: 64, + state: 11111, +}; + +// Distributed Decryption test +const PRSS_SET_128_TEST: PrssSetTest = PrssSetTest { + test_filename: Cow::Borrowed("prss_set_128"), + legacy_filename: Cow::Borrowed("legacy_prss_set_128"), + amount_parties: 13, + amount_points: 3, + residue_poly_size: 128, + state: 2222, +}; + +// Distributed Decryption test +const SHARE_64_TEST: ShareTest = ShareTest { + test_filename: Cow::Borrowed("share_64"), + value: 34653246, + owner: 1, + residue_poly_size: 64, +}; + +// Distributed Decryption test +const SHARE_128_TEST: ShareTest = ShareTest { + test_filename: Cow::Borrowed("share_128"), + value: 934565743256423875434534434, + owner: 1, + residue_poly_size: 128, +}; + +// Distributed Decryption test +const RELEASE_PCR_VALUES_TEST: ReleasePCRValuesTest = ReleasePCRValuesTest { + test_filename: Cow::Borrowed("release_pcr_values"), + state: 64, +}; + +// KMS test +const PRIVATE_SIG_KEY_TEST: PrivateSigKeyTest = PrivateSigKeyTest { + test_filename: Cow::Borrowed("private_sig_key"), + state: 100, +}; + +// KMS-grpc test +const SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST: SignedPubDataHandleInternalTest = + SignedPubDataHandleInternalTest { + test_filename: Cow::Borrowed("signed_pub_data_handle_internal"), + state: 100, + key_handle: Cow::Borrowed("key_handle"), + signature: [1, 2, 3], + external_signature: [4, 5, 6], + }; + +const PUB_DATA_TYPE: PubDataTypeTest = PubDataTypeTest { + test_filename: Cow::Borrowed("pub_data_type"), +}; + +const PRIV_DATA_TYPE: PrivDataTypeTest = PrivDataTypeTest { + test_filename: Cow::Borrowed("priv_data_type"), +}; + +// KMS test +const PUBLIC_SIG_KEY_TEST: PublicSigKeyTest = PublicSigKeyTest { + test_filename: Cow::Borrowed("public_sig_key"), + state: 100, +}; + +// KMS test +// TODO: include eip712_domain parameter +const KMS_FHE_KEY_HANDLES_TEST: KmsFheKeyHandlesTest = KmsFheKeyHandlesTest { + test_filename: Cow::Borrowed("kms_fhe_key_handles"), + client_key_filename: Cow::Borrowed("client_key_handle"), + public_key_filename: Cow::Borrowed("public_key_handle"), + server_key_filename: Cow::Borrowed("server_key_handle"), + sig_key_filename: Cow::Borrowed("sig_key_handle"), + decompression_key_filename: Cow::Borrowed("decompression_key"), + state: 100, + seed: 100, + element: Cow::Borrowed("element"), + dkg_parameters_sns: TEST_DKG_PARAMS_SNS, +}; + +// KMS test +const THRESHOLD_FHE_KEYS_TEST: ThresholdFheKeysTest = ThresholdFheKeysTest { + test_filename: Cow::Borrowed("threshold_fhe_keys"), + private_key_set_filename: Cow::Borrowed("private_key_set"), + integer_server_key_filename: Cow::Borrowed("integer_server_key"), + sns_key_filename: Cow::Borrowed("sns_key"), + info_filename: Cow::Borrowed("info"), + decompression_key_filename: Cow::Borrowed("decompression_key"), + state: 100, + amount: 2, + threshold: 1, + role_i: 1, + element: Cow::Borrowed("element"), + dkg_parameters_sns: TEST_DKG_PARAMS_SNS, +}; + +// KMS test +const KEY_GEN_METADATA_TEST: KeyGenMetadataTest = KeyGenMetadataTest { + test_filename: Cow::Borrowed("key_gen_metadata"), + legacy_filename: Cow::Borrowed("legacy_key_gen_metadata"), + state: 100, +}; + +// KMS test +const CRS_GEN_METADATA_TEST: CrsGenMetadataTest = CrsGenMetadataTest { + test_filename: Cow::Borrowed("crs_gen_metadata"), + legacy_filename: Cow::Borrowed("legacy_crs_gen_metadata"), + state: 100, + max_num_bits: 2048, +}; + +// KMS test — for key generation metadata with the 14.0 format (including extra data). +const KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST: KeyGenMetadataWithExtraDataTest = + KeyGenMetadataWithExtraDataTest { + test_filename: Cow::Borrowed("key_gen_metadata_with_extra_data"), + state: 101, + extra_data: Cow::Borrowed(&[0x02, 0xAA, 0xBB, 0xCC]), + }; + +const CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST: CrsGenMetadataWithExtraDataTest = + CrsGenMetadataWithExtraDataTest { + test_filename: Cow::Borrowed("crs_gen_metadata_with_extra_data"), + state: 101, + max_num_bits: 2048, + extra_data: Cow::Borrowed(&[0x02, 0xDD, 0xEE, 0xFF]), + }; + +// KMS test +const APP_KEY_BLOB_TEST: AppKeyBlobTest = AppKeyBlobTest { + test_filename: Cow::Borrowed("app_key_blob"), + root_key_id: Cow::Borrowed("root_key_id"), + data_key_blob: Cow::Borrowed("data_key_blob"), + ciphertext: Cow::Borrowed("ciphertext"), + iv: Cow::Borrowed("iv"), + auth_tag: Cow::Borrowed("auth_tag"), +}; + +// KMS test +fn typed_plaintext_test() -> TypedPlaintextTest { + TypedPlaintextTest { + test_filename: Cow::Borrowed("typed_plaintext"), + plaintext_bytes: vec![1, 2, 3, 4, 5], + fhe_type: 8, // FheTypes::Uint8 + } +} + +// KMS test +fn signcryption_payload_test() -> SigncryptionPayloadTest { + SigncryptionPayloadTest { + test_filename: Cow::Borrowed("signcryption_payload"), + plaintext_bytes: vec![1, 2, 3, 4, 5], + fhe_type: 8, // FheTypes::Uint8 + link: vec![222, 173, 190, 239], + } +} + +// KMS test +const SIGNCRYPTION_KEY_TEST: UnifiedSigncryptionKeyTest = UnifiedSigncryptionKeyTest { + test_filename: Cow::Borrowed("signcryption_key"), + state: 100, +}; + +// KMS test +const UNSIGNCRYPTION_KEY_TEST: UnifiedUnsigncryptionKeyTest = UnifiedUnsigncryptionKeyTest { + test_filename: Cow::Borrowed("designcryption_key"), + state: 200, +}; + +// KMS test +const UNIFIED_SIGNCRYPTION_TEST: UnifiedSigncryptionTest = UnifiedSigncryptionTest { + test_filename: Cow::Borrowed("unified_signcryption"), + state: 202, +}; + +// KMS test +const BACKUP_CIPHERTEXT_TEST: BackupCiphertextTest = BackupCiphertextTest { + test_filename: Cow::Borrowed("backup_ciphertext"), + unified_cipher_filename: Cow::Borrowed("unified_ciphertext_handle"), + state: 200, +}; + +// KMS test +const UNIFIED_CIPHER_TEST: UnifiedCipherTest = UnifiedCipherTest { + test_filename: Cow::Borrowed("unified_ciphertext"), + hybrid_kem_filename: Cow::Borrowed("hybrid_kem_ct_handle"), + state: 123, +}; + +// KMS test +const PRSS_SETUP_COMBINED_TEST: PrssSetupCombinedTest = PrssSetupCombinedTest { + test_filename: Cow::Borrowed("prss_setup_combined"), + prss_setup_64: Cow::Borrowed("prss_setup_64"), + prss_setup_128: Cow::Borrowed("prss_setup_128"), + role_i: 3, + amount: 13, + threshold: 4, +}; + +// KMS test +fn hybrid_kem_ct_test() -> HybridKemCtTest { + HybridKemCtTest { + test_filename: Cow::Borrowed("hybrid_kem_ct"), + nonce: [2u8; 12], + kem_ct: vec![1, 2, 3, 4, 5], + payload_ct: vec![6, 7, 8, 9, 10], + } +} + +// KMS test +fn context_info_test() -> ContextInfoTest { + ContextInfoTest { + test_filename: Cow::Borrowed("context_info"), + threshold: 3, + state: 234, + } +} + +// KMS test +fn node_info_test() -> NodeInfoTest { + NodeInfoTest { + test_filename: Cow::Borrowed("node_info"), + mpc_identity: Cow::Borrowed("node_mpc_identity"), + party_id: 4, + external_url: Cow::Borrowed("https://node4.example.com/mpc/something-something"), + public_storage_url: Cow::Borrowed("https://storage.example.com/node4"), + public_storage_prefix: Cow::Borrowed("PUB"), + ca_cert: Some(vec![1, 2, 3, 4, 6, 7, 8, 9]), + state: 500, + } +} + +// KMS test +const SOFTWARE_VERSION_TEST: SoftwareVersionTest = SoftwareVersionTest { + test_filename: Cow::Borrowed("software_version"), + major: 0, + minor: 13, + patch: 4, + tag: Cow::Borrowed("super fun version"), +}; + +// KMS test +const RECOVERY_MATERIAL_TEST: RecoveryValidationMaterialTest = RecoveryValidationMaterialTest { + test_filename: Cow::Borrowed("recovery_material"), + internal_cus_context_filename: Cow::Borrowed("internal_cus_context_handle"), + state: 300, + custodian_count: 5, + mpc_context_id: [7u8; 32], +}; + +// KMS test +const INTERNAL_RECOVERY_REQUEST_TEST: InternalRecoveryRequestTest = InternalRecoveryRequestTest { + test_filename: Cow::Borrowed("internal_recovery_request"), + amount: 10, + state: 300, +}; + +// KMS test +const INTERNAL_CUS_CONTEXT_TEST: InternalCustodianContextTest = InternalCustodianContextTest { + test_filename: Cow::Borrowed("internal_cus_context"), + internal_cus_setup_filename: Cow::Borrowed("internal_cus_setup_handle"), + unified_enc_key_filename: Cow::Borrowed("unified_enc_key_handle"), + state: 300, + custodian_count: 5, +}; + +// KMS test +const INTERNAL_CUS_SETUP_MSG_TEST: InternalCustodianSetupMessageTest = + InternalCustodianSetupMessageTest { + test_filename: Cow::Borrowed("internal_custodian_setup_message"), + state: 42, + }; + +// KMS test +const INTERNAL_CUS_REC_OUT_TEST: InternalCustodianRecoveryOutputTest = + InternalCustodianRecoveryOutputTest { + test_filename: Cow::Borrowed("internal_custodian_recovery_output"), + state: 43, + mpc_context_id: [7u8; 32], + }; + +// KMS test +const OPERATOR_BACKUP_OUTPUT_TEST: OperatorBackupOutputTest = OperatorBackupOutputTest { + test_filename: Cow::Borrowed("operator_backup_output"), + custodian_count: 3, + custodian_threshold: 1, + plaintext: [0u8; 32], + backup_id: [1u8; 32], + seed: 42, +}; + +fn dummy_domain() -> alloy_sol_types_1_4_1::Eip712Domain { + alloy_sol_types_1_4_1::eip712_domain!( + name: "Authorization token", + version: "1", + chain_id: 8006, + verifying_contract: alloy_primitives_1_4_1::address!("66f9664f97F2b50F62D13eA064982f936dE76657"), + ) +} + +pub struct V0_14_0; + +struct KmsV0_14_0; + +impl KmsV0_14_0 { + fn gen_private_sig_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(PRIVATE_SIG_KEY_TEST.state); + let (_, private_sig_key) = gen_sig_keys(&mut rng); + + store_versioned_test!(&private_sig_key, dir, &PRIVATE_SIG_KEY_TEST.test_filename); + + TestMetadataKMS::PrivateSigKey(PRIVATE_SIG_KEY_TEST) + } + + fn gen_public_sig_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(PUBLIC_SIG_KEY_TEST.state); + let (public_sig_key, _) = gen_sig_keys(&mut rng); + + store_versioned_test!(&public_sig_key, dir, &PUBLIC_SIG_KEY_TEST.test_filename); + + TestMetadataKMS::PublicSigKey(PUBLIC_SIG_KEY_TEST) + } + + fn gen_typed_plaintext(dir: &PathBuf) -> TestMetadataKMS { + let test = typed_plaintext_test(); + + let plaintext = TypedPlaintext { + bytes: test.plaintext_bytes.clone(), + fhe_type: test.fhe_type, + }; + + // TypedPlaintext doesn't use tfhe-versionable, serialize directly with bincode + let serialized = bc2wrap::serialize(&plaintext).unwrap(); + let filename = format!("{}.bincode", test.test_filename); + std::fs::write(dir.join(&filename), serialized).unwrap(); + + TestMetadataKMS::TypedPlaintext(test) + } + + fn gen_app_key_blob(dir: &PathBuf) -> TestMetadataKMS { + let app_key_blob = AppKeyBlob { + root_key_id: APP_KEY_BLOB_TEST.root_key_id.to_string(), + data_key_blob: APP_KEY_BLOB_TEST.data_key_blob.into_owned().into(), + ciphertext: APP_KEY_BLOB_TEST.ciphertext.into_owned().into(), + iv: APP_KEY_BLOB_TEST.iv.into_owned().into(), + auth_tag: APP_KEY_BLOB_TEST.auth_tag.into_owned().into(), + }; + + store_versioned_test!(&app_key_blob, dir, &APP_KEY_BLOB_TEST.test_filename); + + TestMetadataKMS::AppKeyBlob(APP_KEY_BLOB_TEST) + } + + fn gen_key_gen_metadata(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(KEY_GEN_METADATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + // We need to serialize something that is versioned, so let us just use signing keys for the test + let (pretend_server_key, pretend_public_key) = gen_sig_keys(&mut rng); + let preprocessing_id: RequestId = RequestId::new_random(&mut rng); + let key_id: RequestId = RequestId::new_random(&mut rng); + + let mut key_digest_map: HashMap> = HashMap::new(); + let mut legacy: HashMap = HashMap::new(); + let server_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_server_key).unwrap(); + let pub_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_public_key).unwrap(); + let sol_type = KeygenVerificationQ126::new_standard( + &preprocessing_id, + &key_id, + server_key_digest.clone(), + pub_key_digest.clone(), + ); + key_digest_map.insert(PubDataType::ServerKey, server_key_digest); + key_digest_map.insert(PubDataType::PublicKey, pub_key_digest); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + + legacy.insert( + PubDataType::ServerKey, + SignedPubDataHandleInternal { + key_handle: key_id.to_string(), + signature: vec![1_u8; 65], + external_signature: external_signature.clone(), + }, + ); + legacy.insert( + PubDataType::PublicKey, + SignedPubDataHandleInternal { + key_handle: key_id.to_string(), + signature: vec![2_u8; 65], + external_signature: external_signature.clone(), + }, + ); + + let current = KeyGenMetadataInner { + key_id, + preprocessing_id, + key_digest_map, + external_signature, + extra_data: None, + }; + store_versioned_auxiliary!( + &legacy, + dir, + &KEY_GEN_METADATA_TEST.test_filename, + &KEY_GEN_METADATA_TEST.legacy_filename, + ); + store_versioned_test!(¤t, dir, &KEY_GEN_METADATA_TEST.test_filename); + + TestMetadataKMS::KeyGenMetadata(KEY_GEN_METADATA_TEST) + } + + fn gen_crs_metadata(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(CRS_GEN_METADATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + let crs_id: RequestId = RequestId::new_random(&mut rng); + let digest = [12u8; 32].to_vec(); + let max_num_bits = CRS_GEN_METADATA_TEST.max_num_bits; + let sol_type = CrsgenVerificationQ126::new(&crs_id, max_num_bits as usize, digest.clone()); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + let current_crs_meta_data = CrsGenMetadata::new( + crs_id, + digest, + max_num_bits, + external_signature.clone(), + vec![], // Empty extra data to signal legacy + ); + + let legacy_crs_meta_data = SignedPubDataHandleInternal::new( + crs_id.to_string(), + [3u8; 65].to_vec(), + external_signature.clone(), + ); + + store_versioned_auxiliary!( + &legacy_crs_meta_data, + dir, + &CRS_GEN_METADATA_TEST.test_filename, + &CRS_GEN_METADATA_TEST.legacy_filename, + ); + store_versioned_test!( + ¤t_crs_meta_data, + dir, + &CRS_GEN_METADATA_TEST.test_filename + ); + + TestMetadataKMS::CrsGenMetadata(CRS_GEN_METADATA_TEST) + } + + /// Twin of `gen_key_gen_metadata` for version 14.0 (with extra_data). + fn gen_key_gen_metadata_with_extra_data(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + let (pretend_server_key, pretend_public_key) = gen_sig_keys(&mut rng); + let preprocessing_id: RequestId = RequestId::new_random(&mut rng); + let key_id: RequestId = RequestId::new_random(&mut rng); + + let extra_data = KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST.extra_data.to_vec(); + let mut key_digest_map: HashMap> = HashMap::new(); + let server_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_server_key).unwrap(); + let pub_key_digest = + safe_serialize_hash_element_versioned(b"TESTTEST", &pretend_public_key).unwrap(); + let sol_type = KeygenVerification::new_uncompressed( + &preprocessing_id, + &key_id, + server_key_digest.clone(), + pub_key_digest.clone(), + extra_data.clone(), + ); + key_digest_map.insert(PubDataType::ServerKey, server_key_digest); + key_digest_map.insert(PubDataType::PublicKey, pub_key_digest); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + + let current = KeyGenMetadataInner { + key_id, + preprocessing_id, + key_digest_map, + external_signature, + extra_data: Some(extra_data), + }; + store_versioned_test!( + ¤t, + dir, + &KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST.test_filename, + ); + + TestMetadataKMS::KeyGenMetadataWithExtraData(KEY_GEN_METADATA_WITH_EXTRA_DATA_TEST) + } + + /// Twin of `gen_crs_metadata` for version 14.0 (with extra_data). + fn gen_crs_metadata_with_extra_data(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.state); + let (_verf_key, sig_key) = gen_sig_keys(&mut rng); + let crs_id: RequestId = RequestId::new_random(&mut rng); + let digest = [12u8; 32].to_vec(); + let max_num_bits = CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.max_num_bits; + let extra_data = CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.extra_data.to_vec(); + let sol_type = CrsgenVerification::new( + &crs_id, + max_num_bits as usize, + digest.clone(), + extra_data.clone(), + ); + let external_signature = + compute_eip712_signature(&sig_key, &sol_type, &dummy_domain()).unwrap(); + let current_crs_meta_data = CrsGenMetadata::new( + crs_id, + digest, + max_num_bits, + external_signature.clone(), + extra_data, + ); + + store_versioned_test!( + ¤t_crs_meta_data, + dir, + &CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST.test_filename + ); + + TestMetadataKMS::CrsGenMetadataWithExtraData(CRS_GEN_METADATA_WITH_EXTRA_DATA_TEST) + } + + #[allow(clippy::ptr_arg)] + fn gen_signcryption_payload(dir: &PathBuf) -> TestMetadataKMS { + let test = signcryption_payload_test(); + + let payload = SigncryptionPayload { + plaintext: TypedPlaintext { + bytes: test.plaintext_bytes.clone(), + fhe_type: test.fhe_type, + }, + link: test.link.clone(), + }; + + // SigncryptionPayload doesn't use tfhe-versionable, serialize with bc2wrap from v0.11.1 + // This uses the exact bc2wrap implementation and bincode version from v0.11.1 + let serialized = bc2wrap::serialize(&payload).unwrap(); + let filename = format!("{}.bincode", test.test_filename); + std::fs::write(dir.join(&filename), serialized).unwrap(); + + TestMetadataKMS::SigncryptionPayload(test) + } + + fn gen_signcryption_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(SIGNCRYPTION_KEY_TEST.state); + let (_verf_key, server_sig_key) = gen_sig_keys(&mut rng); + let (client_verf_key, _server_sig_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let signcrypt_key = UnifiedSigncryptionKeyOwned::new( + server_sig_key, + enc_key, + client_verf_key.verf_key_id(), + ); + store_versioned_test!(&signcrypt_key, dir, &SIGNCRYPTION_KEY_TEST.test_filename); + TestMetadataKMS::UnifiedSigncryptionKeyOwned(SIGNCRYPTION_KEY_TEST) + } + + fn gen_designcryption_key(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(UNSIGNCRYPTION_KEY_TEST.state); + let (sender_verf_key, _sender_sig_key) = gen_sig_keys(&mut rng); + let (receiver_verf_key, _receiver_sig_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (dec_key, enc_key) = encryption.keygen().unwrap(); + let signcrypt_key = UnifiedUnsigncryptionKeyOwned::new( + dec_key, + enc_key, + sender_verf_key, + receiver_verf_key.verf_key_id().to_vec(), + ); + store_versioned_test!(&signcrypt_key, dir, &UNSIGNCRYPTION_KEY_TEST.test_filename); + TestMetadataKMS::UnifiedUnsigncryptionKeyOwned(UNSIGNCRYPTION_KEY_TEST) + } + + fn gen_backup_ciphertext(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(BACKUP_CIPHERTEXT_TEST.state); + let backup_id: RequestId = RequestId::new_random(&mut rng); + // Generate the unified ciphertext after using the RNG for generating backup ID since backup ID + // will also be generated as part of the test + let mut kem_ct = [0_u8; 32]; + rng.fill_bytes(&mut kem_ct); + let mut payload_ct = [0_u8; 32]; + rng.fill_bytes(&mut payload_ct); + let ciphertext: UnifiedCipher = UnifiedCipher { + cipher: HybridKemCt { + nonce: [0_u8; 12], + kem_ct: kem_ct.to_vec(), + payload_ct: payload_ct.to_vec(), + }, + pke_type: PkeSchemeType::MlKem512, + }; + store_versioned_auxiliary!( + &ciphertext, + dir, + &BACKUP_CIPHERTEXT_TEST.test_filename, + &BACKUP_CIPHERTEXT_TEST.unified_cipher_filename, + ); + + let backup_ct = BackupCiphertext { + ciphertext, + priv_data_type: PrivDataType::SigningKey, + backup_id, + }; + + store_versioned_test!(&backup_ct, dir, &BACKUP_CIPHERTEXT_TEST.test_filename); + TestMetadataKMS::BackupCiphertext(BACKUP_CIPHERTEXT_TEST) + } + + fn gen_unified_signcryption(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(UNIFIED_SIGNCRYPTION_TEST.state); + let (verf_key, server_sig_key) = gen_sig_keys(&mut rng); + let (client_verf_key, _server_sig_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let signcrypt_key = UnifiedSigncryptionKeyOwned::new( + server_sig_key, + enc_key, + client_verf_key.verf_key_id(), + ); + let signcryption = signcrypt_key + .signcrypt(&mut rng, b"TESTTEST", &verf_key) + .unwrap(); + + store_versioned_test!(&signcryption, dir, &UNIFIED_SIGNCRYPTION_TEST.test_filename); + TestMetadataKMS::UnifiedSigncryption(UNIFIED_SIGNCRYPTION_TEST) + } + + fn gen_unified_cipher(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(UNIFIED_CIPHER_TEST.state); + let mut kem_ct = [0_u8; 32]; + rng.fill_bytes(&mut kem_ct); + let mut payload_ct = [0_u8; 32]; + rng.fill_bytes(&mut payload_ct); + let kem = HybridKemCt { + nonce: [0_u8; 12], + kem_ct: kem_ct.to_vec(), + payload_ct: payload_ct.to_vec(), + }; + store_versioned_auxiliary!( + &kem, + dir, + &UNIFIED_CIPHER_TEST.test_filename, + &UNIFIED_CIPHER_TEST.hybrid_kem_filename, + ); + let cipher = UnifiedCipher { + cipher: kem, + pke_type: PkeSchemeType::MlKem512, + }; + + store_versioned_test!(&cipher, dir, &UNIFIED_CIPHER_TEST.test_filename); + + TestMetadataKMS::UnifiedCipher(UNIFIED_CIPHER_TEST) + } + + fn gen_hybrid_kem_ct(dir: &PathBuf) -> TestMetadataKMS { + let test = hybrid_kem_ct_test(); + let cipher = HybridKemCt { + nonce: test.nonce, + kem_ct: test.kem_ct.clone(), + payload_ct: test.payload_ct.clone(), + }; + + store_versioned_test!(&cipher, dir, &test.test_filename); + + TestMetadataKMS::HybridKemCt(test) + } + + fn gen_prss_setup_combined(dir: &PathBuf) -> TestMetadataKMS { + let role = Role::indexed_from_one(PRSS_SETUP_COMBINED_TEST.role_i); + let base_session_64 = get_networkless_base_session_for_parties( + PRSS_SETUP_COMBINED_TEST.amount as usize, + PRSS_SETUP_COMBINED_TEST.threshold, + role, + ); + let base_session_128 = get_networkless_base_session_for_parties( + PRSS_SETUP_COMBINED_TEST.amount as usize, + PRSS_SETUP_COMBINED_TEST.threshold, + role, + ); + let prss_setup_z64 = get_dummy_prss_setup::(base_session_64); + let prss_setup_z128 = get_dummy_prss_setup::(base_session_128); + let prss = PRSSSetupCombined { + prss_setup_z64: prss_setup_z64.clone(), + prss_setup_z128: prss_setup_z128.clone(), + num_parties: PRSS_SETUP_COMBINED_TEST.amount, + threshold: PRSS_SETUP_COMBINED_TEST.threshold, + }; + store_versioned_auxiliary!( + &prss_setup_z64, + dir, + &PRSS_SETUP_COMBINED_TEST.test_filename, + &PRSS_SETUP_COMBINED_TEST.prss_setup_64, + ); + store_versioned_auxiliary!( + &prss_setup_z128, + dir, + &PRSS_SETUP_COMBINED_TEST.test_filename, + &PRSS_SETUP_COMBINED_TEST.prss_setup_128, + ); + + store_versioned_test!(&prss, dir, &PRSS_SETUP_COMBINED_TEST.test_filename); + TestMetadataKMS::PrssSetupCombined(PRSS_SETUP_COMBINED_TEST) + } + + fn gen_context_info(dir: &PathBuf) -> TestMetadataKMS { + let test = context_info_test(); + let mut rng = AesRng::seed_from_u64(test.state); + // Note that `NodeInfo`, `SoftwareVersion` and `ReleasePCRValues` are tested separately so we just do a simple static construction here + let node_info = NodeInfo { + mpc_identity: "Staoshi Nakamoto".to_string(), + party_id: 42, + verification_key: None, + external_url: "https://node42.example.com".to_string(), + ca_cert: None, + public_storage_url: "https://storage.example.com/node42".to_string(), + public_storage_prefix: Some("PUB".to_string()), + extra_verification_keys: vec![], + }; + let software_version = SoftwareVersion { + major: 2, + minor: 11, + patch: 12, + tag: None, + }; + let pcr_values = ReleasePCRValues { + pcr0: vec![0_u8; 32], + pcr1: vec![1_u8; 32], + pcr2: vec![2_u8; 32], + }; + let context_info = ContextInfo { + mpc_nodes: vec![node_info.clone(), node_info.clone()], + software_version, + context_id: RequestId::new_random(&mut rng).into(), + threshold: test.threshold, + pcr_values: vec![pcr_values.clone(), pcr_values.clone()], + }; + + store_versioned_test!(&context_info, dir, &test.test_filename); + + TestMetadataKMS::ContextInfo(test) + } + + fn gen_node_info(dir: &PathBuf) -> TestMetadataKMS { + let node_info_test = node_info_test(); + let mut rng = AesRng::seed_from_u64(node_info_test.state); + let (verf_key, _sig_key) = gen_sig_keys(&mut rng); + let (verf_key2, _sig_key) = gen_sig_keys(&mut rng); + let node_info = NodeInfo { + mpc_identity: node_info_test.mpc_identity.to_string(), + party_id: node_info_test.party_id, + verification_key: Some(verf_key), + external_url: node_info_test.external_url.to_string(), + ca_cert: node_info_test.ca_cert.clone(), // We currently don't have simple code for generating certificates + public_storage_url: node_info_test.public_storage_url.to_string(), + public_storage_prefix: Some(node_info_test.public_storage_prefix.to_string()), + extra_verification_keys: vec![verf_key2], + }; + + store_versioned_test!(&node_info, dir, &node_info_test.test_filename); + + TestMetadataKMS::NodeInfo(node_info_test) + } + + fn gen_software_version(dir: &PathBuf) -> TestMetadataKMS { + let software_version = SoftwareVersion { + major: SOFTWARE_VERSION_TEST.major, + minor: SOFTWARE_VERSION_TEST.minor, + patch: SOFTWARE_VERSION_TEST.patch, + tag: Some(SOFTWARE_VERSION_TEST.tag.to_string()), + }; + + store_versioned_test!(&software_version, dir, &SOFTWARE_VERSION_TEST.test_filename); + + TestMetadataKMS::SoftwareVersion(SOFTWARE_VERSION_TEST) + } + + fn gen_recovery_material(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(RECOVERY_MATERIAL_TEST.state); + let backup_id: RequestId = RequestId::new_random(&mut rng); + let (operator_pk, operator_sk) = gen_sig_keys(&mut rng); + let mut commitments = BTreeMap::new(); + let mut cts = BTreeMap::new(); + for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { + let cus_role = Role::indexed_from_one(role_j); + let (custodian_pk, _) = gen_sig_keys(&mut rng); + let backup_material = BackupMaterial { + backup_id, + custodian_pk, + custodian_role: cus_role, + operator_pk: operator_pk.clone(), + shares: Vec::new(), + }; + let msg_digest = + safe_serialize_hash_element_versioned(&DSEP_BACKUP_COMMITMENT, &backup_material) + .unwrap(); + commitments.insert(cus_role, msg_digest); + let mut payload = [0_u8; 32]; + rng.fill_bytes(&mut payload); + let cts_out = InnerOperatorBackupOutput { + signcryption: UnifiedSigncryption { + payload: payload.to_vec(), + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }, + }; + cts.insert(cus_role, cts_out); + } + + // Dummy payload; but needs to be a properly serialized payload + // This must be generated after the commitment stuff, since the test will regenerate the commitment stuff, + // but read the custodian context from disk + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let (cus_pk, _) = gen_sig_keys(&mut rng); + let payload = CustodianSetupMessagePayload { + header: "header".to_string(), + random_value: [4_u8; 32], + timestamp: 0, + public_enc_key: enc_key.clone(), + verification_key: cus_pk.clone(), + }; + let mut payload_serial = Vec::new(); + safe_serialize(&payload, &mut payload_serial, SAFE_SER_SIZE_LIMIT).unwrap(); + let mut custodian_nodes = Vec::new(); + for role_j in 1..=RECOVERY_MATERIAL_TEST.custodian_count { + let setup_msg = CustodianSetupMessage { + custodian_role: role_j as u64, + name: format!("Custodian-{role_j}"), + payload: payload_serial.clone(), + }; + custodian_nodes.push(setup_msg); + } + let custodian_context = CustodianContext { + custodian_nodes, + custodian_context_id: Some(backup_id.into()), + threshold: 1, + }; + let internal_custodian_context = + InternalCustodianContext::new(custodian_context, enc_key).unwrap(); + store_versioned_auxiliary!( + &internal_custodian_context, + dir, + &RECOVERY_MATERIAL_TEST.test_filename, + &RECOVERY_MATERIAL_TEST.internal_cus_context_filename, + ); + let recovery_material = RecoveryValidationMaterial::new( + cts, + commitments, + internal_custodian_context, + &operator_sk, + kms_grpc_0_14_0::ContextId::from_bytes(RECOVERY_MATERIAL_TEST.mpc_context_id), + ) + .unwrap(); + store_versioned_test!( + &recovery_material, + dir, + &RECOVERY_MATERIAL_TEST.test_filename + ); + TestMetadataKMS::RecoveryValidationMaterial(RECOVERY_MATERIAL_TEST) + } + + fn gen_internal_recovery_request(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_RECOVERY_REQUEST_TEST.state); + let backup_id: RequestId = RequestId::new_random(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_dec_key, enc_key) = encryption.keygen().unwrap(); + let (verf_key, _) = gen_sig_keys(&mut rng); + let mut cts = BTreeMap::new(); + for role_j in 1..=INTERNAL_RECOVERY_REQUEST_TEST.amount { + let cur_role = Role::indexed_from_one(role_j as usize); + let mut payload = [0_u8; 32]; + rng.fill_bytes(&mut payload); + let signcryption = UnifiedSigncryption { + payload: payload.to_vec(), + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }; + cts.insert(cur_role, InnerOperatorBackupOutput { signcryption }); + } + let recovery_material = + InternalRecoveryRequest::new(enc_key, cts, backup_id, verf_key).unwrap(); + store_versioned_test!( + &recovery_material, + dir, + &INTERNAL_RECOVERY_REQUEST_TEST.test_filename + ); + TestMetadataKMS::InternalRecoveryRequest(INTERNAL_RECOVERY_REQUEST_TEST) + } + + fn gen_internal_cus_context_handles(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_CONTEXT_TEST.state); + let context_id: RequestId = RequestId::new_random(&mut rng); + let mut cus_nodes = BTreeMap::new(); + for role_j in 1..=INTERNAL_CUS_CONTEXT_TEST.custodian_count { + let cus_role = Role::indexed_from_one(role_j); + let (custodian_verf_key, _) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_, cus_enc_key) = encryption.keygen().unwrap(); + let mut rnd = [0_u8; 32]; + rng.fill_bytes(&mut rnd); + let setup_msg = InternalCustodianSetupMessage { + header: "header".to_string(), + custodian_role: cus_role, + name: format!("role{role_j}"), + random_value: rnd, + timestamp: 42, + public_enc_key: cus_enc_key, + public_verf_key: custodian_verf_key, + }; + cus_nodes.insert(cus_role, setup_msg); + } + // Generate the extra encryption key last since it will be loaded from file and + // thus we should avoid using the RNG for the things that it will be used to generate in the test + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (_, cus_enc_key) = encryption.keygen().unwrap(); + let internal_cus_context = InternalCustodianContext { + threshold: 1, + context_id, + custodian_nodes: cus_nodes, + backup_enc_key: cus_enc_key.clone(), + }; + store_versioned_auxiliary!( + &cus_enc_key, + dir, + &INTERNAL_CUS_CONTEXT_TEST.test_filename, + &INTERNAL_CUS_CONTEXT_TEST.unified_enc_key_filename, + ); + + store_versioned_test!( + &internal_cus_context, + dir, + &INTERNAL_CUS_CONTEXT_TEST.test_filename + ); + + TestMetadataKMS::InternalCustodianContext(INTERNAL_CUS_CONTEXT_TEST) + } + + fn gen_kms_fhe_key_handles(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(KMS_FHE_KEY_HANDLES_TEST.state); + let (_, private_sig_key) = gen_sig_keys(&mut rng); + store_versioned_auxiliary!( + &private_sig_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.sig_key_filename, + ); + + let dkg_params: DKGParams = DKGParams::WithSnS(convert_dkg_params_sns( + KMS_FHE_KEY_HANDLES_TEST.dkg_parameters_sns, + )); + let seed = Some(Seed(KMS_FHE_KEY_HANDLES_TEST.seed)); + + let client_key = generate_client_fhe_key(dkg_params, Tag::default(), seed); + store_versioned_auxiliary!( + &client_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.client_key_filename, + ); + + // The following code is basically the same as in `generate_fhe_keys` in + // `service/src/cryptography/central_kms.rs`, because we need to retrieve and save some of + // its intermediate values in order to be able to re-build a KmsFheKeyHandles in tests + let server_key = client_key.generate_server_key(); + let server_key = server_key.into_raw_parts(); + let decompression_key = server_key.3.clone(); + + store_versioned_auxiliary!( + &decompression_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.decompression_key_filename, + ); + + let server_key = ServerKey::from_raw_parts( + server_key.0, + server_key.1, + server_key.2, + server_key.3, + server_key.4, + server_key.5, + server_key.6, + server_key.7, + Tag::default(), + ); + + store_versioned_auxiliary!( + &server_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.server_key_filename, + ); + + let public_key = FhePublicKey::new(&client_key); + store_versioned_auxiliary!( + &public_key, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename, + &KMS_FHE_KEY_HANDLES_TEST.public_key_filename, + ); + + let public_key_set = FhePubKeySet { + public_key, + server_key, + }; + + // NOTE: kms_fhe_key_handles.public_key_info is a HashMap + // so generation is not deterministic + let key_id = kms_grpc_0_14_0::RequestId::zeros(); + let preproc_id = kms_grpc_0_14_0::RequestId::zeros(); + let kms_fhe_key_handles = KmsFheKeyHandles::new( + &private_sig_key, + client_key, + &key_id, + &preproc_id, + &public_key_set, + decompression_key, + &dummy_domain(), + Vec::new(), // empty extra_data + ) + .unwrap(); + + store_versioned_test!( + &kms_fhe_key_handles, + dir, + &KMS_FHE_KEY_HANDLES_TEST.test_filename + ); + + TestMetadataKMS::KmsFheKeyHandles(KMS_FHE_KEY_HANDLES_TEST) + } + + fn gen_threshold_fhe_keys(dir: &PathBuf) -> TestMetadataKMS { + let role = Role::indexed_from_one(THRESHOLD_FHE_KEYS_TEST.role_i); + let mut base_session = get_networkless_base_session_for_parties( + THRESHOLD_FHE_KEYS_TEST.amount, + THRESHOLD_FHE_KEYS_TEST.threshold, + role, + ); + let dkg_params: DKGParams = DKGParams::WithSnS(convert_dkg_params_sns( + THRESHOLD_FHE_KEYS_TEST.dkg_parameters_sns, + )); + + let rt = Runtime::new().unwrap(); + let (fhe_pub_key_set, private_key_set) = rt.block_on(async { + insecure_initialize_key_material(&mut base_session, dkg_params, Tag::default()) + .await + .unwrap() + }); + store_versioned_auxiliary!( + &private_key_set, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.private_key_set_filename, + ); + + let (integer_server_key, _, _, _, sns_key, _, _, _, _) = + fhe_pub_key_set.server_key.clone().into_raw_parts(); + store_versioned_auxiliary!( + &sns_key, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.sns_key_filename, + ); + store_versioned_auxiliary!( + &integer_server_key, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.integer_server_key_filename, + ); + + // NOTE: this is not deterministic since the result is a HashMap + // compute_all_info doesn't exist in v0.11.1, so we create the metadata manually + let info: HashMap = HashMap::new(); + store_versioned_auxiliary!( + &info, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.info_filename, + ); + + let decompression_key = fhe_pub_key_set.server_key.to_owned().into_raw_parts().3; + store_versioned_auxiliary!( + &decompression_key, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename, + &THRESHOLD_FHE_KEYS_TEST.decompression_key_filename, + ); + + let public_material = PublicKeyMaterial::Uncompressed { + integer_server_key: std::sync::Arc::new(integer_server_key), + sns_key: sns_key.map(std::sync::Arc::new), + decompression_key: decompression_key.map(std::sync::Arc::new), + }; + let threshold_fhe_keys = ThresholdFheKeys::new( + std::sync::Arc::new(private_key_set), + public_material, + kms_0_14_0::engine::base::KeyGenMetadata::LegacyV0(info), + ); + + store_versioned_test!( + &threshold_fhe_keys, + dir, + &THRESHOLD_FHE_KEYS_TEST.test_filename + ); + + TestMetadataKMS::ThresholdFheKeys(THRESHOLD_FHE_KEYS_TEST) + } + + /// Generates the _internal_ custodian setup message + fn gen_internal_cus_setup_msg(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_SETUP_MSG_TEST.state); + let (_verification_key, signing_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (private_key, public_key) = encryption.keygen().unwrap(); + let custodian = Custodian::new( + Role::indexed_from_one(1), + signing_key, + public_key, + private_key, + ) + .unwrap(); + let custodian_setup_message = custodian + .generate_setup_message(&mut rng, "custodian-1".to_string()) + .unwrap(); + store_versioned_test!( + &custodian_setup_message, + dir, + &INTERNAL_CUS_SETUP_MSG_TEST.test_filename + ); + TestMetadataKMS::InternalCustodianSetupMessage(INTERNAL_CUS_SETUP_MSG_TEST) + } + + fn gen_internal_cus_rec_out(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(INTERNAL_CUS_REC_OUT_TEST.state); + let (operator_verification_key, _) = gen_sig_keys(&mut rng); + let mut buf = [0u8; 100]; + rng.fill_bytes(&mut buf); + let signcryption = UnifiedSigncryption { + payload: buf.to_vec(), + pke_type: PkeSchemeType::MlKem512, + signing_type: SigningSchemeType::Ecdsa256k1, + }; + let icro = InternalCustodianRecoveryOutput { + signcryption, + custodian_role: Role::indexed_from_one(2), + operator_verification_key, + mpc_context_id: RequestId::from_bytes(INTERNAL_CUS_REC_OUT_TEST.mpc_context_id), + }; + store_versioned_test!(&icro, dir, &INTERNAL_CUS_REC_OUT_TEST.test_filename); + TestMetadataKMS::InternalCustodianRecoveryOutput(INTERNAL_CUS_REC_OUT_TEST) + } + + fn gen_operator_backup_output(dir: &PathBuf) -> TestMetadataKMS { + let mut rng = AesRng::seed_from_u64(OPERATOR_BACKUP_OUTPUT_TEST.seed); + + let custodians: Vec<_> = (1..=OPERATOR_BACKUP_OUTPUT_TEST.custodian_count) + .map(|i| { + let (_verification_key, signing_key) = gen_sig_keys(&mut rng); + let mut encryption = Encryption::new(PkeSchemeType::MlKem512, &mut rng); + let (private_key, public_key) = encryption.keygen().unwrap(); + Custodian::new( + Role::indexed_from_one(i), + signing_key, + public_key, + private_key, + ) + .unwrap() + }) + .collect(); + let custodian_messages: Vec<_> = custodians + .iter() + .enumerate() + .map(|(i, c)| { + c.generate_setup_message(&mut rng, format!("Custodian-{i}")) + .unwrap() + }) + .collect(); + + let operator = { + let (_verification_key, signing_key) = gen_sig_keys(&mut rng); + Operator::new_for_sharing( + custodian_messages, + signing_key, + OPERATOR_BACKUP_OUTPUT_TEST.custodian_threshold, + custodians.len(), + ) + .unwrap() + }; + let operator_backup_output = &operator + .secret_share_and_signcrypt( + &mut rng, + &OPERATOR_BACKUP_OUTPUT_TEST.plaintext, + RequestId::from_bytes(OPERATOR_BACKUP_OUTPUT_TEST.backup_id), + ) + .unwrap() + .ct_shares[&Role::indexed_from_one(1)]; + + store_versioned_test!( + operator_backup_output, + dir, + &OPERATOR_BACKUP_OUTPUT_TEST.test_filename + ); + TestMetadataKMS::OperatorBackupOutput(OPERATOR_BACKUP_OUTPUT_TEST) + } +} + +struct DistributedDecryptionV0_14_0; + +impl DistributedDecryptionV0_14_0 { + fn gen_prss_setup_rpoly_64(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(PRSS_SETUP_RPOLY_64_TEST.role_i); + let base_session = get_networkless_base_session_for_parties( + PRSS_SETUP_RPOLY_64_TEST.amount, + PRSS_SETUP_RPOLY_64_TEST.threshold, + role, + ); + let prss_setup = get_dummy_prss_setup::(base_session); + + store_versioned_test!(&prss_setup, dir, &PRSS_SETUP_RPOLY_64_TEST.test_filename); + + TestMetadataDD::PRSSSetup(PRSS_SETUP_RPOLY_64_TEST) + } + + fn gen_prss_setup_rpoly_128(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(PRSS_SETUP_RPOLY_128_TEST.role_i); + let base_session = get_networkless_base_session_for_parties( + PRSS_SETUP_RPOLY_128_TEST.amount, + PRSS_SETUP_RPOLY_128_TEST.threshold, + role, + ); + let prss_setup = get_dummy_prss_setup::(base_session); + + store_versioned_test!(&prss_setup, dir, &PRSS_SETUP_RPOLY_128_TEST.test_filename); + + TestMetadataDD::PRSSSetup(PRSS_SETUP_RPOLY_128_TEST) + } + + fn gen_prss_set_64(dir: &PathBuf) -> TestMetadataDD { + let mut rng = AesRng::seed_from_u64(PRSS_SET_64_TEST.state); + + let mut party_set = Vec::new(); + for i in 1..=PRSS_SET_64_TEST.amount_parties { + party_set.push(Role::indexed_from_one(i)); + } + + let mut set_key = [0u8; 16]; + rng.fill_bytes(&mut set_key); + + let mut f_a_points = Vec::new(); + for _ in 0..PRSS_SET_64_TEST.amount_points { + f_a_points.push(ResiduePolyF4Z64::from_scalar(Wrapping(rng.next_u64()))); + } + + let current_set = PrssSet::::new( + party_set.clone(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + let legacy_set = PrssSetV0::::new( + party_set.iter().map(|r| r.one_based()).collect(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + store_versioned_auxiliary!( + &legacy_set.upgrade().unwrap(), + dir, + &PRSS_SET_64_TEST.test_filename, + &PRSS_SET_64_TEST.legacy_filename, + ); + store_versioned_test!(¤t_set, dir, &PRSS_SET_64_TEST.test_filename); + + TestMetadataDD::PrssSet(PRSS_SET_64_TEST) + } + + fn gen_prss_set_128(dir: &PathBuf) -> TestMetadataDD { + let mut rng = AesRng::seed_from_u64(PRSS_SET_128_TEST.state); + + let mut party_set = Vec::new(); + for i in 1..=PRSS_SET_128_TEST.amount_parties { + party_set.push(Role::indexed_from_one(i)); + } + + let mut set_key = [0u8; 16]; + rng.fill_bytes(&mut set_key); + + let mut f_a_points = Vec::new(); + for _ in 0..PRSS_SET_128_TEST.amount_points { + f_a_points.push(ResiduePolyF4Z128::from_scalar(Wrapping( + rng.next_u64() as u128 + ))); + } + + let current_set = PrssSet::::new( + party_set.clone(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + let legacy_set = PrssSetV0::::new( + party_set.iter().map(|r| r.one_based()).collect(), + PrfKey(set_key.clone()), + f_a_points.clone(), + ); + store_versioned_auxiliary!( + &legacy_set.upgrade().unwrap(), + dir, + &PRSS_SET_128_TEST.test_filename, + &PRSS_SET_128_TEST.legacy_filename, + ); + store_versioned_test!(¤t_set, dir, &PRSS_SET_128_TEST.test_filename); + + TestMetadataDD::PrssSet(PRSS_SET_128_TEST) + } + + fn gen_share_64(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(SHARE_64_TEST.owner); + let val = ResiduePolyF4Z64::from_scalar(Wrapping(SHARE_64_TEST.value as u64)); + let share = Share::::new(role, val); + + store_versioned_test!(&share, dir, &SHARE_64_TEST.test_filename); + + TestMetadataDD::Share(SHARE_64_TEST) + } + + fn gen_share_128(dir: &PathBuf) -> TestMetadataDD { + let role = Role::indexed_from_one(SHARE_128_TEST.owner); + let val = ResiduePolyF4Z128::from_scalar(Wrapping(SHARE_128_TEST.value)); + let share = Share::::new(role, val); + + store_versioned_test!(&share, dir, &SHARE_128_TEST.test_filename); + + TestMetadataDD::Share(SHARE_128_TEST) + } + + fn gen_prf_key(dir: &PathBuf) -> TestMetadataDD { + let mut buf = [0u8; 16]; + let mut rng = AesRng::from_seed(PRF_KEY_TEST.seed.to_le_bytes()); + rng.fill_bytes(&mut buf); + + let prf_key = PrfKey(buf); + + store_versioned_test!(&prf_key, dir, &PRF_KEY_TEST.test_filename); + + TestMetadataDD::PrfKey(PRF_KEY_TEST) + } + + fn gen_release_pcr_values(dir: &PathBuf) -> TestMetadataDD { + let mut rng = AesRng::seed_from_u64(RELEASE_PCR_VALUES_TEST.state); + let mut pcr0 = [0u8; 64]; + rng.fill_bytes(&mut pcr0); + let mut pcr1 = [0u8; 33]; + rng.fill_bytes(&mut pcr1); + let mut pcr2 = [0u8; 73]; + rng.fill_bytes(&mut pcr2); + + let pcr_values = ReleasePCRValues { + pcr0: pcr0.to_vec(), + pcr1: pcr1.to_vec(), + pcr2: pcr2.to_vec(), + }; + + store_versioned_test!(&pcr_values, dir, &RELEASE_PCR_VALUES_TEST.test_filename); + + TestMetadataDD::ReleasePCRValues(RELEASE_PCR_VALUES_TEST) + } +} + +struct KmsGrpcV0_14_0; + +impl KmsGrpcV0_14_0 { + fn gen_signed_pub_data_handle_internal(dir: &PathBuf) -> TestMetadataKmsGrpc { + let signed_pub_data_handle_internal = SignedPubDataHandleInternal::new( + SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.key_handle.to_string(), + SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.signature.to_vec(), + SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST + .external_signature + .to_vec(), + ); + + store_versioned_test!( + &signed_pub_data_handle_internal, + dir, + &SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST.test_filename + ); + + TestMetadataKmsGrpc::SignedPubDataHandleInternal(SIGNED_PUB_DATA_HANDLE_INTERNAL_TEST) + } + + fn gen_pub_data_type(dir: &PathBuf) -> TestMetadataKmsGrpc { + let pub_data_type = PubDataType::DecompressionKey; + store_versioned_test!(&pub_data_type, dir, &PUB_DATA_TYPE.test_filename); + + TestMetadataKmsGrpc::PubDataType(PUB_DATA_TYPE) + } + + fn gen_priv_data_type(dir: &PathBuf) -> TestMetadataKmsGrpc { + let priv_data_type = PrivDataType::ContextInfo; + store_versioned_test!(&priv_data_type, dir, &PRIV_DATA_TYPE.test_filename); + + TestMetadataKmsGrpc::PrivDataType(PRIV_DATA_TYPE) + } +} + +impl KMSCoreVersion for V0_14_0 { + const VERSION_NUMBER: &'static str = "0.14.0"; + + // Without this, some keys will be generated differently every time we run the script + fn seed_prng(seed: u128) { + let mut seeder = DeterministicSeeder::::new(Seed(seed)); + let shortint_engine = ShortintEngine::new_from_seeder(&mut seeder); + ShortintEngine::with_thread_local_mut(|local_engine| { + let _ = std::mem::replace(local_engine, shortint_engine); + }); + } + + fn gen_kms_data() -> Vec { + let dir = Self::data_dir().join(KMS_MODULE_NAME); + create_dir_all(&dir).unwrap(); + + vec![ + KmsV0_14_0::gen_private_sig_key(&dir), + KmsV0_14_0::gen_public_sig_key(&dir), + KmsV0_14_0::gen_app_key_blob(&dir), + KmsV0_14_0::gen_key_gen_metadata(&dir), + KmsV0_14_0::gen_crs_metadata(&dir), + KmsV0_14_0::gen_key_gen_metadata_with_extra_data(&dir), + KmsV0_14_0::gen_crs_metadata_with_extra_data(&dir), + KmsV0_14_0::gen_typed_plaintext(&dir), + KmsV0_14_0::gen_signcryption_payload(&dir), + KmsV0_14_0::gen_signcryption_key(&dir), + KmsV0_14_0::gen_designcryption_key(&dir), + KmsV0_14_0::gen_unified_signcryption(&dir), + KmsV0_14_0::gen_backup_ciphertext(&dir), + KmsV0_14_0::gen_unified_cipher(&dir), + KmsV0_14_0::gen_hybrid_kem_ct(&dir), + KmsV0_14_0::gen_prss_setup_combined(&dir), + KmsV0_14_0::gen_context_info(&dir), + KmsV0_14_0::gen_node_info(&dir), + KmsV0_14_0::gen_software_version(&dir), + KmsV0_14_0::gen_recovery_material(&dir), + KmsV0_14_0::gen_internal_recovery_request(&dir), + KmsV0_14_0::gen_internal_cus_context_handles(&dir), + KmsV0_14_0::gen_internal_cus_setup_msg(&dir), + KmsV0_14_0::gen_kms_fhe_key_handles(&dir), + KmsV0_14_0::gen_threshold_fhe_keys(&dir), + KmsV0_14_0::gen_internal_cus_rec_out(&dir), + KmsV0_14_0::gen_operator_backup_output(&dir), + ] + } + + fn gen_threshold_fhe_data() -> Vec { + let dir = Self::data_dir().join(DISTRIBUTED_DECRYPTION_MODULE_NAME); + create_dir_all(&dir).unwrap(); + + vec![ + DistributedDecryptionV0_14_0::gen_prss_setup_rpoly_64(&dir), + DistributedDecryptionV0_14_0::gen_prss_setup_rpoly_128(&dir), + DistributedDecryptionV0_14_0::gen_prss_set_64(&dir), + DistributedDecryptionV0_14_0::gen_prss_set_128(&dir), + DistributedDecryptionV0_14_0::gen_share_64(&dir), + DistributedDecryptionV0_14_0::gen_share_128(&dir), + DistributedDecryptionV0_14_0::gen_prf_key(&dir), + DistributedDecryptionV0_14_0::gen_release_pcr_values(&dir), + ] + } + + fn gen_kms_grpc_data() -> Vec { + let dir = Self::data_dir().join(KMS_GRPC_MODULE_NAME); + create_dir_all(&dir).unwrap(); + + vec![ + KmsGrpcV0_14_0::gen_signed_pub_data_handle_internal(&dir), + KmsGrpcV0_14_0::gen_pub_data_type(&dir), + KmsGrpcV0_14_0::gen_priv_data_type(&dir), + ] + } +} diff --git a/backward-compatibility/generate-v0.14.0/src/generate.rs b/backward-compatibility/generate-v0.14.0/src/generate.rs new file mode 100644 index 0000000000..398b485da3 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/generate.rs @@ -0,0 +1,174 @@ +//! Utility functions, traits and macros to generate and store versioned data for any kms-core version. + +use std::{ + borrow::Cow, + fs, + path::{Path, PathBuf}, +}; + +use serde::Serialize; +use tfhe_versionable_0_7::Versionize as Versionize_0_7; + +use backward_compatibility::{ + data_dir, dir_for_version, + parameters::{ + ClassicPBSParametersTest, DKGParamsRegularTest, DKGParamsSnSTest, + SwitchAndSquashCompressionParametersTest, SwitchAndSquashParametersTest, + }, + TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc, +}; + +// Parameters set for tests in kms-core 0.9, found in `PARAMS_TEST_BK_SNS`. However, for stability +// reasons, these should never change. +// For `DKGParamsRegularTest`, parameters `dedicated_compact_public_key_parameters` and +// `compression_decompression_parameters` are not included because they are optional tfhe-rs types, +// which means their backward compatibility is already tested. +pub const TEST_DKG_PARAMS_SNS: DKGParamsSnSTest = DKGParamsSnSTest { + regular_params: DKGParamsRegularTest { + sec: 128, + ciphertext_parameters: ClassicPBSParametersTest { + lwe_dimension: 10, + glwe_dimension: 1, + polynomial_size: 256, + lwe_noise_gaussian: 0, + glwe_noise_gaussian: 0, + pbs_base_log: 16, + pbs_level: 1, + ks_base_log: 14, + ks_level: 1, + message_modulus: 4, + carry_modulus: 4, + max_noise_level: 5, + log2_p_fail: -49.5137, // dummy parameter + encryption_key_choice: Cow::Borrowed("big"), + }, + flag: true, + }, + sns_params: SwitchAndSquashParametersTest { + glwe_dimension: 1, + glwe_noise_distribution: 0, + polynomial_size: 256, + pbs_base_log: 32, + pbs_level: 2, + message_modulus: 4, + carry_modulus: 4, + }, + sns_compression_parameters: SwitchAndSquashCompressionParametersTest { + packing_ks_level: 1, + packing_ks_base_log: 16, + packing_ks_polynomial_size: 256, + packing_ks_glwe_dimension: 1, + lwe_per_glwe: 10, + packing_ks_key_noise_distribution: 0, + message_modulus: 4, + carry_modulus: 4, + }, +}; + +pub fn save_bcode>(msg: &Data, path: P) { + // Use bincode 2.x API with legacy config to match bc2wrap behavior + let config = bincode::config::legacy().with_fixed_int_encoding(); + let encoded = bincode::serde::encode_to_vec(msg, config).unwrap(); + fs::write(path, encoded).unwrap(); +} + +/// Stores the test data in `dir`, encoded in bincode, using the right tfhe-versionable version +macro_rules! define_store_versioned_test_fn { + ($fn_name:ident, $versionize_trait:ident) => { + pub fn $fn_name>( + msg: &Data, + dir: P, + test_filename: &str, + ) { + let versioned = msg.versionize(); + + // Store in bincode + let filename_bincode = format!("{}.bcode", test_filename); + save_bcode(&versioned, dir.as_ref().join(filename_bincode)); + } + }; +} +define_store_versioned_test_fn!(store_versioned_test_05, Versionize_0_7); + +/// Stores the auxiliary data in `dir`, encoded in bincode, using the right tfhe-versionable version +macro_rules! define_store_versioned_auxiliary_fn { + ($fn_name:ident, $versionize_trait:ident) => { + pub fn $fn_name>( + msg: &Data, + dir: P, + test_name: &str, + filename: &str, + ) { + let versioned = msg.versionize(); + + // Store in bincode + let filename_bincode = format!("{}.bcode", filename); + let sub_dir_name = format!("auxiliary_{}", test_name); + let sub_dir = dir.as_ref().join(&sub_dir_name); + fs::create_dir_all(&sub_dir).unwrap(); + save_bcode( + &versioned, + dir.as_ref().join(sub_dir_name).join(filename_bincode), + ); + } + }; +} +define_store_versioned_auxiliary_fn!(store_versioned_auxiliary_05, Versionize_0_7); + +pub fn store_metadata(new_data: &Vec, path: P) +where + Meta: Serialize + serde::de::DeserializeOwned + Clone, + P: AsRef, +{ + let path = path.as_ref(); + + // If file doesn't exist, just write the new data + if !path.exists() { + let serialized = + ron::ser::to_string_pretty(new_data, ron::ser::PrettyConfig::default()).unwrap(); + fs::write(path, serialized).unwrap(); + return; + } + + // Load existing metadata + let existing_content = fs::read_to_string(path).unwrap(); + let mut combined_data: Vec = + ron::from_str(&existing_content).expect("Failed to deserialize existing metadata"); + + // Append new entries + combined_data.extend_from_slice(new_data); + + // Write combined data + let serialized = + ron::ser::to_string_pretty(&combined_data, ron::ser::PrettyConfig::default()).unwrap(); + fs::write(path, serialized).unwrap(); +} + +pub trait KMSCoreVersion { + const VERSION_NUMBER: &'static str; + + fn data_dir() -> PathBuf { + let base_data_dir = data_dir(); + dir_for_version(base_data_dir, Self::VERSION_NUMBER) + } + + /// How to fix the prng seed for this version to make sure the generated (public) keys do not change every time we run the script + fn seed_prng(seed: u128); + + /// Generates data for the KMS module for this version. + /// This should create KMS-core types, versionize them and store them into the version specific directory. + /// The metadata for the generated tests should be returned in the same order that the tests will be run. + fn gen_kms_data() -> Vec; + + /// Generates data for the KMG grpc module for this version. + /// This should create types from kms-grpc, + /// versionize them and store them into the version specific directory. + /// The metadata for the generated tests should be returned in the same order that the tests will be run. + fn gen_kms_grpc_data() -> Vec; + + /// Generates data for the distributed decryption module for this version. + /// This should create types from distributed decryption, + /// versionize them and store them into the version specific directory. + /// The metadata for the generated tests should be returned in the same order that the tests will be run. + fn gen_threshold_fhe_data() -> Vec; +} diff --git a/backward-compatibility/generate-v0.14.0/src/lib.rs b/backward-compatibility/generate-v0.14.0/src/lib.rs new file mode 100644 index 0000000000..a07a7d51b1 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/lib.rs @@ -0,0 +1,7 @@ +//! Data generation utilities for backward compatibility tests. +//! +//! This crate is separate from `backward-compatibility` to isolate version-specific +//! dependencies (like old KMS versions) from the test loading and execution logic. + +pub mod data_0_14; +pub mod generate; diff --git a/backward-compatibility/generate-v0.14.0/src/main.rs b/backward-compatibility/generate-v0.14.0/src/main.rs new file mode 100644 index 0000000000..64d5de52d2 --- /dev/null +++ b/backward-compatibility/generate-v0.14.0/src/main.rs @@ -0,0 +1,64 @@ +//! Main file to run for generating all the versioned data for all kms-core versions. + +use backward_compatibility::{ + data_dir, TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc, Testcase, + DISTRIBUTED_DECRYPTION_MODULE_NAME, KMS_GRPC_MODULE_NAME, KMS_MODULE_NAME, PRNG_SEED, +}; +use backward_compatibility_generate_v0_14_0::{ + data_0_14::V0_14_0, + generate::{store_metadata, KMSCoreVersion}, +}; + +// Type aliases +type KmsTestcases = Vec>; +type KmsGrpcTestcases = Vec>; +type DdTestcases = Vec>; + +fn gen_testcases( + gen_data_fn: F, + module_name: &str, +) -> Vec> +where + F: Fn() -> Vec, + Metadata: Clone, +{ + let tests = gen_data_fn(); + + tests + .iter() + .map(|metadata| Testcase { + kms_core_version_min: Vers::VERSION_NUMBER.to_string(), + kms_core_module: module_name.to_string(), + metadata: metadata.clone(), + }) + .collect() +} + +fn gen_all_data() -> (KmsTestcases, KmsGrpcTestcases, DdTestcases) { + // Seed TFHE-rs' key generation PRNG + Vers::seed_prng(PRNG_SEED); + + let kms_testcases = + gen_testcases::(Vers::gen_kms_data, KMS_MODULE_NAME); + + let kms_grpc_testcases = gen_testcases::( + Vers::gen_kms_grpc_data, + KMS_GRPC_MODULE_NAME, + ); + + let dd_testcases = gen_testcases::( + Vers::gen_threshold_fhe_data, + DISTRIBUTED_DECRYPTION_MODULE_NAME, + ); + + (kms_testcases, kms_grpc_testcases, dd_testcases) +} + +fn main() { + let (kms_testcases, kms_grpc_testcases, dd_testcases) = gen_all_data::(); + + // Use module name as the filename prefix + store_metadata(&kms_testcases, data_dir().join("kms.ron")); + store_metadata(&kms_grpc_testcases, data_dir().join("kms-grpc.ron")); + store_metadata(&dd_testcases, data_dir().join("threshold-fhe.ron")); +} From 3d07acfd4f047b51f6dbfbd09201bf59b3befde4 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 15 May 2026 12:42:45 +0200 Subject: [PATCH 21/29] chore: updated backwards files --- .../auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_20/kms/internal_custodian_setup_message.bcode | 2 +- .../data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode | 2 +- .../data/0_14_0/kms/internal_custodian_recovery_output.bcode | 2 +- .../data/0_14_0/kms/internal_custodian_setup_message.bcode | 2 +- .../data/0_14_0/kms/internal_recovery_request.bcode | 2 +- .../data/0_14_0/kms/kms_fhe_key_handles.bcode | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index 3e915b7200..d761bf957d 100644 --- a/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 size 468 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode index 44cd00f904..f260de9174 100644 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:271029c25928bcf107d5843363b3d604fcc6ce289e63191e2d86c60d9dc392f8 +oid sha256:33f53340b53b525e646d25f2b5918f431593d5a9c8a6e36aa16a968e271a0205 size 992 diff --git a/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode index a35ae27c47..0a44396d4c 100644 --- a/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode +++ b/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11575ae3f8530dde09f753f69c754bde1a07d7185290bf0725545675e877ea8f +oid sha256:ac0ded3ade3242ce472ecb8ff691834667b04d6c648f0535ff1028e627449ee2 size 258 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode index ff92537351..836c2129e3 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0728d5ceb78c452d0affe194733c43509bbf0886b1c2734258c31be77aaafb2e +oid sha256:b1e0264ec788ad7273ce2698c2016806d90fa49a45578ac17bcdc6183243f283 size 144 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode index b7ddb0e715..781a820c4c 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0c495b4c4bb470e419ddf637685bf31081d4f223180bb8628a4db6abf3e1f93 +oid sha256:95912457f5b3c35eeb729ebe105b7903e7a4b4d04e6d8cbcc8b1ad6996606d55 size 992 diff --git a/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode index fc91546070..a974d5707c 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a9ed66acac6beb2bcc673bd9dacc69eee174087655b20444cf4a9bcfb7d47fd +oid sha256:0a490c3e5d9bf53913d77bb73800955a5b145d422be8e6fc24def7f6585a93c0 size 1588 diff --git a/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode index a509ba13bc..397b91584f 100644 --- a/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 +oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 size 11318 From 67f3cb8c78196667c0b067a2ddd6d4eb9ad77304 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 15 May 2026 14:06:59 +0200 Subject: [PATCH 22/29] test: removed unneeded test --- core/service/src/engine/backup_operator.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/core/service/src/engine/backup_operator.rs b/core/service/src/engine/backup_operator.rs index 77dca2d27c..37d118b42b 100644 --- a/core/service/src/engine/backup_operator.rs +++ b/core/service/src/engine/backup_operator.rs @@ -1307,28 +1307,6 @@ mod tests { .await; } - #[tokio::test] - async fn test_filter_custodian_data_missing_verification_key() { - // The fixture has 3 custodians (roles 1..=3). Submit four outputs so role 4 passes the - // role-range check, then `validate_one_recovery_output` looks role 4 up in the operator's - // `custodian_keys` map, doesn't find it, and skips with `MissingVerificationKey`. - let (rec, verf_key, dec_key, enc_key) = dummy_recovery_material(1); - run_filter_expect_skip( - vec![ - dummy_output_for_operator(1), - dummy_output_for_operator(2), - dummy_output_for_operator(3), - dummy_output_for_operator(4), - ], - &rec, - &verf_key, - &dec_key, - &enc_key, - RecoverySkipReason::MissingVerificationKey, - ) - .await; - } - #[tokio::test] async fn test_update_backup_vault() { let mut priv_storage = RamStorage::new(); From c535aa7e16f493ce110226c17bb62e4ebbf5a54f Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 19 May 2026 16:04:06 +0200 Subject: [PATCH 23/29] chore: handle copilot comments --- backward-compatibility/generate-v0.14.0/Cargo.toml | 2 +- backward-compatibility/generate-v0.14.0/src/generate.rs | 2 +- core/service/tests/backward_compatibility_kms.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backward-compatibility/generate-v0.14.0/Cargo.toml b/backward-compatibility/generate-v0.14.0/Cargo.toml index f412757da7..f5ffe73dd1 100644 --- a/backward-compatibility/generate-v0.14.0/Cargo.toml +++ b/backward-compatibility/generate-v0.14.0/Cargo.toml @@ -15,7 +15,7 @@ bc2wrap = { git = "https://github.com/zama-ai/kms.git", package = "bc2wrap", rev # This is intentional - these crates are excluded from the workspace for isolation. # Each generator may need different versions to match its target KMS version. -# All dependencies below target tag v0.14.0-0. +# All dependencies below target tag v0.14.0-0 (for now just using a commit from main until tag is made). kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "3eb3862"} kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "3eb3862"} algebra_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-algebra", default-features = false, rev = "3eb3862" } diff --git a/backward-compatibility/generate-v0.14.0/src/generate.rs b/backward-compatibility/generate-v0.14.0/src/generate.rs index 398b485da3..492e83fd80 100644 --- a/backward-compatibility/generate-v0.14.0/src/generate.rs +++ b/backward-compatibility/generate-v0.14.0/src/generate.rs @@ -160,7 +160,7 @@ pub trait KMSCoreVersion { /// The metadata for the generated tests should be returned in the same order that the tests will be run. fn gen_kms_data() -> Vec; - /// Generates data for the KMG grpc module for this version. + /// Generates data for the KMS grpc module for this version. /// This should create types from kms-grpc, /// versionize them and store them into the version specific directory. /// The metadata for the generated tests should be returned in the same order that the tests will be run. diff --git a/core/service/tests/backward_compatibility_kms.rs b/core/service/tests/backward_compatibility_kms.rs index 6c011f539e..4bac3f9b87 100644 --- a/core/service/tests/backward_compatibility_kms.rs +++ b/core/service/tests/backward_compatibility_kms.rs @@ -723,7 +723,7 @@ fn test_context_info( let original_versionized: ContextInfo = load_and_unversionize(dir, test, format)?; let mut rng = AesRng::seed_from_u64(test.state); let node_info = NodeInfo { - mpc_identity: "Staoshi Nakamoto".to_string(), + mpc_identity: "Satoshi Nakamoto".to_string(), party_id: 42, verification_key: None, external_url: "https://node42.example.com".to_string(), From 4cb7f174805c197ec7a4f1654d4f2a065d00a319 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Tue, 19 May 2026 16:31:07 +0200 Subject: [PATCH 24/29] chore: regenerate --- backward-compatibility/Cargo.lock | 154 ++ .../data/0_11_1/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_0/kms/key_gen_metadata.bcode | 2 +- .../data/0_13_10/kms/key_gen_metadata.bcode | 2 +- .../internal_cus_context_handle.bcode | 3 - .../internal_custodian_recovery_output.bcode | 3 - .../internal_custodian_setup_message.bcode | 2 +- .../kms/internal_recovery_request.bcode | 3 - .../0_13_20/kms/kms_fhe_key_handles.bcode | 2 +- .../0_13_20/kms/operator_backup_output.bcode | 3 - .../data/0_13_20/kms/recovery_material.bcode | 3 - .../0_13_20/kms/signcryption_payload.bincode | Bin 0 -> 29 bytes .../data/0_13_20/kms/typed_plaintext.bincode | Bin 0 -> 17 bytes .../internal_custodian_setup_message.bcode | 2 +- backward-compatibility/data/kms-grpc.ron | 25 + backward-compatibility/data/kms.ron | 364 +++++ backward-compatibility/data/threshold-fhe.ron | 82 + .../generate-v0.13.20/Cargo.lock | 1427 +++++++---------- .../tests/backward_compatibility_kms.rs | 2 +- 20 files changed, 1234 insertions(+), 849 deletions(-) create mode 100644 backward-compatibility/Cargo.lock delete mode 100644 backward-compatibility/data/0_13_20/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode delete mode 100644 backward-compatibility/data/0_13_20/kms/recovery_material.bcode create mode 100644 backward-compatibility/data/0_13_20/kms/signcryption_payload.bincode create mode 100644 backward-compatibility/data/0_13_20/kms/typed_plaintext.bincode diff --git a/backward-compatibility/Cargo.lock b/backward-compatibility/Cargo.lock new file mode 100644 index 0000000000..3beb73e9fd --- /dev/null +++ b/backward-compatibility/Cargo.lock @@ -0,0 +1,154 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "backward-compatibility" +version = "0.14.0" +dependencies = [ + "bincode", + "ron", + "semver", + "serde", + "strum", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +dependencies = [ + "serde_core", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ron" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" +dependencies = [ + "base64", + "bitflags", + "serde", + "serde_derive", + "unicode-ident", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[patch.unused]] +name = "rcgen" +version = "0.14.7" +source = "git+https://github.com/mkmks/rcgen.git?branch=k256#f8582f243899a7eff1a6524b42da60faaec73f15" diff --git a/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode index e30c1ff159..2859334bb1 100644 --- a/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ab1ea78f19d679845dbea16d39dc5d02311736a66efc7dc86284eddfec94180 +oid sha256:78dcf61f269be47abe065d2f0b249ad076adf613284f90b9f1163f075133b6fb size 11199 diff --git a/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index 3e915b7200..d761bf957d 100644 --- a/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 size 468 diff --git a/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode index aff78c52fe..c08bd87f6f 100644 --- a/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d11d0c555157f483446fd64c71c694019f4ffff92c8604ace43b8a828d952a43 +oid sha256:62f8b355d53250052ce835b22a04b5911c2b196013e00fb446baf87927584134 size 245 diff --git a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode index aff78c52fe..c08bd87f6f 100644 --- a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d11d0c555157f483446fd64c71c694019f4ffff92c8604ace43b8a828d952a43 +oid sha256:62f8b355d53250052ce835b22a04b5911c2b196013e00fb446baf87927584134 size 245 diff --git a/backward-compatibility/data/0_13_20/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode b/backward-compatibility/data/0_13_20/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode deleted file mode 100644 index 3720877b3a..0000000000 --- a/backward-compatibility/data/0_13_20/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:83edb0410c16b0df4692bc269140625188b9168cec607eaabafbec2e3d27f068 -size 5714 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode deleted file mode 100644 index 38cdf921d8..0000000000 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5a79b59689143dadc62d606abd3fe5921a14fc7971d620dd246645d8368374f -size 221 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode index c0670eafbe..ac04027395 100644 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d17f1327cf70ca328c34ea554861058aad9dc723d4801405a1273fbd9af6645b +oid sha256:0bd33249da40b616bbbc1f43cfb777c37b33ba755ad0c7906c29149ad18b8507 size 992 diff --git a/backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode b/backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode deleted file mode 100644 index d3e042756e..0000000000 --- a/backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:131b45495e950de30f57d751f78f662d939fb50fa91265d5aaca4365b92b9bef -size 1665 diff --git a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode index 397b91584f..a509ba13bc 100644 --- a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 +oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 size 11318 diff --git a/backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode b/backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode deleted file mode 100644 index 7c24373275..0000000000 --- a/backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9622e8a05c3c04d5f8d74a5a9f9460b6be883f061ef3e9e49252553f2e50b7b -size 1260 diff --git a/backward-compatibility/data/0_13_20/kms/recovery_material.bcode b/backward-compatibility/data/0_13_20/kms/recovery_material.bcode deleted file mode 100644 index 6365f46725..0000000000 --- a/backward-compatibility/data/0_13_20/kms/recovery_material.bcode +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7c3a25b30266ea83f46f55e42aa155f7216e069f9cf79613c4a06163770c1b24 -size 6482 diff --git a/backward-compatibility/data/0_13_20/kms/signcryption_payload.bincode b/backward-compatibility/data/0_13_20/kms/signcryption_payload.bincode new file mode 100644 index 0000000000000000000000000000000000000000..3d998f4d15a2f7c391836229df41f62d71d7732a GIT binary patch literal 29 ZcmZQ&fB;4&W)@ZsAe#j$aBuCt_W%l816cq7 literal 0 HcmV?d00001 diff --git a/backward-compatibility/data/0_13_20/kms/typed_plaintext.bincode b/backward-compatibility/data/0_13_20/kms/typed_plaintext.bincode new file mode 100644 index 0000000000000000000000000000000000000000..50b7c47b79702e4dc18ab4ba027ddb3cfe249b4e GIT binary patch literal 17 ScmZQ&fB;4&W)@ZsAR7Px Date: Tue, 19 May 2026 17:52:15 +0200 Subject: [PATCH 25/29] chore: regenerate data --- .../data/0_11_0/kms/kms_fhe_key_handles.bcode | 2 +- .../data/0_13_0/kms/key_gen_metadata.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_10/kms/key_gen_metadata.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../internal_custodian_setup_message.bcode | 2 +- .../0_13_20/kms/kms_fhe_key_handles.bcode | 2 +- .../internal_custodian_setup_message.bcode | 2 +- .../data/0_14_0/kms/key_gen_metadata.bcode | 2 +- .../data/0_14_0/kms/kms_fhe_key_handles.bcode | 2 +- backward-compatibility/data/kms-grpc.ron | 25 -- backward-compatibility/data/kms.ron | 364 ------------------ backward-compatibility/data/threshold-fhe.ron | 82 ---- .../generate-v0.14.0/Cargo.lock | 46 +-- .../generate-v0.14.0/Cargo.toml | 14 +- 15 files changed, 40 insertions(+), 511 deletions(-) diff --git a/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode index 5d41e2eafc..c1ba2d0934 100644 --- a/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8d74ed16cbbb34018f8cc03b234818f7d2fd0b6255b47fb09db0d9af8845343 +oid sha256:8db11b1373de6d643aea6dc9117eb41ddb3f24671290b58e7a38368ec6d202bf size 11428 diff --git a/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode index c08bd87f6f..aff78c52fe 100644 --- a/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_0/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62f8b355d53250052ce835b22a04b5911c2b196013e00fb446baf87927584134 +oid sha256:d11d0c555157f483446fd64c71c694019f4ffff92c8604ace43b8a828d952a43 size 245 diff --git a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index 3e915b7200..d761bf957d 100644 --- a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 size 468 diff --git a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode index c08bd87f6f..aff78c52fe 100644 --- a/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62f8b355d53250052ce835b22a04b5911c2b196013e00fb446baf87927584134 +oid sha256:d11d0c555157f483446fd64c71c694019f4ffff92c8604ace43b8a828d952a43 size 245 diff --git a/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index d761bf957d..3e915b7200 100644 --- a/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 +oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 size 468 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode index ac04027395..f8774fbda1 100644 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0bd33249da40b616bbbc1f43cfb777c37b33ba755ad0c7906c29149ad18b8507 +oid sha256:aa6927561d8755350b9574584963a2ee110176e0f221908d4881bf53459ebaea size 992 diff --git a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode index a509ba13bc..397b91584f 100644 --- a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 +oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 size 11318 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode index a100f85525..43a2e5895f 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8a85b0ec533efe1a86a3ded7fe86eae2534e9da826fd28640fa516053355513 +oid sha256:11584e13ae5bc8c6243c0c288b76dd8fec570d06e9dffef3cb609459528ee882 size 992 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode index 8b5c1b78a1..5d440827de 100644 --- a/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:216516c2d9475a4e2bb098b47a7b0c00242bfcc7b0f6b9b48ffc031441fd6817 +oid sha256:66e3bc33dbc047674bf0163868f3d73ad86962c6fb07c4bf1db7c704ea4722b0 size 246 diff --git a/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode index 397b91584f..a509ba13bc 100644 --- a/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 +oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 size 11318 diff --git a/backward-compatibility/data/kms-grpc.ron b/backward-compatibility/data/kms-grpc.ron index 15c5cc2641..ed31e6a3c6 100644 --- a/backward-compatibility/data/kms-grpc.ron +++ b/backward-compatibility/data/kms-grpc.ron @@ -142,29 +142,4 @@ test_filename: "priv_data_type", )), ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms-grpc", - metadata: SignedPubDataHandleInternal(( - test_filename: "signed_pub_data_handle_internal", - state: 100, - key_handle: "key_handle", - signature: (1, 2, 3), - external_signature: (4, 5, 6), - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms-grpc", - metadata: PubDataType(( - test_filename: "pub_data_type", - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms-grpc", - metadata: PrivDataType(( - test_filename: "priv_data_type", - )), - ), ] \ No newline at end of file diff --git a/backward-compatibility/data/kms.ron b/backward-compatibility/data/kms.ron index 085dead3bd..aba833b17e 100644 --- a/backward-compatibility/data/kms.ron +++ b/backward-compatibility/data/kms.ron @@ -1582,370 +1582,6 @@ tag: "super fun version", )), ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: InternalCustodianContext(( - test_filename: "internal_cus_context", - internal_cus_setup_filename: "internal_cus_setup_handle", - unified_enc_key_filename: "unified_enc_key_handle", - state: 300, - custodian_count: 5, - )), - ), - ( - kms_core_version_min: "0.13.20", - kms_core_module: "kms", - metadata: InternalCustodianSetupMessage(( - test_filename: "internal_custodian_setup_message", - state: 42, - )), - ), - ( - kms_core_version_min: "0.13.20", - kms_core_module: "kms", - metadata: KmsFheKeyHandles(( - test_filename: "kms_fhe_key_handles", - client_key_filename: "client_key_handle", - public_key_filename: "public_key_handle", - server_key_filename: "server_key_handle", - sig_key_filename: "sig_key_handle", - decompression_key_filename: "decompression_key", - state: 100, - seed: 100, - element: "element", - dkg_parameters_sns: ( - regular_params: ( - sec: 128, - ciphertext_parameters: ( - lwe_dimension: 10, - glwe_dimension: 1, - polynomial_size: 256, - lwe_noise_gaussian: 0, - glwe_noise_gaussian: 0, - pbs_base_log: 16, - pbs_level: 1, - ks_base_log: 14, - ks_level: 1, - message_modulus: 4, - carry_modulus: 4, - max_noise_level: 5, - log2_p_fail: -49.5137, - encryption_key_choice: "big", - ), - flag: true, - ), - sns_params: ( - glwe_dimension: 1, - glwe_noise_distribution: 0, - polynomial_size: 256, - pbs_base_log: 32, - pbs_level: 2, - message_modulus: 4, - carry_modulus: 4, - ), - sns_compression_parameters: ( - packing_ks_level: 1, - packing_ks_base_log: 16, - packing_ks_polynomial_size: 256, - packing_ks_glwe_dimension: 1, - lwe_per_glwe: 10, - packing_ks_key_noise_distribution: 0, - message_modulus: 4, - carry_modulus: 4, - ), - ), - )), - ), - ( - kms_core_version_min: "0.13.20", - kms_core_module: "kms", - metadata: ThresholdFheKeys(( - test_filename: "threshold_fhe_keys", - private_key_set_filename: "private_key_set", - integer_server_key_filename: "integer_server_key", - sns_key_filename: "sns_key", - info_filename: "info", - decompression_key_filename: "decompression_key", - state: 100, - amount: 2, - threshold: 1, - role_i: 1, - element: "element", - dkg_parameters_sns: ( - regular_params: ( - sec: 128, - ciphertext_parameters: ( - lwe_dimension: 10, - glwe_dimension: 1, - polynomial_size: 256, - lwe_noise_gaussian: 0, - glwe_noise_gaussian: 0, - pbs_base_log: 16, - pbs_level: 1, - ks_base_log: 14, - ks_level: 1, - message_modulus: 4, - carry_modulus: 4, - max_noise_level: 5, - log2_p_fail: -49.5137, - encryption_key_choice: "big", - ), - flag: true, - ), - sns_params: ( - glwe_dimension: 1, - glwe_noise_distribution: 0, - polynomial_size: 256, - pbs_base_log: 32, - pbs_level: 2, - message_modulus: 4, - carry_modulus: 4, - ), - sns_compression_parameters: ( - packing_ks_level: 1, - packing_ks_base_log: 16, - packing_ks_polynomial_size: 256, - packing_ks_glwe_dimension: 1, - lwe_per_glwe: 10, - packing_ks_key_noise_distribution: 0, - message_modulus: 4, - carry_modulus: 4, - ), - ), - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: PrivateSigKey(( - test_filename: "private_sig_key", - state: 100, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: PublicSigKey(( - test_filename: "public_sig_key", - state: 100, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: AppKeyBlob(( - test_filename: "app_key_blob", - root_key_id: "root_key_id", - data_key_blob: "data_key_blob", - ciphertext: "ciphertext", - iv: "iv", - auth_tag: "auth_tag", - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: KeyGenMetadata(( - test_filename: "key_gen_metadata", - legacy_filename: "legacy_key_gen_metadata", - state: 100, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: CrsGenMetadata(( - test_filename: "crs_gen_metadata", - legacy_filename: "legacy_crs_gen_metadata", - state: 100, - max_num_bits: 2048, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: KeyGenMetadataWithExtraData(( - test_filename: "key_gen_metadata_with_extra_data", - state: 101, - extra_data: [ - 2, - 170, - 187, - 204, - ], - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: CrsGenMetadataWithExtraData(( - test_filename: "crs_gen_metadata_with_extra_data", - state: 101, - max_num_bits: 2048, - extra_data: [ - 2, - 221, - 238, - 255, - ], - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: TypedPlaintext(( - test_filename: "typed_plaintext", - plaintext_bytes: [ - 1, - 2, - 3, - 4, - 5, - ], - fhe_type: 8, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: SigncryptionPayload(( - test_filename: "signcryption_payload", - plaintext_bytes: [ - 1, - 2, - 3, - 4, - 5, - ], - fhe_type: 8, - link: [ - 222, - 173, - 190, - 239, - ], - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: UnifiedSigncryptionKeyOwned(( - test_filename: "signcryption_key", - state: 100, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: UnifiedUnsigncryptionKeyOwned(( - test_filename: "designcryption_key", - state: 200, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: UnifiedSigncryption(( - test_filename: "unified_signcryption", - state: 202, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: BackupCiphertext(( - test_filename: "backup_ciphertext", - unified_cipher_filename: "unified_ciphertext_handle", - state: 200, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: UnifiedCipher(( - test_filename: "unified_ciphertext", - hybrid_kem_filename: "hybrid_kem_ct_handle", - state: 123, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: HybridKemCt(( - test_filename: "hybrid_kem_ct", - nonce: (2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), - kem_ct: [ - 1, - 2, - 3, - 4, - 5, - ], - payload_ct: [ - 6, - 7, - 8, - 9, - 10, - ], - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: PrssSetupCombined(( - test_filename: "prss_setup_combined", - prss_setup_64: "prss_setup_64", - prss_setup_128: "prss_setup_128", - role_i: 3, - amount: 13, - threshold: 4, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: ContextInfo(( - test_filename: "context_info", - threshold: 3, - state: 234, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: NodeInfo(( - test_filename: "node_info", - mpc_identity: "node_mpc_identity", - party_id: 4, - public_storage_url: "https://storage.example.com/node4", - public_storage_prefix: "PUB", - external_url: "https://node4.example.com/mpc/something-something", - ca_cert: Some([ - 1, - 2, - 3, - 4, - 6, - 7, - 8, - 9, - ]), - state: 500, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "kms", - metadata: SoftwareVersion(( - test_filename: "software_version", - major: 0, - minor: 13, - patch: 4, - tag: "super fun version", - )), - ), ( kms_core_version_min: "0.14.0", kms_core_module: "kms", diff --git a/backward-compatibility/data/threshold-fhe.ron b/backward-compatibility/data/threshold-fhe.ron index 84e7a1cca7..eb56f87865 100644 --- a/backward-compatibility/data/threshold-fhe.ron +++ b/backward-compatibility/data/threshold-fhe.ron @@ -478,86 +478,4 @@ state: 64, )), ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: PRSSSetup(( - test_filename: "prss_setup_rpoly_64", - amount: 10, - threshold: 3, - role_i: 1, - residue_poly_size: 64, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: PRSSSetup(( - test_filename: "prss_setup_rpoly_128", - amount: 10, - threshold: 3, - role_i: 1, - residue_poly_size: 128, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: PrssSet(( - test_filename: "prss_set_64", - legacy_filename: "legacy_prss_set_64", - amount_parties: 7, - amount_points: 7, - residue_poly_size: 64, - state: 11111, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: PrssSet(( - test_filename: "prss_set_128", - legacy_filename: "legacy_prss_set_128", - amount_parties: 13, - amount_points: 3, - residue_poly_size: 128, - state: 2222, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: Share(( - test_filename: "share_64", - value: 34653246, - owner: 1, - residue_poly_size: 64, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: Share(( - test_filename: "share_128", - value: 934565743256423875434534434, - owner: 1, - residue_poly_size: 128, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: PrfKey(( - test_filename: "prf_key", - seed: 100, - )), - ), - ( - kms_core_version_min: "0.14.0", - kms_core_module: "threshold-fhe", - metadata: ReleasePCRValues(( - test_filename: "release_pcr_values", - state: 64, - )), - ), ] \ No newline at end of file diff --git a/backward-compatibility/generate-v0.14.0/Cargo.lock b/backward-compatibility/generate-v0.14.0/Cargo.lock index a335a8cb28..3665e424a7 100644 --- a/backward-compatibility/generate-v0.14.0/Cargo.lock +++ b/backward-compatibility/generate-v0.14.0/Cargo.lock @@ -1682,7 +1682,7 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bc2wrap" version = "2.0.1" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "bincode 2.0.1", "serde", @@ -2781,8 +2781,8 @@ dependencies = [ [[package]] name = "error-utils" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "tracing", @@ -3805,8 +3805,8 @@ dependencies = [ [[package]] name = "kms" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "aes", "aes-gcm", @@ -3892,8 +3892,8 @@ dependencies = [ [[package]] name = "kms-grpc" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -4337,8 +4337,8 @@ dependencies = [ [[package]] name = "observability" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "axum", @@ -6480,8 +6480,8 @@ checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "test-utils" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "bc2wrap", @@ -6655,8 +6655,8 @@ dependencies = [ [[package]] name = "thread-handles" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "error-utils", @@ -6686,8 +6686,8 @@ dependencies = [ [[package]] name = "threshold-algebra" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "error-utils", @@ -6708,8 +6708,8 @@ dependencies = [ [[package]] name = "threshold-execution" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "aes", "aes-prng", @@ -6754,8 +6754,8 @@ dependencies = [ [[package]] name = "threshold-hashing" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "bc2wrap", @@ -6765,8 +6765,8 @@ dependencies = [ [[package]] name = "threshold-networking" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "async-trait", @@ -6800,8 +6800,8 @@ dependencies = [ [[package]] name = "threshold-types" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=bf50d1e346fb40fa54a12b8910292b3b05b16291#bf50d1e346fb40fa54a12b8910292b3b05b16291" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=1dc6f4cce0892d7d79820c10bd5ad8c456f9c167#1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" dependencies = [ "anyhow", "async-trait", diff --git a/backward-compatibility/generate-v0.14.0/Cargo.toml b/backward-compatibility/generate-v0.14.0/Cargo.toml index 19b78fd507..38c6974cf6 100644 --- a/backward-compatibility/generate-v0.14.0/Cargo.toml +++ b/backward-compatibility/generate-v0.14.0/Cargo.toml @@ -9,19 +9,19 @@ license = "BSD-3-Clause-Clear" [dependencies] # Import the base backward-compatibility crate for shared types and utilities backward-compatibility = { path = ".." } -bc2wrap = { git = "https://github.com/zama-ai/kms.git", package = "bc2wrap", rev = "bf50d1e346fb40fa54a12b8910292b3b05b16291" } +bc2wrap = { git = "https://github.com/zama-ai/kms.git", package = "bc2wrap", rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } # NOTE: Some dependencies below are duplicated from ../Cargo.toml # This is intentional - these crates are excluded from the workspace for isolation. # Each generator may need different versions to match its target KMS version. # All dependencies below target tag v0.14.0-0 (for now just using a commit from main until tag is made). -kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "3eb3862"} -kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "3eb3862"} -algebra_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-algebra", default-features = false, rev = "3eb3862" } -threshold_execution_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-execution", default-features = false, rev = "3eb3862", features = ["testing"] } -threshold_networking_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-networking", default-features = false, rev = "3eb3862" } -threshold_types_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-types", default-features = false, rev = "3eb3862" } +kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167"} +kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167"} +algebra_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-algebra", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } +threshold_execution_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-execution", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167", features = ["testing"] } +threshold_networking_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-networking", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } +threshold_types_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-types", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } #error-utils_0_14_0 = { path = "./core/error-utils", default-features = false } #thread-handles_0_14_0 = { path = "./core/thread-handles" } From 356a84389ef24f91796d248ec6558189d29b7bbf Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Wed, 20 May 2026 10:34:12 +0200 Subject: [PATCH 26/29] chore: update backwards comp test --- .../auxiliary_threshold_fhe_keys/info.bcode | 2 +- .../data/0_11_0/kms/kms_fhe_key_handles.bcode | 2 +- .../data/0_11_0/kms/threshold_fhe_keys.bcode | 2 +- .../data/0_11_1/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../data/0_13_0/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../0_13_10/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../internal_custodian_setup_message.bcode | 2 +- .../key_gen_metadata_with_extra_data.bcode | 2 +- .../0_13_20/kms/kms_fhe_key_handles.bcode | 2 +- .../legacy_key_gen_metadata.bcode | 2 +- .../internal_custodian_recovery_output.bcode | 4 +- .../internal_custodian_setup_message.bcode | 2 +- .../kms/internal_recovery_request.bcode | 4 +- .../data/0_14_0/kms/key_gen_metadata.bcode | 2 +- .../key_gen_metadata_with_extra_data.bcode | 2 +- .../0_14_0/kms/operator_backup_output.bcode | 4 +- .../data/0_14_0/kms/recovery_material.bcode | 2 +- .../generate-v0.14.0/Cargo.lock | 46 +++++++++---------- .../generate-v0.14.0/Cargo.toml | 14 +++--- 22 files changed, 53 insertions(+), 53 deletions(-) diff --git a/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode b/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode index 859256079b..4b468d6c29 100644 --- a/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode +++ b/backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:922354a6e88322f5567e99dc6689258f40db225cc91876b74f2881e71507cdef +oid sha256:2079954959214cb0402a05eddc27240ed4d2ddce6303134f601e109bd4f3eabf size 482 diff --git a/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode index 5d41e2eafc..c1ba2d0934 100644 --- a/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_11_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8d74ed16cbbb34018f8cc03b234818f7d2fd0b6255b47fb09db0d9af8845343 +oid sha256:8db11b1373de6d643aea6dc9117eb41ddb3f24671290b58e7a38368ec6d202bf size 11428 diff --git a/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode b/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode index 376c1a3614..ba693728a4 100644 --- a/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode +++ b/backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7e4f57268fea99a49d5cb877e2382aece2f1e45ea79ebb012e64fc907115afa +oid sha256:c9d8b7fb017c1af4401f357d39c4314780797f2fa28093f2aa19267ea2979f51 size 505527 diff --git a/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode index 2859334bb1..e30c1ff159 100644 --- a/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_11_1/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78dcf61f269be47abe065d2f0b249ad076adf613284f90b9f1163f075133b6fb +oid sha256:5ab1ea78f19d679845dbea16d39dc5d02311736a66efc7dc86284eddfec94180 size 11199 diff --git a/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index d761bf957d..3e915b7200 100644 --- a/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 +oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 size 468 diff --git a/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode index 01f8f8a85c..501fb29423 100644 --- a/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_0/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2190f3e6afd35d3c1da4fe9e058d90c4b6e25febe03de181343db0170465d2b0 +oid sha256:56a6f47fe169b963fdc1b33bc3a74245d66832b22f62261679bee85a0dc5013e size 11208 diff --git a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index 3e915b7200..d761bf957d 100644 --- a/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 size 468 diff --git a/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode index 501fb29423..01f8f8a85c 100644 --- a/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56a6f47fe169b963fdc1b33bc3a74245d66832b22f62261679bee85a0dc5013e +oid sha256:2190f3e6afd35d3c1da4fe9e058d90c4b6e25febe03de181343db0170465d2b0 size 11208 diff --git a/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index 3e915b7200..d761bf957d 100644 --- a/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_13_20/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 size 468 diff --git a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode index ac04027395..9a484fe4ed 100644 --- a/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0bd33249da40b616bbbc1f43cfb777c37b33ba755ad0c7906c29149ad18b8507 +oid sha256:be7677719379ec60b91fab6c66c273907af82f09f032b8eb7b8938615f6db97f size 992 diff --git a/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode index 0a44396d4c..a35ae27c47 100644 --- a/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode +++ b/backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac0ded3ade3242ce472ecb8ff691834667b04d6c648f0535ff1028e627449ee2 +oid sha256:11575ae3f8530dde09f753f69c754bde1a07d7185290bf0725545675e877ea8f size 258 diff --git a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode index a509ba13bc..397b91584f 100644 --- a/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode +++ b/backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66109cc83c96100d35c06229016feaa517d71f30a2764d03fc1cd95c5abe7866 +oid sha256:556168b309d817cbcdd0a10554916546a09b59847b250d1d4b56c52a882db7c4 size 11318 diff --git a/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode index 3e915b7200..d761bf957d 100644 --- a/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode +++ b/backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcaa5ec92d837668257440f038409da4cfbab18d2f2f700f553386ae7b1802e5 +oid sha256:28e48be8b487d1008bb0c3231e1c04b7632516cefb43209050f354d08e557531 size 468 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode index 38cdf921d8..836c2129e3 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5a79b59689143dadc62d606abd3fe5921a14fc7971d620dd246645d8368374f -size 221 +oid sha256:b1e0264ec788ad7273ce2698c2016806d90fa49a45578ac17bcdc6183243f283 +size 144 diff --git a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode index a100f85525..80db2e7280 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8a85b0ec533efe1a86a3ded7fe86eae2534e9da826fd28640fa516053355513 +oid sha256:82dab1647344d54f7a36f6973db7a51dd9f25626693d4559f3c8cfc6444636c1 size 992 diff --git a/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode index d3e042756e..a974d5707c 100644 --- a/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode +++ b/backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:131b45495e950de30f57d751f78f662d939fb50fa91265d5aaca4365b92b9bef -size 1665 +oid sha256:0a490c3e5d9bf53913d77bb73800955a5b145d422be8e6fc24def7f6585a93c0 +size 1588 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode index 5d440827de..8b5c1b78a1 100644 --- a/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66e3bc33dbc047674bf0163868f3d73ad86962c6fb07c4bf1db7c704ea4722b0 +oid sha256:216516c2d9475a4e2bb098b47a7b0c00242bfcc7b0f6b9b48ffc031441fd6817 size 246 diff --git a/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode b/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode index 0a44396d4c..a35ae27c47 100644 --- a/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode +++ b/backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac0ded3ade3242ce472ecb8ff691834667b04d6c648f0535ff1028e627449ee2 +oid sha256:11575ae3f8530dde09f753f69c754bde1a07d7185290bf0725545675e877ea8f size 258 diff --git a/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode b/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode index 7c24373275..acf33d1721 100644 --- a/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode +++ b/backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9622e8a05c3c04d5f8d74a5a9f9460b6be883f061ef3e9e49252553f2e50b7b -size 1260 +oid sha256:e6bcc99dc0d9dbfa8e2a36acfcc8c61c602ff5efb4c6f1e9212c2a73a5e82390 +size 1292 diff --git a/backward-compatibility/data/0_14_0/kms/recovery_material.bcode b/backward-compatibility/data/0_14_0/kms/recovery_material.bcode index 6365f46725..e0992faa43 100644 --- a/backward-compatibility/data/0_14_0/kms/recovery_material.bcode +++ b/backward-compatibility/data/0_14_0/kms/recovery_material.bcode @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c3a25b30266ea83f46f55e42aa155f7216e069f9cf79613c4a06163770c1b24 +oid sha256:dab6df5aab012710bf4a270a23739db534d74aa51f402c47e66a738a153a2ea9 size 6482 diff --git a/backward-compatibility/generate-v0.14.0/Cargo.lock b/backward-compatibility/generate-v0.14.0/Cargo.lock index 4d70323621..8e82b3ac3b 100644 --- a/backward-compatibility/generate-v0.14.0/Cargo.lock +++ b/backward-compatibility/generate-v0.14.0/Cargo.lock @@ -1682,7 +1682,7 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bc2wrap" version = "2.0.1" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "bincode 2.0.1", "serde", @@ -2781,8 +2781,8 @@ dependencies = [ [[package]] name = "error-utils" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "tracing", @@ -3805,8 +3805,8 @@ dependencies = [ [[package]] name = "kms" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "aes", "aes-gcm", @@ -3892,8 +3892,8 @@ dependencies = [ [[package]] name = "kms-grpc" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -4337,8 +4337,8 @@ dependencies = [ [[package]] name = "observability" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "axum", @@ -6480,8 +6480,8 @@ checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "test-utils" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "bc2wrap", @@ -6655,8 +6655,8 @@ dependencies = [ [[package]] name = "thread-handles" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "error-utils", @@ -6686,8 +6686,8 @@ dependencies = [ [[package]] name = "threshold-algebra" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "error-utils", @@ -6708,8 +6708,8 @@ dependencies = [ [[package]] name = "threshold-execution" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "aes", "aes-prng", @@ -6754,8 +6754,8 @@ dependencies = [ [[package]] name = "threshold-hashing" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "bc2wrap", @@ -6765,8 +6765,8 @@ dependencies = [ [[package]] name = "threshold-networking" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "async-trait", @@ -6800,8 +6800,8 @@ dependencies = [ [[package]] name = "threshold-types" -version = "0.13.20-0" -source = "git+https://github.com/zama-ai/kms.git?rev=3eb3862#3eb3862e81502efc020ce718d81ddd90b2601320" +version = "0.14.0-0" +source = "git+https://github.com/zama-ai/kms.git?rev=865e4091da5d663dec82c62cca3f2a0aad83939a#865e4091da5d663dec82c62cca3f2a0aad83939a" dependencies = [ "anyhow", "async-trait", diff --git a/backward-compatibility/generate-v0.14.0/Cargo.toml b/backward-compatibility/generate-v0.14.0/Cargo.toml index 38c6974cf6..0fe501056f 100644 --- a/backward-compatibility/generate-v0.14.0/Cargo.toml +++ b/backward-compatibility/generate-v0.14.0/Cargo.toml @@ -9,19 +9,19 @@ license = "BSD-3-Clause-Clear" [dependencies] # Import the base backward-compatibility crate for shared types and utilities backward-compatibility = { path = ".." } -bc2wrap = { git = "https://github.com/zama-ai/kms.git", package = "bc2wrap", rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } +bc2wrap = { git = "https://github.com/zama-ai/kms.git", package = "bc2wrap", rev = "865e4091da5d663dec82c62cca3f2a0aad83939a" } # NOTE: Some dependencies below are duplicated from ../Cargo.toml # This is intentional - these crates are excluded from the workspace for isolation. # Each generator may need different versions to match its target KMS version. # All dependencies below target tag v0.14.0-0 (for now just using a commit from main until tag is made). -kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167"} -kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167"} -algebra_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-algebra", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } -threshold_execution_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-execution", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167", features = ["testing"] } -threshold_networking_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-networking", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } -threshold_types_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-types", default-features = false, rev = "1dc6f4cce0892d7d79820c10bd5ad8c456f9c167" } +kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "865e4091da5d663dec82c62cca3f2a0aad83939a"} +kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "865e4091da5d663dec82c62cca3f2a0aad83939a"} +algebra_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-algebra", default-features = false, rev = "865e4091da5d663dec82c62cca3f2a0aad83939a" } +threshold_execution_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-execution", default-features = false, rev = "865e4091da5d663dec82c62cca3f2a0aad83939a", features = ["testing"] } +threshold_networking_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-networking", default-features = false, rev = "865e4091da5d663dec82c62cca3f2a0aad83939a" } +threshold_types_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-types", default-features = false, rev = "865e4091da5d663dec82c62cca3f2a0aad83939a" } #error-utils_0_14_0 = { path = "./core/error-utils", default-features = false } #thread-handles_0_14_0 = { path = "./core/thread-handles" } From bffc3a4c337c7aa181924d948f997ccc78016364 Mon Sep 17 00:00:00 2001 From: Tore <33345641+jot2re@users.noreply.github.com> Date: Wed, 20 May 2026 12:33:54 +0200 Subject: [PATCH 27/29] Update docs/guides/backup.md Co-authored-by: David --- docs/guides/backup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/backup.md b/docs/guides/backup.md index 0a48dddc1b..894abf0221 100644 --- a/docs/guides/backup.md +++ b/docs/guides/backup.md @@ -172,7 +172,7 @@ Notes: ### Phase 3 — Ongoing backup (whenever the operator writes private material) -When the operator writes any `PrivDataType` (signing key, threshold FHE keys, custodian context itself, etc.) into private storage, the `SecretSharing` keychain wraps the bytes under `pk^{B}` and stores the resulting `BackupCiphertext` in the backup vault, tagged with the originating `RequestId` and `PrivDataType`. The custodians never see this material — only `pk^{B}` matters here. +When the operator writes any `PrivDataType` (signing key, threshold FHE keys, custodian context itself, etc.) to private storage, the `SecretSharing` keychain encrypts the data under `pk^{B}` and stores the resulting `BackupCiphertext` in the backup vault, tagged with the originating `RequestId` and `PrivDataType`. The custodians never see this material — only `pk^{B}` matters here. This phase is invisible to custodians and to the core-client. It runs continuously for the life of the operator. From cdf4ec6a23083914c52aa4f428f39294af90428e Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Wed, 20 May 2026 14:47:29 +0200 Subject: [PATCH 28/29] test: added tests requested by David --- core/service/src/vault/keychain/mod.rs | 93 ++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/core/service/src/vault/keychain/mod.rs b/core/service/src/vault/keychain/mod.rs index fb2dd6e3e2..98301e6365 100644 --- a/core/service/src/vault/keychain/mod.rs +++ b/core/service/src/vault/keychain/mod.rs @@ -253,6 +253,99 @@ pub mod tests { assert_eq!(buf, plaintext, "decrypted bytes must match the plaintext"); } + #[test] + fn test_encrypt_decrypt_empty_plaintext() { + let key = [0x42u8; 32]; + let iv = [0xABu8; 12]; + let mut buf: Vec = Vec::new(); + + let auth_tag = encrypt_under_data_key(&mut buf, &key, &iv) + .expect("encryption should succeed on empty plaintext"); + assert!( + buf.is_empty(), + "ciphertext of empty plaintext must also be empty" + ); + assert_eq!(auth_tag.len(), 16, "auth tag must be 128 bits"); + + decrypt_under_data_key(&mut buf, &key, &iv, &auth_tag) + .expect("decryption should succeed on empty ciphertext with valid auth tag"); + assert!( + buf.is_empty(), + "decrypted empty ciphertext must remain empty" + ); + } + + #[test] + fn test_encrypt_same_plaintext() { + let key = [0x42u8; 32]; + let iv1 = [0xAAu8; 12]; + let iv2 = [0xBBu8; 12]; + let plaintext = b"identical payload encrypted twice".to_vec(); + + let mut buf1 = plaintext.clone(); + let tag_1 = encrypt_under_data_key(&mut buf1, &key, &iv1).expect("encryption must succeed"); + let mut buf2 = plaintext.clone(); + let tag_2 =encrypt_under_data_key(&mut buf2, &key, &iv2).expect("encryption must succeed"); + + assert_ne!( + buf1, buf2, + "ciphertexts under distinct IVs must not be identical" + ); + // Tag will also be different + assert_ne!( + tag_1, tag_2, + "auth tags should be different under distinct IVs" + ); + } + + #[test] + fn test_encrypt_decrypt_rejects_swapped_key_and_iv() { + let key = [0x42u8; 32]; + let iv = [0xABu8; 12]; + let mut buf = b"some payload".to_vec(); + + // Pass IV (12 bytes) as the key: must fail the key length check. + let err = encrypt_under_data_key(&mut buf, &iv, &key) + .expect_err("encryption must reject swapped key and IV"); + assert!( + err.to_string().contains("data key length"), + "error should mention data key length, got: {err}" + ); + + // Same on the decryption path. + let auth_tag = vec![0u8; 16]; + let err = decrypt_under_data_key(&mut buf, &iv, &key, &auth_tag) + .expect_err("decryption must reject swapped key and IV"); + assert!( + err.to_string().contains("data key length"), + "error should mention data key length, got: {err}" + ); + } + + #[test] + fn test_decrypt_rejects_bitflipped_ciphertext() { + let key = [0x42u8; 32]; + let iv = [0xABu8; 12]; + let plaintext = b"sensitive payload that must not be tampered with".to_vec(); + + let mut buf = plaintext.clone(); + let auth_tag = encrypt_under_data_key(&mut buf, &key, &iv).expect("encryption must succeed"); + + // Flip a single bit in the first ciphertext byte. + buf[0] ^= 0x01; + + let err = decrypt_under_data_key(&mut buf, &key, &iv, &auth_tag) + .expect_err("decryption of tampered ciphertext must fail the auth tag check"); + assert!( + !err.to_string().is_empty(), + "must surface a decryption error, got empty message" + ); + assert_ne!( + buf, plaintext, + "tampered ciphertext must not decrypt back to the original plaintext" + ); + } + #[test] fn test_encrypt_under_data_key_rejects_invalid_iv() { let key = [0u8; 32]; From 721414cf84c1dc3e465979e7d4c0f9672072b26f Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Wed, 20 May 2026 14:58:46 +0200 Subject: [PATCH 29/29] fix: lint --- core/service/src/vault/keychain/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/service/src/vault/keychain/mod.rs b/core/service/src/vault/keychain/mod.rs index 98301e6365..3f1ec8da39 100644 --- a/core/service/src/vault/keychain/mod.rs +++ b/core/service/src/vault/keychain/mod.rs @@ -285,7 +285,7 @@ pub mod tests { let mut buf1 = plaintext.clone(); let tag_1 = encrypt_under_data_key(&mut buf1, &key, &iv1).expect("encryption must succeed"); let mut buf2 = plaintext.clone(); - let tag_2 =encrypt_under_data_key(&mut buf2, &key, &iv2).expect("encryption must succeed"); + let tag_2 = encrypt_under_data_key(&mut buf2, &key, &iv2).expect("encryption must succeed"); assert_ne!( buf1, buf2, @@ -329,7 +329,8 @@ pub mod tests { let plaintext = b"sensitive payload that must not be tampered with".to_vec(); let mut buf = plaintext.clone(); - let auth_tag = encrypt_under_data_key(&mut buf, &key, &iv).expect("encryption must succeed"); + let auth_tag = + encrypt_under_data_key(&mut buf, &key, &iv).expect("encryption must succeed"); // Flip a single bit in the first ciphertext byte. buf[0] ^= 0x01;