Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tfhe): allow unpacking packed compact ciphertext lists in js/wasm #1509

Merged
merged 2 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/aws_tfhe_wasm_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ jobs:
make test_nodejs_wasm_api_in_docker
- name: Run parallel wasm tests
timeout-minutes: 60
run: |
make test_web_js_api_parallel_ci
Expand Down
2 changes: 1 addition & 1 deletion tfhe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ lazy_static = { version = "1.4.0", optional = true }
serde = { version = "1.0", features = ["derive"] }
rayon = { version = "1.5.0" }
bincode = "1.3.3"
concrete-fft = { version = "0.5.0", features = ["serde", "fft128"] }
concrete-fft = { version = "0.5.1", features = ["serde", "fft128"] }
concrete-ntt = { version = "0.2.0" }
pulp = "0.18.22"
tfhe-cuda-backend = { version = "0.4.0-alpha.0", path = "../backends/tfhe-cuda-backend", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion tfhe/js_on_wasm_tests/test-hlapi-signed.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,5 +520,5 @@ test('hlapi_compact_ciphertext_list_with_proof', (t) => {
assert.deepStrictEqual(deserialized.get_kind_of(2), FheTypes.Bool);
assert.deepStrictEqual(deserialized.get_kind_of(3), FheTypes.Uint256);

// We cannot verify packed ZK in wasm
// Verifying and expanding is too slow for single threaded node tests.
});
19 changes: 19 additions & 0 deletions tfhe/src/js_on_wasm_api/js_high_level_api/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ impl TfheCompressedServerKey {
}
}

#[wasm_bindgen]
pub struct TfheServerKey(pub(crate) hlapi::ServerKey);

#[wasm_bindgen]
impl TfheServerKey {
#[wasm_bindgen]
pub fn new(client_key: &TfheClientKey) -> Result<TfheServerKey, JsError> {
catch_panic_result(|| Ok(Self(hlapi::ServerKey::new(&client_key.0))))
}
}

#[wasm_bindgen]
pub fn set_server_key(server_key: &TfheServerKey) -> Result<(), JsError> {
catch_panic_result(|| {
crate::set_server_key(server_key.0.clone());
Ok(())
})
}

#[wasm_bindgen]
pub struct TfhePublicKey(pub(crate) hlapi::PublicKey);

Expand Down
4 changes: 2 additions & 2 deletions tfhe/web_wasm_parallel_tests/test/compact-public-key.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ it(
async () => {
await runTestAttachedToButton("compactPublicKeyZeroKnowledge");
},
1200 * 1000,
); // 20 minutes timeout
3600 * 1000,
); // 60 minutes timeout

it(
"Compact Public Key Bench 64 Bit With ZeroKnowledge",
Expand Down
54 changes: 46 additions & 8 deletions tfhe/web_wasm_parallel_tests/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import * as Comlink from "comlink";
import init, {
initThreadPool,
init_panic_hook,
set_server_key,
ShortintParametersName,
ShortintParameters,
TfheClientKey,
TfhePublicKey,
TfheServerKey,
TfheCompressedPublicKey,
TfheCompressedServerKey,
TfheCompressedCompactPublicKey,
Expand Down Expand Up @@ -254,8 +256,11 @@ async function compactPublicKeyWithCastingTest256Bit() {
.build();

let clientKey = TfheClientKey.generate(config);
let serverKey = TfheServerKey.new(clientKey);
let publicKey = TfheCompactPublicKey.new(clientKey);

set_server_key(serverKey);

let clear_u2 = 3;
let clear_i32 = -3284;
let clear_bool = true;
Expand All @@ -271,7 +276,7 @@ async function compactPublicKeyWithCastingTest256Bit() {
console.log("Numb bits in compact list: ", num_bits_encrypted);

console.time("CompactCiphertextList Encrypt");
let list = builder.build();
let list = builder.build_packed();
console.timeEnd("CompactCiphertextList Encrypt");

let serialized = list.safe_serialize(BigInt(10000000));
Expand All @@ -281,7 +286,15 @@ async function compactPublicKeyWithCastingTest256Bit() {
BigInt(10000000),
);

// Cannot expand
let expander = deserialized.expand();

assert_eq(expander.get_uint2(0).decrypt(clientKey), clear_u2);

assert_eq(expander.get_int32(1).decrypt(clientKey), clear_i32);

assert_eq(expander.get_bool(2).decrypt(clientKey), clear_bool);

assert_eq(expander.get_uint256(3).decrypt(clientKey), clear_u256);
}

async function compressedCompactPublicKeyWithCastingTest256Bit() {
Expand All @@ -298,9 +311,12 @@ async function compressedCompactPublicKeyWithCastingTest256Bit() {
.build();

let clientKey = TfheClientKey.generate(config);
let serverKey = TfheServerKey.new(clientKey);
let compressedPublicKey = TfheCompressedCompactPublicKey.new(clientKey);
let publicKey = compressedPublicKey.decompress();

set_server_key(serverKey);

let clear_u2 = 3;
let clear_i32 = -3284;
let clear_bool = true;
Expand All @@ -316,7 +332,7 @@ async function compressedCompactPublicKeyWithCastingTest256Bit() {
console.log("Numb bits in compact list: ", num_bits_encrypted);

console.time("CompactCiphertextList Encrypt");
let list = builder.build();
let list = builder.build_packed();
console.timeEnd("CompactCiphertextList Encrypt");

let serialized = list.safe_serialize(BigInt(10000000));
Expand All @@ -326,7 +342,15 @@ async function compressedCompactPublicKeyWithCastingTest256Bit() {
BigInt(10000000),
);

// Cannot expand
let expander = deserialized.expand();

assert_eq(expander.get_uint2(0).decrypt(clientKey), clear_u2);

assert_eq(expander.get_int32(1).decrypt(clientKey), clear_i32);

assert_eq(expander.get_bool(2).decrypt(clientKey), clear_bool);

assert_eq(expander.get_uint256(3).decrypt(clientKey), clear_u256);
}

async function compactPublicKeyZeroKnowledge() {
Expand All @@ -343,8 +367,11 @@ async function compactPublicKeyZeroKnowledge() {
.build();

let clientKey = TfheClientKey.generate(config);
let serverKey = TfheServerKey.new(clientKey);
let publicKey = TfheCompactPublicKey.new(clientKey);

set_server_key(serverKey);

console.log("Start CRS generation");
console.time("CRS generation");
let crs = CompactPkeCrs.from_config(config, 4 * 64);
Expand All @@ -368,10 +395,13 @@ async function compactPublicKeyZeroKnowledge() {
" ms",
);

let bytes = list.serialize();
console.log("CompactCiphertextList size:", bytes.length);
let serialized = list.serialize();
console.log("CompactCiphertextList size:", serialized.length);
let deserialized = ProvenCompactCiphertextList.deserialize(serialized);

// We cannot expand a packed list in WASM
let expander = deserialized.verify_and_expand(public_params, publicKey);

assert_eq(expander.get_uint64(0).decrypt(clientKey), input);
}

{
Expand All @@ -397,7 +427,15 @@ async function compactPublicKeyZeroKnowledge() {
" ms",
);

// We cannot expand a packed list in WASM
let expander = encrypted.verify_and_expand(public_params, publicKey);

assert_eq(expander.get_uint64(0).decrypt(clientKey), inputs[0]);

assert_eq(expander.get_uint64(1).decrypt(clientKey), inputs[1]);

assert_eq(expander.get_uint64(2).decrypt(clientKey), inputs[2]);

assert_eq(expander.get_uint64(3).decrypt(clientKey), inputs[3]);
}
}

Expand Down
Loading