Skip to content

Commit

Permalink
feat(zk)!: plug zk v2
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
- The object ZkVerificationOutCome has been renamed ZkVerificationOutcome.
- Conformance of proofs now checks the scheme version of the CRS. This is
breaking at the shortint and core_crypto levels, and for manually built integer
conformance params.

New CRS will be generated with the V2 Scheme by default, but V1 CRS and proofs
are still accepted, so this is not breaking. New methods have been added to
generate a V1 CRS.
  • Loading branch information
nsarlin-zama committed Dec 4, 2024
1 parent 0f14984 commit 74813d9
Show file tree
Hide file tree
Showing 16 changed files with 1,055 additions and 749 deletions.
11 changes: 2 additions & 9 deletions tfhe/src/c_api/high_level_api/zk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@ impl From<ZkComputeLoad> for crate::zk::ZkComputeLoad {
pub struct CompactPkeCrs(pub(crate) crate::core_crypto::entities::CompactPkeCrs);
impl_destroy_on_type!(CompactPkeCrs);

// Because we use a repr(transparent) for the CompactPkeCrs, cbindgen will define CompactPkeCrs as
// an alias for CompactPkePublicParams. We need to define this struct even if it will not actually
// be used in the C api.
#[allow(unused)]
pub struct CompactPkePublicParams(pub(crate) crate::core_crypto::entities::CompactPkePublicParams);
impl_destroy_on_type!(CompactPkePublicParams);

/// Serializes the CRS
///
/// If compress is true, the data will be compressed (less serialized bytes), however, this makes
Expand Down Expand Up @@ -144,7 +137,7 @@ pub unsafe extern "C" fn compact_pke_crs_deserialize_from_params(

*result = std::ptr::null_mut();

let deserialized: crate::core_crypto::entities::CompactPkePublicParams =
let deserialized: crate::core_crypto::entities::ZkCompactPkeV1PublicParams =
bincode::deserialize(buffer_view.as_slice()).unwrap();
let crs = deserialized.into();

Expand All @@ -170,7 +163,7 @@ pub unsafe extern "C" fn compact_pke_crs_safe_deserialize_from_params(

let buffer_view: &[u8] = buffer_view.as_slice();

let deserialized: crate::core_crypto::entities::CompactPkePublicParams =
let deserialized: crate::core_crypto::entities::ZkCompactPkeV1PublicParams =
crate::safe_serialization::DeserializationConfig::new(serialized_size_limit)
.disable_conformance()
.deserialize_from(buffer_view)
Expand Down
208 changes: 35 additions & 173 deletions tfhe/src/core_crypto/algorithms/lwe_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ use crate::core_crypto::commons::parameters::*;
use crate::core_crypto::commons::traits::*;
use crate::core_crypto::entities::*;
use rayon::prelude::*;
#[cfg(feature = "zk-pok")]
use tfhe_zk_pok::proofs::pke::{commit, prove};

/// Convenience function to share the core logic of the LWE encryption between all functions needing
/// it.
Expand Down Expand Up @@ -1858,8 +1856,7 @@ where
BodyDistribution: BoundedDistribution<Scalar::Signed>,
KeyCont: Container<Element = Scalar>,
{
let public_params = crs.public_params();
let exclusive_max = public_params.exclusive_max_noise();
let exclusive_max = crs.exclusive_max_noise();
if Scalar::BITS < 64 && (1u64 << Scalar::BITS) >= exclusive_max {
return Err(
"The given random distribution would create random values out \
Expand Down Expand Up @@ -1893,39 +1890,34 @@ where
return Err("Zero knowledge proof do not support moduli greater than 2**64".into());
}

let expected_q = if Scalar::BITS == 64 {
0u64
} else {
164 << Scalar::BITS
};

if expected_q != public_params.q {
if ciphertext_modulus != crs.ciphertext_modulus() {
return Err("Mismatched modulus between CRS and ciphertexts".into());
}

if ciphertext_count.0 > public_params.k {
if ciphertext_count > crs.max_num_messages() {
return Err(format!(
"CRS allows at most {} ciphertexts to be proven at once, {} contained in the list",
public_params.k, ciphertext_count.0
crs.max_num_messages().0,
ciphertext_count.0
)
.into());
}

if lwe_compact_public_key.lwe_dimension().0 > public_params.d {
if lwe_compact_public_key.lwe_dimension() > crs.lwe_dimension() {
return Err(format!(
"CRS allows a LweDimension of at most {}, current dimension: {}",
public_params.d,
crs.lwe_dimension().0,
lwe_compact_public_key.lwe_dimension().0
)
.into());
}

// 2**64 /delta == ((2**63) / delta) *2
let plaintext_modulus = ((1u64 << (u64::BITS - 1) as usize) / u64::cast_from(delta)) * 2;
if plaintext_modulus != public_params.t {
if plaintext_modulus != crs.plaintext_modulus() {
return Err(format!(
"Mismatched plaintext modulus: CRS expects {}, requested modulus: {plaintext_modulus:?}",
public_params.t
crs.plaintext_modulus()
).into());
}

Expand Down Expand Up @@ -2291,52 +2283,18 @@ where
encryption_generator,
);

let (c1, c2) = output.get_mask_and_body();

let (public_commit, private_commit) = commit(
lwe_compact_public_key
.get_mask()
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
lwe_compact_public_key
.get_body()
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
c1.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
vec![i64::cast_from(*c2.data)],
binary_random_vector
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
mask_noise
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
vec![i64::cast_from(message.0)],
body_noise
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
crs.public_params(),
random_generator,
);

Ok(prove(
(crs.public_params(), &public_commit),
&private_commit,
Ok(crs.prove(
lwe_compact_public_key,
&vec![message.0],
&LweCompactCiphertextList::from_container(
output.as_ref(),
output.lwe_size(),
LweCiphertextCount(1),
output.ciphertext_modulus(),
),
&binary_random_vector,
&mask_noise,
&body_noise,
metadata,
load,
random_generator,
Expand Down Expand Up @@ -2807,61 +2765,13 @@ where
encryption_generator,
);

let (c1, c2) = output.get_mask_and_body_list();

let (public_commit, private_commit) = commit(
lwe_compact_public_key
.get_mask()
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
lwe_compact_public_key
.get_body()
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
c1.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
c2.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
binary_random_vector
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
mask_noise
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
messages
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
body_noise
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
crs.public_params(),
random_generator,
);

Ok(prove(
(crs.public_params(), &public_commit),
&private_commit,
Ok(crs.prove(
lwe_compact_public_key,
messages,
output,
&binary_random_vector,
&mask_noise,
&body_noise,
metadata,
load,
random_generator,
Expand Down Expand Up @@ -3341,61 +3251,13 @@ where
encryption_generator,
);

let (c1, c2) = output.get_mask_and_body_list();

let (public_commit, private_commit) = commit(
lwe_compact_public_key
.get_mask()
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
lwe_compact_public_key
.get_body()
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
c1.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
c2.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
binary_random_vector
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
mask_noise
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
messages
.as_ref()
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
body_noise
.iter()
.copied()
.map(CastFrom::cast_from)
.collect::<Vec<_>>(),
crs.public_params(),
random_generator,
);

Ok(prove(
(crs.public_params(), &public_commit),
&private_commit,
Ok(crs.prove(
lwe_compact_public_key,
messages,
output,
&binary_random_vector,
&mask_noise,
&body_noise,
metadata,
load,
random_generator,
Expand Down
Loading

0 comments on commit 74813d9

Please sign in to comment.