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

This commit is contained in:
Arthur Meyre
2024-08-27 13:30:37 +02:00
parent ce9e355c15
commit 26055b236e
4 changed files with 67 additions and 10 deletions

View File

@@ -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 }

View File

@@ -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.
});

View File

@@ -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);

View File

@@ -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,
@@ -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;
@@ -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));
@@ -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() {
@@ -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;
@@ -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));
@@ -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() {
@@ -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);
@@ -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);
}
{
@@ -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]);
}
}