Skip to content

Commit 9ef4926

Browse files
authored
Golf aes gcm fold (#103)
* add witness calc to CI * idiomatic CI nameing * constraints: 801698, removed redunant parameters * constraints: 801676, ghash modes? * simplify a bit more * CI Fix * comments: tracing our ghash mode selectors * mode logs * removing unneeded generics and adding documentation * remove unused test * removed all auth from ghash * figure fix * compiling array builder * accumulating all values * witness calc works * Update aes-gcm-fold.circom * fix bug in WriteToIndex component * squashing bugs 🐞 * squashing bugs 🐞 * tests passing for a single block * remove misleading logs * remove unused components * fix CI * cleanning up comments * cleanning up comments * bug in to blocks? * passing non zero pr test * test passing for two block case * remove unused foldable ghash * fix ci
1 parent 2d571a4 commit 9ef4926

24 files changed

+540
-740
lines changed

.github/workflows/test.yml .github/workflows/circom.yml

+18-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,21 @@ jobs:
3232
circom --version
3333
3434
- name: Run tests
35-
run: npm run test
35+
run: npm run test
36+
37+
- name: Install Protocol Buffers
38+
run: |
39+
sudo apt-get update
40+
sudo apt-get install -y protobuf-compiler libprotobuf-dev
41+
42+
- name: Setup circom-witnesscalc
43+
run: |
44+
cd .. && git clone https://github.com/iden3/circom-witnesscalc.git
45+
cd circom-witnesscalc
46+
cargo install --path .
47+
echo $(which build-circuit)
48+
49+
- name: Build witness for aes-gcm
50+
run: |
51+
build-circuit circuits/aes-gcm-fold/aes-gcm-fold.circom aes-fold.bin -l node_modules
52+

.github/workflows/ci.yml .github/workflows/rust.yml

-11
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,6 @@ jobs:
2626
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
2727
- run: rustup component add clippy
2828
- run: cargo clippy -- -Dwarnings
29-
# test:
30-
# name: test project
31-
# runs-on: ubuntu-latest
32-
# strategy:
33-
# matrix:
34-
# toolchain:
35-
# - nightly
36-
# steps:
37-
# - uses: actions/checkout@v4
38-
# - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
39-
# - run: cargo test --all-features --verbose
4029

4130
fmt:
4231
name: fmt project

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ circuits/test/*.circom
1313
circuits/main/*
1414
ir_log/*
1515
log_input_signals.txt
16-
*.bin
16+
*.bin
17+
ghash_gmul.r1cs
18+
main.r1cs
19+
*.r1cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pragma circom 2.1.9;
2+
3+
include "../aes-gcm/aes-gcm-fold.circom";
4+
5+
component main = AESGCMFOLD(16);

circuits/aes-gcm/aes-gcm-fold.circom

+46-32
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,66 @@
11
pragma circom 2.1.9;
22

33
include "./aes-gcm-foldable.circom";
4+
include "./utils.circom";
45

56
// Compute AES-GCM
6-
template AESGCMFOLD(bytesPerFold, totalBytes) {
7-
// cannot fold outside chunk boundaries.
8-
assert(bytesPerFold % 16 == 0);
9-
assert(totalBytes % 16 == 0);
7+
template AESGCMFOLD(INPUT_LEN) {
8+
assert(INPUT_LEN % 16 == 0);
9+
10+
var DATA_BYTES = (INPUT_LEN * 2) + 5;
1011

1112
signal input key[16];
1213
signal input iv[12];
1314
signal input aad[16];
14-
signal input plainText[bytesPerFold];
15+
signal input plainText[16];
16+
17+
// step_in[0..INPUT_LEN] => accumulate plaintext blocks
18+
// step_in[INPUT_LEN..INPUT_LEN*2] => accumulate ciphertext blocks
19+
// step_in[INPUT_LEN*2..INPUT_LEN*2+4] => lastCounter
20+
// step_in[INPUT_LEN*2+5] => foldedBlocks // TODO(WJ 2024-10-24): technically not needed if can read 4 bytes as a 32 bit number
21+
signal input step_in[DATA_BYTES];
22+
signal output step_out[DATA_BYTES];
23+
signal counter <== step_in[INPUT_LEN*2 + 4];
1524

16-
// Output from the last encryption step
17-
// Always use last bytes for inputs which are not same size.
18-
// step_in[0..4] => lastCounter
19-
// step_in[4..20] => lastTag
20-
// step_in[20] => foldedBlocks
21-
signal input step_in[21];
25+
// write new plain text block.
26+
signal plainTextAccumulator[DATA_BYTES];
27+
component writeToIndex = WriteToIndex(DATA_BYTES, 16);
28+
writeToIndex.array_to_write_to <== step_in;
29+
writeToIndex.array_to_write_at_index <== plainText;
30+
writeToIndex.index <== counter * 16;
31+
writeToIndex.out ==> plainTextAccumulator;
2232

23-
// For now, attempt to support variable fold size. Potential fix at 16 in the future.
24-
component aes = AESGCMFOLDABLE(bytesPerFold, totalBytes\16);
33+
// folds one block
34+
component aes = AESGCMFOLDABLE();
2535
aes.key <== key;
2636
aes.iv <== iv;
2737
aes.aad <== aad;
2838
aes.plainText <== plainText;
2939

30-
// Fold inputs
3140
for(var i = 0; i < 4; i++) {
32-
aes.lastCounter[i] <== step_in[i];
41+
aes.lastCounter[i] <== step_in[INPUT_LEN*2 + i];
3342
}
34-
for(var i = 0; i < 16; i++) {
35-
aes.lastTag[i] <== step_in[4 + i];
36-
}
37-
// TODO:tracy range check, assertions, stuff.
38-
aes.foldedBlocks <== step_in[20];
3943

40-
// Fold Outputs
41-
signal output step_out[21];
42-
for(var i = 0; i < 4; i++) {
43-
step_out[i] <== aes.counter[i];
44-
}
45-
for(var i = 0; i < 16; i++) {
46-
step_out[4 + i] <== aes.authTag[i];
47-
}
48-
step_out[20] <== step_in[20] + bytesPerFold \ 16;
44+
// accumulate cipher text
45+
signal cipherTextAccumulator[DATA_BYTES];
46+
component writeCipherText = WriteToIndex(DATA_BYTES, 16);
47+
writeCipherText.array_to_write_to <== plainTextAccumulator;
48+
writeCipherText.array_to_write_at_index <== aes.cipherText;
49+
writeCipherText.index <== INPUT_LEN + counter * 16;
50+
writeCipherText.out ==> cipherTextAccumulator;
51+
52+
// get counter
53+
signal counterAccumulator[DATA_BYTES];
54+
component writeCounter = WriteToIndex(DATA_BYTES, 4);
55+
writeCounter.array_to_write_to <== cipherTextAccumulator;
56+
writeCounter.array_to_write_at_index <== aes.counter;
57+
writeCounter.index <== INPUT_LEN*2;
58+
writeCounter.out ==> counterAccumulator;
4959

50-
signal output authTag[16] <== aes.authTag;
51-
signal output cipherText[bytesPerFold] <== aes.cipherText;
52-
}
60+
// accumulate number of folded blocks
61+
component writeNumberOfFoldedBlocks = WriteToIndex(DATA_BYTES, 1);
62+
writeNumberOfFoldedBlocks.array_to_write_to <== counterAccumulator;
63+
writeNumberOfFoldedBlocks.array_to_write_at_index <== [step_in[INPUT_LEN*2 + 4] + 1];
64+
writeNumberOfFoldedBlocks.index <== INPUT_LEN*2 + 4;
65+
writeNumberOfFoldedBlocks.out ==> step_out;
66+
}

0 commit comments

Comments
 (0)