Skip to content

Commit

Permalink
Fixup aes-gcm bugs, add self generated test case (#75)
Browse files Browse the repository at this point in the history
Co-authored-by: devloper <[email protected]>
  • Loading branch information
devloper and devloper authored Sep 17, 2024
1 parent a52b82d commit 4a14455
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 9 deletions.
2 changes: 1 addition & 1 deletion circuits/aes-gcm/aes-gcm.circom
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ template AESGCM(l) {
signal output authTag[16]; // Authentication tag length is 128 bits (16 bytes)

component zeroBlock = ToBlocks(16);
for (var i = 0; i < l; i++) {
for (var i = 0; i < 16; i++) {
zeroBlock.stream[i] <== 0;
}

Expand Down
56 changes: 48 additions & 8 deletions circuits/test/aes-gcm.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { assert } from "chai";
import { WitnessTester } from "circomkit";
import { circomkit, hexBytesToBigInt } from "./common";
import { circomkit, hexBytesToBigInt, hexToBytes } from "./common";

describe("aes-gcm", () => {
let circuit: WitnessTester<["key", "iv", "plainText", "aad"], ["cipherText", "tag"]>;
Expand All @@ -13,19 +13,59 @@ describe("aes-gcm", () => {
});
});

let key = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let plainText = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let iv = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let HashKey = [0x66,0xe9,0x4b,0xd4,0xef,0x8a,0x2c,0x3b,0x88,0x4c,0xfa,0x59,0xca,0x34,0x2b,0x2e];
let aad = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let expected_output = [0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78];

it("should have correct output", async () => {
let key = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let plainText = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let iv = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
// TODO: Fix hashkey.
let HashKey = [0x66,0xe9,0x4b,0xd4,0xef,0x8a,0x2c,0x3b,0x88,0x4c,0xfa,0x59,0xca,0x34,0x2b,0x2e];
let aad = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let expected_output = [0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78];

const witness = await circuit.compute({ key: key, iv: iv, plainText: plainText, aad: aad }, ["cipherText", "authTag"])

assert.deepEqual(witness.cipherText, hexBytesToBigInt(expected_output))
});

it("should work for self generated test case", async () => {
let circuit_one_block: WitnessTester<["key", "iv", "plainText", "aad"], ["cipherText", "tag"]>;
circuit_one_block = await circomkit.WitnessTester(`aes-gcm`, {
file: "aes-gcm/aes-gcm",
template: "AESGCM",
params: [16],
});

const key = hexToBytes('31313131313131313131313131313131');
const iv = hexToBytes('313131313131313131313131');
const msg = hexToBytes('7465737468656c6c6f30303030303030');
const aad = hexToBytes('00000000000000000000000000000000')
const ct = hexToBytes('2929d2bb1ae94804402b8e776e0d3356');
const auth_tag = hexToBytes('0cab39e1a491b092185965f7b554aea0');

const witness = await circuit_one_block.compute({ key: key, iv: iv, plainText: msg, aad: aad }, ["cipherText", "authTag"])

assert.deepEqual(witness.cipherText, hexBytesToBigInt(ct))
});

it("should work for multiple blocks", async () => {
let circuit_one_block: WitnessTester<["key", "iv", "plainText", "aad"], ["cipherText", "tag"]>;
circuit_one_block = await circomkit.WitnessTester(`aes-gcm`, {
file: "aes-gcm/aes-gcm",
template: "AESGCM",
params: [32],
});

const key = hexToBytes('31313131313131313131313131313131');
const iv = hexToBytes('313131313131313131313131');
const msg = hexToBytes('7465737468656c6c6f303030303030307465737468656c6c6f30303030303030');
const aad = hexToBytes('00000000000000000000000000000000')
const ct = hexToBytes('2929d2bb1ae94804402b8e776e0d335626756530713e4c065af1d3c4f56e0204');
const auth_tag = hexToBytes('438542d7f387568c84d23df60b223ecb');

const witness = await circuit_one_block.compute({ key: key, iv: iv, plainText: msg, aad: aad }, ["cipherText", "authTag"])

assert.deepEqual(witness.cipherText, hexBytesToBigInt(ct))
});
});

// signal input key[16]; // 128-bit key
Expand Down
5 changes: 5 additions & 0 deletions circuits/test/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export const circomkit = new Circomkit({

export { WitnessTester };


export function hexToBytes(hex: any) {
return hex.match(/.{1,2}/g).map((byte: any) => parseInt(byte, 16));
}

export function hexBytesToBigInt(hexBytes: number[]): any[] {
return hexBytes.map(byte => {
let n = BigInt(byte);
Expand Down
29 changes: 29 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ async fn main() -> io::Result<()> {
witness.iv.extend_from_slice(&[0, 0, 0, 0]);

make_json_witness(&witness, witness::CipherMode::Vanilla).unwrap();

Ok(())
}

Expand All @@ -69,4 +70,32 @@ mod tests {
// generate proof
proof::gen_proof_aes_gcm_siv(&witness, SIV_WTNS, SIV_R1CS);
}

// AES GCM multiple blocks of data
// cargo test test_aes_gcm_blocks -- --show-output
#[tokio::test]
async fn test_aes_gcm_blocks() {
use aes_gcm::{
aead::{generic_array::GenericArray, Aead, NewAead, Payload},
Aes128Gcm,
};

let test_key = [
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
0x31, 0x31,
];
let test_iv = [0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31];

let message = String::from("testhello0000000testhello0000000");
let aes_payload = Payload { msg: &message.as_bytes(), aad: &[] };

let cipher = Aes128Gcm::new_from_slice(&test_key).unwrap();
let nonce = GenericArray::from_slice(&test_iv);
let ct = cipher.encrypt(nonce, aes_payload).expect("error generating ct");

println!("key={}", hex::encode(test_key));
println!("iv={}", hex::encode(test_iv));
println!("msg={}", hex::encode(message));
println!("ct={}", hex::encode(ct));
}
}

0 comments on commit 4a14455

Please sign in to comment.