Skip to content

Commit

Permalink
inc32 sub routine and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
0xJepsen committed Sep 9, 2024
1 parent 1048487 commit 815ab16
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 17 deletions.
48 changes: 31 additions & 17 deletions circuits/aes-gcm/aes-gcm.circom
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,25 @@ include "../ghash/ghash.circom";
include "../aes-ctr/cipher.circom";
include "circomlib/circuits/bitify.circom";

template AESGCM(l, nk) {

/// AES-GCM with 128 bit key according to: https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38d.pdf
///
/// Parameters:
/// l: length of the plaintext
///
/// Inputs:
/// key: 128-bit key
/// iv: initialization vector
/// plainText: plaintext to be encrypted
/// additionalData: additional data to be authenticated
///
/// Outputs:
/// cipherText: encrypted ciphertext
/// authTag: authentication tag
///
template AESGCM(l) {
// Inputs
signal input key[nk * 4];
signal input key[16]; // 128-bit key
signal input iv[12]; // IV length is 96 bits (12 bytes)
signal input plainText[l];
signal input additionalData[16]; // AAD length is 128 bits (16 bytes)
Expand All @@ -19,26 +35,25 @@ template AESGCM(l, nk) {
// Step 1: Let H = CIPHK(0128)
component zeroBlock = Num2Bits(128);
zeroBlock.in <== 0;
component cipherH = Cipher(nk);
component cipherH = Cipher(4); // 128-bit key -> 4 32-bit words -> 10 rounds
cipherH.key <== key;
cipherH.block <== zeroBlock.out;
signal H[128];
H <== cipherH.cipher;

// Step 2: Define a block, J0
// Step 2: Define a block, J0 with 96 bits of iv and 32 bits of 0s
// you can of the 96bits as a nonce and the 32 bits of 0s as an integer counter
signal J0[128];
if (iv.length == 12) {
for (var i = 0; i < 96; i++) {
J0[i] <== iv[i];
}
for (var i = 96; i < 127; i++) {
J0[i] <== 0;
}
J0[127] <== 1;
} else {
// Handle the case where IV length is not 96 bits
// This part is omitted for simplicity
for (var i = 0; i < 96; i++) {
J0[i] <== iv[i];
}
for (var i = 96; i < 127; i++) {
J0[i] <== 0;
}
J0[127] <== 1;
/// NOTE(WJ 2024-09-09): There is a way to handle IVs that are not 96 bits in the nist spec involving padding and GHASHing the IV
/// since we set the size for the iv here we don't need to handle it


// Step 3: Let C = GCTRK(inc32(J0), P)
component incJ0 = Increment32();
Expand Down Expand Up @@ -70,5 +85,4 @@ template AESGCM(l, nk) {
gctrT.plainText <== S;
authTag <== gctrT.cipherText;

}

}
40 changes: 40 additions & 0 deletions circuits/aes-gcm/helper_functions.circom
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,43 @@ template ReverseByteArray() {
}
}
}

/// IncrementingFunction increments the integer represented by the 32 least significant bits of the input 128-bit value
/// and returns the result.
template Increment32() {
signal input in[128];
signal output out[128];

// Copy the left-most 96 bits unchanged
for (var i = 0; i < 96; i++) {
out[i] <== in[i];
}

// Convert rightBits to an integer
component rightBitsInt = Bits2Num(32);
for (var i = 0; i < 32; i++) {
rightBitsInt.in[i] <== in[96 + i];
}

// Debugging signal to check the integer value of rightBitsInt
signal rightBitsValue <== rightBitsInt.out;

// Constraint: Increment rightBitsInt
signal incremented <== rightBitsValue + 1;

// Convert the incremented integer back to binary
component num2bits = Num2Bits(32);
num2bits.in <== incremented;
signal incrementedBits[32];
for (var i = 0; i < 32; i++) {
incrementedBits[i] <== num2bits.out[i];
}

// TODO(WJ 2024-09-09): Check if this bit-reversal is needed.
component reverseBits = ReverseBitsArray(32);
reverseBits.in <== incrementedBits;
// Copy the incremented bits to the output
for (var i = 0; i < 32; i++) {
out[96 + i] <== reverseBits.out[i];
}
}
20 changes: 20 additions & 0 deletions circuits/test/increment.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { WitnessTester } from "circomkit";
import { circomkit } from "./common";

describe("Increment", () => {
let circuit: WitnessTester<["in"], ["out"]>;
it("should increment the input", async () => {
circuit = await circomkit.WitnessTester(`Increment`, {
file: "aes-gcm/helper_functions",
template: "Increment32",
});
let res = await circuit.expectPass(
{
in: Array(128).fill(0),
},
{
out: [...Array(127).fill(0), 1],
}
);
});
});

0 comments on commit 815ab16

Please sign in to comment.