arnaucube
arnaucube/plonky2-crypto-gadgetsPublic Self-hosted repository
plonky2-crypto-gadgets/examples/aes_gcm_128.rs
examples/aes_gcm_128.rsRaw
 1//! Run: `cargo run --release --example aes_gcm_128`
 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};
14
15use plonky2_aes::{AesGcm128Target, D, KEY_LEN_128};
16
17fn main() -> Result<()> {
18    // max size (bytes) of plaintext supported by the instantiation of the circuit
19    const L: usize = 42;
20
21    let key: &[u8; KEY_LEN_128] = &[123; KEY_LEN_128];
22    let nonce: &[u8; 12] = &[111; 12];
23    let pt: &[u8; L] = &[231u8; L]; // plaintext
24
25    // use external rust library to compute the ciphertext & tag
26    let nonce_ext = aes_gcm::Nonce::from_slice(nonce);
27    use aes_gcm::{aead::Aead, KeyInit}; // needed traits
28    let cipher = aes_gcm::Aes128Gcm::new_from_slice(key.as_slice()).unwrap();
29    let encrypt_res = cipher.encrypt(nonce_ext, pt.as_ref()).unwrap();
30    let ct = &encrypt_res[..L]; // ciphertext
31    let tag = &encrypt_res[L..];
32
33    // alternatively we could use this repo's rust implementation (only for tests)
34    // let (ct, tag) = plonky2_aes::native_gcm::encrypt::<4, 4, 10>(key, nonce, pt);
35
36    // Circuit declaration
37    let config = CircuitConfig::standard_recursion_config();
38    let mut builder = CircuitBuilder::<F, D>::new(config);
39    let aes_targets = AesGcm128Target::<L>::new_virtual(&mut builder);
40    aes_targets.build_circuit(&mut builder);
41
42    println!(
43        "AES-GCM-128 circuit (L:{}) num_gates: {}",
44        L,
45        builder.num_gates()
46    );
47
48    let data = builder.build::<PoseidonGoldilocksConfig>();
49
50    // set values to circuit
51    let mut pw = PartialWitness::<F>::new();
52    aes_targets.set_targets(&mut pw, key, nonce, pt, &ct, &tag)?;
53
54    let proof = data.prove(pw)?;
55    data.verify(proof)
56}