fix(integer): check overflows when computing expected list size

This commit is contained in:
Nicolas Sarlin
2025-12-04 11:19:29 +01:00
committed by Nicolas Sarlin
parent c7b869c956
commit d98033c71d
2 changed files with 37 additions and 8 deletions

View File

@@ -430,10 +430,10 @@ impl ParameterSetConformant for CompactCiphertextList {
return false;
}
let total_expected_num_blocks: usize = info
.iter()
.map(|a| a.num_blocks(self.message_modulus()))
.sum();
let Ok(total_expected_num_blocks) = self.expected_num_block() else {
// Return early if the sum overflowed
return false;
};
let total_expected_lwe_count = if is_packed {
total_expected_num_blocks.div_ceil(2)
@@ -1001,6 +1001,13 @@ impl CompactCiphertextList {
pub fn message_modulus(&self) -> MessageModulus {
self.ct_list.message_modulus
}
/// Computes the expected number of blocks based on the `info` metadata.
///
/// Returns an error if the sum overflows
fn expected_num_block(&self) -> Result<usize, ()> {
DataKind::total_block_count(&self.info, self.message_modulus())
}
}
#[cfg(feature = "zk-pok")]
@@ -1127,6 +1134,13 @@ impl ProvenCompactCiphertextList {
pub fn get_kind_of(&self, index: usize) -> Option<DataKind> {
self.info.get(index).copied()
}
/// Computes the expected number of blocks based on the `info` metadata.
///
/// Returns an error if the sum overflows
fn expected_num_block(&self) -> Result<usize, ()> {
DataKind::total_block_count(&self.info, self.message_modulus())
}
}
#[cfg(feature = "zk-pok")]
@@ -1233,10 +1247,10 @@ impl ParameterSetConformant for ProvenCompactCiphertextList {
return false;
}
let total_expected_num_blocks: usize = info
.iter()
.map(|a| a.num_blocks(self.message_modulus()))
.sum();
let Ok(total_expected_num_blocks) = self.expected_num_block() else {
// Return early if the sum overflowed
return false;
};
let total_expected_lwe_count = if is_packed {
total_expected_num_blocks.div_ceil(2)

View File

@@ -30,6 +30,21 @@ impl DataKind {
}
}
}
pub(crate) fn total_block_count(
info: &[Self],
message_modulus: MessageModulus,
) -> Result<usize, ()> {
if message_modulus.0 == 0 {
return Err(());
}
info.iter()
.try_fold(0usize, |acc, &x| {
acc.checked_add(x.num_blocks(message_modulus))
})
.ok_or(())
}
}
pub trait Expandable: Sized {