Skip to content

Commit 84722a4

Browse files
committed
merge main
2 parents dc6309b + e5f1efa commit 84722a4

File tree

29 files changed

+191
-151
lines changed

29 files changed

+191
-151
lines changed

Cargo.lock

Lines changed: 0 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ const_format = "=0.2.34" # Compile-time string formatting - HIGH RISK: Individu
134134
console_error_panic_hook = { version = "=0.1.7" } # WASM panic hook for better error messages - LOW RISK: rustwasm team
135135
criterion = { version = "=0.5.1", features = ["async_tokio"] } # Benchmarking framework - MEDIUM RISK: Individual maintainers (bheisler, lemmih, rust-bus), despite 120M+ downloads, test-only dependency
136136
crypto-bigint = { version = "=0.6.1", features = ["serde", "rand_core", "extra-sizes"] } # Big integer operations for crypto - LOW RISK: RustCrypto org
137-
ctor = "=0.4.2" # Constructor functions - HIGH RISK: Individual maintainer (mmastrac), test-only dependency
138137
dashmap = "=6.1.0" # Concurrent hashmap - HIGH RISK: Individual maintainer (xacrimon), despite 156M+ downloads
139138
derive_more = { version = "=2.0.1", features = ["display"] } # Derive macros for common traits - HIGH RISK: Individual maintainer (JelteF), despite 180M+ downloads
140139
enum_dispatch = "=0.3.13" # Enum dispatch optimization - HIGH RISK: Individual maintainer (Anton Lazarev), despite 29M+ downloads

core/service/src/client/tests/threshold/custodian_backup_tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ async fn auto_update_backup(amount_custodians: usize, threshold: u32) {
7272
))
7373
.unwrap();
7474

75-
let test_path = None;
75+
let temp_dir = tempfile::tempdir().unwrap();
76+
let test_path = Some(temp_dir.path());
7677
let dkg_param: WrappedDKGParams = FheParameter::Test.into();
7778
tokio::time::sleep(tokio::time::Duration::from_millis(TIME_TO_SLEEP_MS)).await;
7879
let (kms_servers, kms_clients, mut internal_client) = threshold_handles_custodian_backup(

core/service/src/cryptography/mod.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ pub mod encryption;
1111
#[allow(deprecated)]
1212
pub mod signcryption;
1313

14-
use crate::cryptography::encryption::UnifiedPublicEncKey;
15-
use crate::cryptography::internal_crypto_types::LegacySerialization;
1614
#[cfg(any(feature = "non-wasm", test))]
1715
use crate::cryptography::signatures::PrivateSigKey;
1816
#[cfg(any(feature = "non-wasm", test))]
@@ -28,17 +26,17 @@ pub(crate) fn compute_external_user_decrypt_signature(
2826
server_sk: &PrivateSigKey,
2927
payload: &UserDecryptionResponsePayload,
3028
eip712_domain: &Eip712Domain,
31-
user_pk: &UnifiedPublicEncKey,
29+
user_pk_buf: &[u8],
3230
extra_data: &[u8],
3331
) -> anyhow::Result<Vec<u8>> {
34-
let message = compute_user_decrypt_message(payload, user_pk, extra_data)?;
32+
let message = compute_user_decrypt_message(payload, user_pk_buf, extra_data)?;
3533
tracing::debug!("Computing signature for UserDecryptResponseVerification");
3634
compute_eip712_signature(server_sk, &message, eip712_domain)
3735
}
3836

3937
pub(crate) fn compute_user_decrypt_message(
4038
payload: &UserDecryptionResponsePayload,
41-
user_pk: &UnifiedPublicEncKey,
39+
user_pk_buf: &[u8],
4240
extra_data: &[u8],
4341
) -> anyhow::Result<UserDecryptResponseVerification> {
4442
// convert external_handles back to 256-bit bytes32 to be signed
@@ -62,21 +60,14 @@ pub(crate) fn compute_user_decrypt_message(
6260

6361
let user_decrypted_share_buf = bc2wrap::serialize(payload)?;
6462

65-
// LEGACY CODE: we used to only support ML-KEM1024 encoded with bincode
66-
// the solidity structure to sign with EIP-712
67-
// note that the JS client must also use the same encoding to verify the result
68-
let user_pk_buf = user_pk
69-
.to_legacy_bytes()
70-
.map_err(|e| anyhow::anyhow!("serialization error: {e}"))?;
71-
7263
tracing::info!(
7364
"Computed UserDecryptResponseVerification for handles {:?} and extra data \"{}\".",
7465
external_handles_bytes32,
7566
hex::encode(extra_data)
7667
);
7768

7869
Ok(UserDecryptResponseVerification {
79-
publicKey: user_pk_buf.into(),
70+
publicKey: user_pk_buf.to_vec().into(),
8071
ctHandles: external_handles_bytes32,
8172
userDecryptedShare: user_decrypted_share_buf.into(),
8273
extraData: extra_data.to_vec().into(),

core/service/src/engine/centralized/central_kms.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::cryptography::attestation::SecurityModuleProxy;
88
use crate::cryptography::compute_external_user_decrypt_signature;
99
use crate::cryptography::decompression;
1010
use crate::cryptography::encryption::UnifiedPublicEncKey;
11+
use crate::cryptography::internal_crypto_types::LegacySerialization;
1112
use crate::cryptography::signatures::{PrivateSigKey, PublicSigKey, Signature};
1213
use crate::cryptography::signcryption::SigncryptFHEPlaintext;
1314
use crate::cryptography::signcryption::UnifiedSigncryptionKey;
@@ -506,7 +507,7 @@ pub async fn async_user_decrypt<
506507
rng: &mut (impl CryptoRng + RngCore),
507508
typed_ciphertexts: &[TypedCiphertext],
508509
req_digest: &[u8],
509-
client_enc_key: &UnifiedPublicEncKey,
510+
client_enc_key_bytes: &[u8],
510511
client_address: &alloy_primitives::Address,
511512
server_verf_key: Vec<u8>,
512513
domain: &alloy_sol_types::Eip712Domain,
@@ -518,6 +519,10 @@ pub async fn async_user_decrypt<
518519
metrics_names::{OP_USER_DECRYPT_INNER, TAG_TFHE_TYPE},
519520
};
520521

522+
// LEGACY CODE: see `from_legacy_bytes` for docs
523+
let client_enc_key = UnifiedPublicEncKey::from_legacy_bytes(client_enc_key_bytes)
524+
.map_err(|e| anyhow::anyhow!("Error deserializing UnifiedPublicEncKey: {e}"))?;
525+
521526
let mut all_signcrypted_cts = vec![];
522527
for typed_ciphertext in typed_ciphertexts {
523528
let mut inner_timer = metrics::METRICS
@@ -538,7 +543,7 @@ pub async fn async_user_decrypt<
538543
fhe_type,
539544
ct_format,
540545
req_digest,
541-
client_enc_key,
546+
&client_enc_key,
542547
client_address.as_ref(),
543548
)?;
544549
all_signcrypted_cts.push(TypedSigncryptedCiphertext {
@@ -562,7 +567,7 @@ pub async fn async_user_decrypt<
562567
sig_key,
563568
&payload,
564569
domain,
565-
client_enc_key,
570+
client_enc_key_bytes,
566571
extra_data,
567572
)?;
568573

core/service/src/engine/centralized/service/decryption.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub async fn user_decrypt_impl<
4747
let (
4848
typed_ciphertexts,
4949
link,
50-
client_enc_key,
50+
client_enc_key_bytes,
5151
client_address,
5252
request_id,
5353
key_id,
@@ -152,7 +152,7 @@ pub async fn user_decrypt_impl<
152152
&mut rng,
153153
&typed_ciphertexts,
154154
&link,
155-
&client_enc_key,
155+
&client_enc_key_bytes,
156156
&client_address,
157157
server_verf_key,
158158
&domain,

core/service/src/engine/threshold/service/user_decryptor.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ use crate::{
5252
anyhow_error_and_log,
5353
cryptography::{
5454
compute_external_user_decrypt_signature,
55+
encryption::UnifiedPublicEncKey,
5556
error::CryptographyError,
5657
internal_crypto_types::LegacySerialization,
5758
signcryption::{SigncryptFHEPlaintext, UnifiedSigncryptionKeyOwned},
@@ -169,6 +170,12 @@ impl<
169170
///
170171
/// This function does not perform user decryption in a background thread.
171172
/// The return type should be [UserDecryptCallValues] except the final item in the tuple
173+
///
174+
/// Note that the argument `client_enc_key_bytes` must be the original
175+
/// bytes that was provided by the user, it should not go through any re-serialization.
176+
/// The same information is in `signcryption_key.receiver_enc_key` but in there it is
177+
/// already serialized, that's why the original bytes representation is still needed
178+
/// for signing later on.
172179
#[allow(clippy::too_many_arguments)]
173180
async fn inner_user_decrypt(
174181
req_id: &RequestId,
@@ -179,6 +186,7 @@ impl<
179186
typed_ciphertexts: Vec<TypedCiphertext>,
180187
link: Vec<u8>,
181188
signcryption_key: Arc<UnifiedSigncryptionKeyOwned>,
189+
client_enc_key_bytes_orig: Vec<u8>,
182190
fhe_keys: OwnedRwLockReadGuard<
183191
HashMap<(RequestId, EpochId), ThresholdFheKeys>,
184192
ThresholdFheKeys,
@@ -384,7 +392,7 @@ impl<
384392
&signcryption_key.signing_key,
385393
&payload,
386394
domain,
387-
&signcryption_key.receiver_enc_key,
395+
&client_enc_key_bytes_orig,
388396
&extra_data,
389397
)?;
390398
Ok((payload, external_signature, extra_data))
@@ -456,7 +464,7 @@ impl<
456464
let (
457465
typed_ciphertexts,
458466
link,
459-
client_enc_key,
467+
client_enc_key_bytes_orig, // the original bytes for the encryption key
460468
client_address,
461469
req_id,
462470
key_id,
@@ -506,6 +514,15 @@ impl<
506514
)
507515
})?)
508516
.clone();
517+
let client_enc_key = UnifiedPublicEncKey::from_legacy_bytes(&client_enc_key_bytes_orig)
518+
.map_err(|e| {
519+
MetricedError::new(
520+
OP_USER_DECRYPT_REQUEST,
521+
Some(req_id),
522+
anyhow::anyhow!("Error deserializing UnifiedPublicEncKey: {e}"),
523+
tonic::Code::Internal,
524+
)
525+
})?;
509526
let signcryption_key = Arc::new(UnifiedSigncryptionKeyOwned::new(
510527
sk,
511528
client_enc_key,
@@ -543,6 +560,7 @@ impl<
543560
typed_ciphertexts,
544561
link,
545562
signcryption_key,
563+
client_enc_key_bytes_orig,
546564
fhe_keys_rlock,
547565
dec_mode,
548566
&domain,

core/service/src/engine/validation_non_wasm.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ pub(crate) fn validate_user_decrypt_req(
186186
(
187187
Vec<TypedCiphertext>,
188188
Vec<u8>,
189-
UnifiedPublicEncKey,
189+
Vec<u8>,
190190
alloy_primitives::Address,
191191
RequestId,
192192
KeyId,
@@ -214,7 +214,7 @@ fn unpack_user_decrypt_req(
214214
(
215215
Vec<TypedCiphertext>,
216216
Vec<u8>,
217-
UnifiedPublicEncKey,
217+
Vec<u8>,
218218
alloy_primitives::Address,
219219
RequestId,
220220
KeyId,
@@ -261,15 +261,17 @@ fn unpack_user_decrypt_req(
261261
};
262262

263263
let (link, _) = req.compute_link_checked()?;
264-
let client_enc_key = UnifiedPublicEncKey::from_legacy_bytes(&req.enc_key).map_err(|e| {
264+
// Deserialize to validate the enc_key bytes, but don't return the typed key —
265+
// callers use raw bytes for EIP-712 and deserialize at point-of-use for crypto.
266+
let _client_enc_key = UnifiedPublicEncKey::from_legacy_bytes(&req.enc_key).map_err(|e| {
265267
Into::<Box<dyn std::error::Error + Send + Sync>>::into(anyhow::anyhow!(
266268
"Error deserializing UnifiedPublicEncKey from UserDecryptionRequest: {e}"
267269
))
268270
})?;
269271
Ok((
270272
req.typed_ciphertexts.clone(),
271273
link,
272-
client_enc_key,
274+
req.enc_key.clone(),
273275
client_verf_key,
274276
request_id,
275277
key_id,

0 commit comments

Comments
 (0)