Skip to content

Commit 55edcfd

Browse files
committed
docs(gpu): add documentation about GPU's accelerated expand on the HL API
1 parent 7d827d5 commit 55edcfd

File tree

1 file changed

+81
-0
lines changed
  • tfhe/docs/configuration/gpu_acceleration

1 file changed

+81
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Zero-knowledge proofs
2+
3+
Zero-knowledge proofs (ZK) are a powerful tool to assert that the encryption of a message is correct, as discussed in [advanced features](../../fhe-computation/advanced-features/zk-pok.md).
4+
However, computation is not possible on verifiable ciphertexts. This document explains how to use the GPU to accelerate the
5+
preprocessing step needed to convert formatted for ZK to ciphertexts in the right format for computation purposes on GPU. This
6+
operation is called "expansion".
7+
8+
## Proven compact ciphertext list
9+
10+
A proven compact list of ciphertexts can be seen as a compacted collection of ciphertexts which encryption can be verified.
11+
This verification is currently only supported on the CPU, but the expansion can be accelerated using the GPU.
12+
This way, verification and expansion can be performed in parallel, efficiently using all the available computational resources.
13+
14+
## Supported types
15+
Encrypted messages can be integers (as FheUint64) or booleans. The GPU backend does not currently support encrypted strings.
16+
17+
{% hint style="info" %}
18+
You can enable this feature using the flag: `--features=zk-pok,gpu` when building **TFHE-rs**.
19+
{% endhint %}
20+
21+
22+
## Example
23+
24+
The following example shows how a client can encrypt and prove a ciphertext, and how a server can verify the proof, preprocess the ciphertext and run a computation on it on GPU:
25+
26+
```rust
27+
use rand::random;
28+
use tfhe::CompressedServerKey;
29+
use tfhe::prelude::*;
30+
use tfhe::set_server_key;
31+
use tfhe::zk::{CompactPkeCrs, ZkComputeLoad};
32+
33+
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
34+
let params = tfhe::shortint::parameters::PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
35+
// Indicate which parameters to use for the Compact Public Key encryption
36+
let cpk_params = tfhe::shortint::parameters::PARAM_PKE_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
37+
// And parameters allowing to keyswitch/cast to the computation parameters.
38+
let casting_params = tfhe::shortint::parameters::PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
39+
// Enable the dedicated parameters on the config
40+
let config = tfhe::ConfigBuilder::with_custom_parameters(params)
41+
.use_dedicated_compact_public_key_parameters((cpk_params, casting_params)).build();
42+
43+
// The CRS should be generated in an offline phase then shared to all clients and the server
44+
let crs = CompactPkeCrs::from_config(config, 64).unwrap();
45+
46+
// Then use TFHE-rs as usual
47+
let client_key = tfhe::ClientKey::generate(config);
48+
let compressed_server_key = CompressedServerKey::new(&client_key);
49+
let gpu_server_key = compressed_server_key.decompress_to_gpu();
50+
let public_key = tfhe::CompactPublicKey::try_new(&client_key).unwrap();
51+
// This can be left empty, but if provided allows to tie the proof to arbitrary data
52+
let metadata = [b'T', b'F', b'H', b'E', b'-', b'r', b's'];
53+
54+
let clear_a = random::<u64>();
55+
let clear_b = random::<u64>();
56+
57+
let proven_compact_list = tfhe::ProvenCompactCiphertextList::builder(&public_key)
58+
.push(clear_a)
59+
.push(clear_b)
60+
.build_with_proof_packed(&crs, &metadata, ZkComputeLoad::Verify)?;
61+
62+
// Server side
63+
let result = {
64+
set_server_key(gpu_server_key);
65+
66+
// Verify the ciphertexts
67+
let expander =
68+
proven_compact_list.verify_and_expand(&crs, &public_key, &metadata)?;
69+
let a: tfhe::FheUint64 = expander.get(0)?.unwrap();
70+
let b: tfhe::FheUint64 = expander.get(1)?.unwrap();
71+
72+
a + b
73+
};
74+
75+
// Back on the client side
76+
let a_plus_b: u64 = result.decrypt(&client_key);
77+
assert_eq!(a_plus_b, clear_a.wrapping_add(clear_b));
78+
79+
Ok(())
80+
}
81+
```

0 commit comments

Comments
 (0)