plonky2-crypto-gadgets/aes-gcm/examples/aes_gcm_256.rs
aes-gcm/examples/aes_gcm_256.rsRaw
1//! Run: `cargo run --release --example aes_gcm_256`
2#![allow(incomplete_features)]
3#![feature(generic_const_exprs)]
4
5use anyhow::Result;
6use plonky2::{
7 field::goldilocks_field::GoldilocksField as F,
8 iop::witness::PartialWitness,
9 plonk::{
10 circuit_builder::CircuitBuilder, circuit_data::CircuitConfig,
11 config::PoseidonGoldilocksConfig,
12 },
13};
14use plonky2_aes::{AesGcm256Target, D, KEY_LEN_256};
15
16fn main() -> Result<()> {
17 // max size (bytes) of plaintext supported by the instantiation of the circuit
18 const L: usize = 42;
19
20 let key: &[u8; KEY_LEN_256] = &[123; KEY_LEN_256];
21 let nonce: &[u8; 12] = &[111; 12];
22 let pt: &[u8; L] = &[231u8; L]; // plaintext
23
24 // use external rust library to compute the ciphertext & tag
25 let nonce_ext = aes_gcm::Nonce::from_slice(nonce);
26 use aes_gcm::{KeyInit, aead::Aead}; // needed traits
27 let cipher = aes_gcm::Aes256Gcm::new_from_slice(key.as_slice()).unwrap();
28 let encrypt_res = cipher.encrypt(nonce_ext, pt.as_ref()).unwrap();
29 let ct = &encrypt_res[..L]; // ciphertext
30 let tag = &encrypt_res[L..];
31
32 // alternatively we could use this repo's rust implementation (only for tests)
33 // let (ct, tag) = plonky2_aes::native_gcm::encrypt::<8, 4, 14>(key, nonce, pt);
34
35 // circuit declaration
36 let config = CircuitConfig::standard_recursion_zk_config();
37 let mut builder = CircuitBuilder::<F, D>::new(config);
38 let aes_targets = AesGcm256Target::<L>::build(&mut builder);
39
40 println!(
41 "AES-GCM-256 circuit (L:{}) num_gates: {}",
42 L,
43 builder.num_gates()
44 );
45
46 let data = builder.build::<PoseidonGoldilocksConfig>();
47
48 // set values to circuit
49 let mut pw = PartialWitness::<F>::new();
50 aes_targets.set_targets(&mut pw, key, nonce, pt, ct, tag)?;
51
52 let proof = data.prove(pw)?;
53 data.verify(proof)
54}