Skip to content

Commit

Permalink
feat(tfhe): plug zk-pok into all layers
Browse files Browse the repository at this point in the history
  • Loading branch information
tmontaigu authored and IceTDrinker committed Apr 8, 2024
1 parent 89d586c commit a67f6a6
Show file tree
Hide file tree
Showing 73 changed files with 4,485 additions and 331 deletions.
32 changes: 20 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,18 @@ fmt_gpu: install_rs_check_toolchain
cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" fmt
cd "$(TFHECUDA_SRC)" && ./format_tfhe_cuda_backend.sh

.PHONY: fmt_c_tests # Format c tests
fmt_c_tests:
find tfhe/c_api_tests/ -regex '.*\.\(cpp\|hpp\|cu\|c\|h\)' -exec clang-format -style=file -i {} \;

.PHONY: check_fmt # Check rust code format
check_fmt: install_rs_check_toolchain
cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" fmt --check

.PHONY: check_fmt_c_tests # Check C tests format
check_fmt_c_tests:
find tfhe/c_api_tests/ -regex '.*\.\(cpp\|hpp\|cu\|c\|h\)' -exec clang-format --dry-run --Werror -style=file {} \;

.PHONY: check_fmt_gpu # Check rust and cuda code format
check_fmt_gpu: install_rs_check_toolchain
cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" fmt --check
Expand Down Expand Up @@ -274,7 +282,7 @@ clippy_trivium: install_rs_check_toolchain
.PHONY: clippy_all_targets # Run clippy lints on all targets (benches, examples, etc.)
clippy_all_targets:
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,zk-pok-experimental \
-p $(TFHE_SPEC) -- --no-deps -D warnings

.PHONY: clippy_concrete_csprng # Run clippy lints on concrete-csprng
Expand Down Expand Up @@ -353,14 +361,14 @@ symlink_c_libs_without_fingerprint:
.PHONY: build_c_api # Build the C API for boolean, shortint and integer
build_c_api: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,$(FORWARD_COMPAT_FEATURE) \
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,zk-pok-experimental,$(FORWARD_COMPAT_FEATURE) \
-p $(TFHE_SPEC)
@"$(MAKE)" symlink_c_libs_without_fingerprint

.PHONY: build_c_api_gpu # Build the C API for boolean, shortint and integer
build_c_api_gpu: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,gpu \
--features=$(TARGET_ARCH_FEATURE),boolean-c-api,shortint-c-api,high-level-c-api,zk-pok-experimental,gpu \
-p $(TFHE_SPEC)
@"$(MAKE)" symlink_c_libs_without_fingerprint

Expand All @@ -376,23 +384,23 @@ build_web_js_api: install_rs_build_toolchain install_wasm_pack
cd tfhe && \
RUSTFLAGS="$(WASM_RUSTFLAGS)" rustup run "$(RS_BUILD_TOOLCHAIN)" \
wasm-pack build --release --target=web \
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api,zk-pok-experimental

.PHONY: build_web_js_api_parallel # Build the js API targeting the web browser with parallelism support
build_web_js_api_parallel: install_rs_check_toolchain install_wasm_pack
cd tfhe && \
rustup component add rust-src --toolchain $(RS_CHECK_TOOLCHAIN) && \
RUSTFLAGS="$(WASM_RUSTFLAGS) -C target-feature=+atomics,+bulk-memory,+mutable-globals" rustup run $(RS_CHECK_TOOLCHAIN) \
wasm-pack build --release --target=web \
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api,parallel-wasm-api \
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api,parallel-wasm-api,zk-pok-experimental \
-Z build-std=panic_abort,std

.PHONY: build_node_js_api # Build the js API targeting nodejs
build_node_js_api: install_rs_build_toolchain install_wasm_pack
cd tfhe && \
RUSTFLAGS="$(WASM_RUSTFLAGS)" rustup run "$(RS_BUILD_TOOLCHAIN)" \
wasm-pack build --release --target=nodejs \
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api,integer-client-js-wasm-api,zk-pok-experimental

.PHONY: build_concrete_csprng # Build concrete_csprng
build_concrete_csprng: install_rs_build_toolchain
Expand All @@ -402,10 +410,10 @@ build_concrete_csprng: install_rs_build_toolchain
.PHONY: test_core_crypto # Run the tests of the core_crypto module including experimental ones
test_core_crypto: install_rs_build_toolchain install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
--features=$(TARGET_ARCH_FEATURE),experimental -p $(TFHE_SPEC) -- core_crypto::
--features=$(TARGET_ARCH_FEATURE),experimental,zk-pok-experimental -p $(TFHE_SPEC) -- core_crypto::
@if [[ "$(AVX512_SUPPORT)" == "ON" ]]; then \
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
--features=$(TARGET_ARCH_FEATURE),experimental,$(AVX512_FEATURE) -p $(TFHE_SPEC) -- core_crypto::; \
--features=$(TARGET_ARCH_FEATURE),experimental,zk-pok-experimental,$(AVX512_FEATURE) -p $(TFHE_SPEC) -- core_crypto::; \
fi

.PHONY: test_core_crypto_cov # Run the tests of the core_crypto module with code coverage
Expand Down Expand Up @@ -576,7 +584,7 @@ test_integer_cov: install_rs_check_toolchain install_tarpaulin
.PHONY: test_high_level_api # Run all the tests for high_level_api
test_high_level_api: install_rs_build_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p $(TFHE_SPEC) \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,zk-pok-experimental -p $(TFHE_SPEC) \
-- high_level_api::

test_high_level_api_gpu: install_rs_build_toolchain install_cargo_nextest
Expand All @@ -587,14 +595,14 @@ test_high_level_api_gpu: install_rs_build_toolchain install_cargo_nextest
.PHONY: test_user_doc # Run tests from the .md documentation
test_user_doc: install_rs_build_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) --doc \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,pbs-stats \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,pbs-stats,zk-pok-experimental \
-p $(TFHE_SPEC) \
-- test_user_docs::

.PHONY: test_user_doc_gpu # Run tests for GPU from the .md documentation
test_user_doc_gpu: install_rs_build_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) --doc \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,gpu -p $(TFHE_SPEC) \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache,gpu,zk-pok-experimental -p $(TFHE_SPEC) \
-- test_user_docs::

.PHONY: test_fhe_strings # Run tests for fhe_strings example
Expand Down Expand Up @@ -633,7 +641,7 @@ test_concrete_csprng:
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
--features=$(TARGET_ARCH_FEATURE) -p concrete-csprng

.PHONY: test_zk_pok # Run tfhe-zk-pok tests
.PHONY: test_zk_pok # Run tfhe-zk-pok-experimental tests
test_zk_pok:
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
-p tfhe-zk-pok
Expand Down
2 changes: 1 addition & 1 deletion scripts/integer-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ cargo "${RUST_TOOLCHAIN}" nextest run \
--cargo-profile "${cargo_profile}" \
--package "${tfhe_package}" \
--profile ci \
--features="${ARCH_FEATURE}",integer,internal-keycache,"${avx512_feature}" \
--features="${ARCH_FEATURE}",integer,internal-keycache,zk-pok-experimental,"${avx512_feature}" \
--test-threads "${test_threads}" \
-E "$filter_expression"

Expand Down
2 changes: 1 addition & 1 deletion scripts/shortint-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ and not test(~smart_add_and_mul)""" # This test is too slow
--cargo-profile "${cargo_profile}" \
--package "${tfhe_package}" \
--profile ci \
--features="${ARCH_FEATURE}",shortint,internal-keycache \
--features="${ARCH_FEATURE}",shortint,internal-keycache,zk-pok-experimental \
--test-threads "${n_threads_small}" \
-E "${filter_expression_small_params}"

Expand Down
36 changes: 13 additions & 23 deletions tfhe-zk-pok/src/proofs/pke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ impl<G: Curve> PublicParams<G> {
}
}

#[allow(dead_code)]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct PrivateParams<G: Curve> {
alpha: G::Zp,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct Proof<G: Curve> {
c_hat: G::G2,
Expand Down Expand Up @@ -104,27 +98,24 @@ pub fn crs_gen<G: Curve>(
q: u64,
t: u64,
rng: &mut dyn RngCore,
) -> (PublicParams<G>, PrivateParams<G>) {
) -> PublicParams<G> {
let alpha = G::Zp::rand(rng);
let b_r = d as u64 / 2 + 1;

let big_d =
d + k * t.ilog2() as usize + (d + k) * (2 + b.ilog2() as usize + b_r.ilog2() as usize);
let n = big_d + 1;
(
PublicParams {
g_lists: GroupElements::<G>::new(n, alpha),
big_d,
n,
d,
k,
b,
b_r,
q,
t,
},
PrivateParams { alpha },
)
PublicParams {
g_lists: GroupElements::<G>::new(n, alpha),
big_d,
n,
d,
k,
b,
b_r,
q,
t,
}
}

#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -990,8 +981,7 @@ mod tests {
m_roundtrip[i] = result;
}

let (public_param, _private_param) =
crs_gen::<crate::curve_api::Bls12_446>(d, k, b_i, q, t, rng);
let public_param = crs_gen::<crate::curve_api::Bls12_446>(d, k, b_i, q, t, rng);

for use_fake_e1 in [false, true] {
for use_fake_e2 in [false, true] {
Expand Down
3 changes: 3 additions & 0 deletions tfhe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ paste = "1.0.7"
fs2 = { version = "0.4.3", optional = true }
# While we wait for repeat_n in rust standard library
itertools = "0.11.0"
rand_core = { version = "0.6.4", features = ["std"] }
tfhe-zk-pok = { version = "0.1.0", path = "../tfhe-zk-pok", optional = true }

# wasm deps
wasm-bindgen = { version = "0.2.86", features = [
Expand All @@ -87,6 +89,7 @@ shortint = []
integer = ["shortint"]
internal-keycache = ["dep:lazy_static", "dep:fs2"]
gpu = ["tfhe-cuda-backend"]
zk-pok-experimental = ["dep:tfhe-zk-pok"]

pbs-stats = []

Expand Down
2 changes: 2 additions & 0 deletions tfhe/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ fn gen_c_api() {
"integer",
#[cfg(feature = "gpu")]
"gpu",
#[cfg(feature = "zk-pok-experimental")]
"zk-pok-experimental",
];

let parse_expand_vec = if parse_expand_features_vec.is_empty() {
Expand Down
109 changes: 109 additions & 0 deletions tfhe/c_api_tests/test_high_level_zk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "tfhe.h"
#include <assert.h>
#include <stdlib.h>
#include <tfhe.h>

int main(void) {
// We want to use zk-proof, which requires bounded random distributions
// tfhe-rs has the `TUniform` as an available bounded distribution.

// Note that simply changing parameters like this does not yield secure parameters
// Its only done for the example / tests
ShortintPBSParameters params = SHORTINT_PARAM_MESSAGE_2_CARRY_2_KS_PBS;
params.glwe_noise_distribution = new_t_uniform(9);
assert(params.encryption_key_choice == ShortintEncryptionKeyChoiceBig);

int status;

ConfigBuilder *builder;
status = config_builder_default(&builder);
assert(status == 0);
status = config_builder_use_custom_parameters(&builder, params);
assert(status == 0);

Config *config;
status = config_builder_build(builder, &config);
assert(status == 0);

// Compute the CRS
// Note that we do that before generating the client key
// as client_key_generate thakes ownership of the config
CompactPkeCrs *crs;
size_t max_num_bits = 32;
status = compact_pke_crs_from_config(config, max_num_bits, &crs);
assert(status == 0);

CompactPkePublicParams *public_params;
status = compact_pke_crs_public_params(crs, &public_params);
assert(status == 0);

ClientKey *client_key;
status = client_key_generate(config, &client_key);
assert(status == 0);

// zk proofs of encryption works only using the CompactPublicKey
CompactPublicKey *pk;
status = compact_public_key_new(client_key, &pk);
assert(status == 0);

// Demo of ProvenCompactFheUint32
{
uint32_t msg = 8328937;
ProvenCompactFheUint32 *proven_fhe_uint;
status = proven_compact_fhe_uint32_try_encrypt(msg, public_params, pk, ZkComputeLoadProof,
&proven_fhe_uint);
assert(status == 0);

FheUint32 *fhe_uint;
// This function does not take ownership of the proven fhe uint, so we have to cleanup later
status =
proven_compact_fhe_uint32_verify_and_expand(proven_fhe_uint, public_params, pk, &fhe_uint);
assert(status == 0);

uint32_t decrypted;
status = fhe_uint32_decrypt(fhe_uint, client_key, &decrypted);
assert(status == 0);

assert(decrypted == msg);
fhe_uint32_destroy(fhe_uint);
proven_compact_fhe_uint32_destroy(proven_fhe_uint);
}

// Demo of ProvenCompactFheUint32List
{
uint32_t msgs[4] = {8328937, 217521191, 2753219039, 91099540};
ProvenCompactFheUint32List *proven_fhe_list;
status = proven_compact_fhe_uint32_list_try_encrypt(msgs, 4, public_params, pk,
ZkComputeLoadProof, &proven_fhe_list);
assert(status == 0);

size_t list_len;
status = proven_compact_fhe_uint32_list_len(proven_fhe_list, &list_len);
assert(status == 0);
assert(list_len == 4);

FheUint32 *fhe_uints[4];
// This function does not take ownership of the proven fhe uint, so we have to cleanup later
status = proven_compact_fhe_uint32_list_verify_and_expand(proven_fhe_list, public_params, pk,
&fhe_uints[0], 4);
assert(status == 0);

for (size_t i = 0; i < 4; ++i) {
uint32_t decrypted;
status = fhe_uint32_decrypt(fhe_uints[i], client_key, &decrypted);
assert(status == 0);

assert(decrypted == msgs[i]);
fhe_uint32_destroy(fhe_uints[i]);
}

proven_compact_fhe_uint32_list_destroy(proven_fhe_list);
}

compact_pke_public_params_destroy(public_params);
compact_pke_crs_destroy(crs);
compact_public_key_destroy(pk);
client_key_destroy(client_key);

return EXIT_SUCCESS;
}
2 changes: 2 additions & 0 deletions tfhe/docs/guides/public_key.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ fn main() {

This example shows how to use compact public keys. The main difference is in the ConfigBuilder, where the parameter set has been changed.

See [the guide on ZK proofs](zk-pok.md) to see how to encrypt data using compact public keys and generate a zero knowledge proof of correct encryption at the same time.

```rust
use tfhe::prelude::*;
use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8, CompactPublicKey};
Expand Down
Loading

0 comments on commit a67f6a6

Please sign in to comment.