-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from pluto/chacha20
Chacha20
- Loading branch information
Showing
23 changed files
with
967 additions
and
123 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pragma circom 2.1.9; | ||
|
||
include "../../circuits/chacha20/chacha20.circom"; | ||
|
||
component main = ChaCha20_NIVC(256); |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
5 changes: 0 additions & 5 deletions
5
builds/target_1024b/http_parse_and_lock_start_line_1024b.circom
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pragma circom 2.1.9; | ||
|
||
include "../../circuits/chacha20/nivc/chacha20_nivc.circom"; | ||
|
||
component main = ChaCha20_NIVC(128); |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
5 changes: 0 additions & 5 deletions
5
builds/target_512b/http_parse_and_lock_start_line_512b.circom
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// initially from https://github.com/reclaimprotocol/zk-symmetric-crypto | ||
// modified for our needs | ||
pragma circom 2.1.9; | ||
|
||
include "../utils/generics-bits.circom"; | ||
|
||
/** | ||
* Perform ChaCha Quarter Round | ||
* Assume 4 words of 32 bits each | ||
* Each word must be little endian | ||
*/ | ||
template QR() { | ||
signal input in[4][32]; | ||
signal output out[4][32]; | ||
|
||
var tmp[4][32] = in; | ||
|
||
// a += b | ||
component add1 = AddBits(32); | ||
add1.a <== tmp[0]; | ||
add1.b <== tmp[1]; | ||
|
||
tmp[0] = add1.out; | ||
|
||
// d ^= a | ||
component xor1 = XorBits(32); | ||
xor1.a <== tmp[3]; | ||
xor1.b <== tmp[0]; | ||
tmp[3] = xor1.out; | ||
|
||
// d = RotateLeft32BitsUnsafe(d, 16) | ||
component rot1 = RotateLeftBits(32, 16); | ||
rot1.in <== tmp[3]; | ||
tmp[3] = rot1.out; | ||
|
||
// c += d | ||
component add2 = AddBits(32); | ||
add2.a <== tmp[2]; | ||
add2.b <== tmp[3]; | ||
tmp[2] = add2.out; | ||
|
||
// b ^= c | ||
component xor2 = XorBits(32); | ||
xor2.a <== tmp[1]; | ||
xor2.b <== tmp[2]; | ||
tmp[1] = xor2.out; | ||
|
||
// b = RotateLeft32BitsUnsafe(b, 12) | ||
component rot2 = RotateLeftBits(32, 12); | ||
rot2.in <== tmp[1]; | ||
tmp[1] = rot2.out; | ||
|
||
// a += b | ||
component add3 = AddBits(32); | ||
add3.a <== tmp[0]; | ||
add3.b <== tmp[1]; | ||
tmp[0] = add3.out; | ||
|
||
// d ^= a | ||
component xor3 = XorBits(32); | ||
xor3.a <== tmp[3]; | ||
xor3.b <== tmp[0]; | ||
tmp[3] = xor3.out; | ||
|
||
// d = RotateLeft32BitsUnsafe(d, 8) | ||
component rot3 = RotateLeftBits(32, 8); | ||
rot3.in <== tmp[3]; | ||
tmp[3] = rot3.out; | ||
|
||
// c += d | ||
component add4 = AddBits(32); | ||
add4.a <== tmp[2]; | ||
add4.b <== tmp[3]; | ||
tmp[2] = add4.out; | ||
|
||
// b ^= c | ||
component xor4 = XorBits(32); | ||
xor4.a <== tmp[1]; | ||
xor4.b <== tmp[2]; | ||
tmp[1] = xor4.out; | ||
|
||
// b = RotateLeft32BitsUnsafe(b, 7) | ||
component rot4 = RotateLeftBits(32, 7); | ||
rot4.in <== tmp[1]; | ||
tmp[1] = rot4.out; | ||
|
||
out <== tmp; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// initially from https://github.com/reclaimprotocol/zk-symmetric-crypto | ||
// modified for our needs | ||
pragma circom 2.1.9; | ||
|
||
include "./chacha-qr.circom"; | ||
include "../utils/generics-bits.circom"; | ||
|
||
template Round() { | ||
// in => 16 32-bit words | ||
signal input in[16][32]; | ||
// out => 16 32-bit words | ||
signal output out[16][32]; | ||
|
||
var tmp[16][32] = in; | ||
|
||
component rounds[10 * 8]; | ||
component finalAdd[16]; | ||
// i-th round | ||
var i = 0; | ||
// col loop counter | ||
var j = 0; | ||
// counter for the rounds array | ||
var k = 0; | ||
for(i = 0; i < 10; i++) { | ||
// columns of the matrix in a loop | ||
// 0, 4, 8, 12 | ||
// 1, 5, 9, 13 | ||
// 2, 6, 10, 14 | ||
// 3, 7, 11, 15 | ||
for(j = 0; j < 4; j++) { | ||
rounds[k] = QR(); | ||
rounds[k].in[0] <== tmp[j]; | ||
rounds[k].in[1] <== tmp[j + 4]; | ||
rounds[k].in[2] <== tmp[j + 8]; | ||
rounds[k].in[3] <== tmp[j + 12]; | ||
|
||
tmp[j] = rounds[k].out[0]; | ||
tmp[j + 4] = rounds[k].out[1]; | ||
tmp[j + 8] = rounds[k].out[2]; | ||
tmp[j + 12] = rounds[k].out[3]; | ||
|
||
k ++; | ||
} | ||
|
||
// 4 diagnals | ||
// 0, 5, 10, 15 | ||
rounds[k] = QR(); | ||
rounds[k].in[0] <== tmp[0]; | ||
rounds[k].in[1] <== tmp[5]; | ||
rounds[k].in[2] <== tmp[10]; | ||
rounds[k].in[3] <== tmp[15]; | ||
|
||
tmp[0] = rounds[k].out[0]; | ||
tmp[5] = rounds[k].out[1]; | ||
tmp[10] = rounds[k].out[2]; | ||
tmp[15] = rounds[k].out[3]; | ||
|
||
k ++; | ||
|
||
// 1, 6, 11, 12 | ||
rounds[k] = QR(); | ||
rounds[k].in[0] <== tmp[1]; | ||
rounds[k].in[1] <== tmp[6]; | ||
rounds[k].in[2] <== tmp[11]; | ||
rounds[k].in[3] <== tmp[12]; | ||
|
||
tmp[1] = rounds[k].out[0]; | ||
tmp[6] = rounds[k].out[1]; | ||
tmp[11] = rounds[k].out[2]; | ||
tmp[12] = rounds[k].out[3]; | ||
|
||
k ++; | ||
|
||
// 2, 7, 8, 13 | ||
rounds[k] = QR(); | ||
rounds[k].in[0] <== tmp[2]; | ||
rounds[k].in[1] <== tmp[7]; | ||
rounds[k].in[2] <== tmp[8]; | ||
rounds[k].in[3] <== tmp[13]; | ||
|
||
tmp[2] = rounds[k].out[0]; | ||
tmp[7] = rounds[k].out[1]; | ||
tmp[8] = rounds[k].out[2]; | ||
tmp[13] = rounds[k].out[3]; | ||
|
||
k ++; | ||
|
||
// 3, 4, 9, 14 | ||
rounds[k] = QR(); | ||
rounds[k].in[0] <== tmp[3]; | ||
rounds[k].in[1] <== tmp[4]; | ||
rounds[k].in[2] <== tmp[9]; | ||
rounds[k].in[3] <== tmp[14]; | ||
|
||
tmp[3] = rounds[k].out[0]; | ||
tmp[4] = rounds[k].out[1]; | ||
tmp[9] = rounds[k].out[2]; | ||
tmp[14] = rounds[k].out[3]; | ||
|
||
k ++; | ||
} | ||
|
||
// add the result to the input | ||
for(i = 0; i < 16; i++) { | ||
finalAdd[i] = AddBits(32); | ||
finalAdd[i].a <== tmp[i]; | ||
finalAdd[i].b <== in[i]; | ||
tmp[i] = finalAdd[i].out; | ||
} | ||
|
||
out <== tmp; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// initially from https://github.com/reclaimprotocol/zk-symmetric-crypto | ||
// modified for our needs | ||
pragma circom 2.1.9; | ||
|
||
include "./chacha-round.circom"; | ||
include "./chacha-qr.circom"; | ||
include "../utils/generics-bits.circom"; | ||
|
||
/** ChaCha20 in counter mode */ | ||
// Chacha20 opperates a 4x4 matrix of 32-bit words where the first 4 words are constants: C | ||
// and the next 8 words are the 256 bit key: K. The next 2 words are the block counter: # | ||
// and the last 2 words are the nonce: N. | ||
// +---+---+---+---+ | ||
// | C | C | C | C | | ||
// +---+---+---+---+ | ||
// | K | K | K | K | | ||
// +---+---+---+---+ | ||
// | K | K | K | K | | ||
// +---+---+---+---+ | ||
// | # | # | N | N | | ||
// +---+---+---+---+ | ||
// paramaterized by n which is the number of 32-bit words to encrypt | ||
template ChaCha20(N) { | ||
// key => 8 32-bit words = 32 bytes | ||
signal input key[8][32]; | ||
// nonce => 3 32-bit words = 12 bytes | ||
signal input nonce[3][32]; | ||
// counter => 32-bit word to apply w nonce | ||
signal input counter[32]; | ||
|
||
// the below can be both ciphertext or plaintext depending on the direction | ||
// in => N 32-bit words => N 4 byte words | ||
signal input in[N][32]; | ||
// out => N 32-bit words => N 4 byte words | ||
signal output out[N][32]; | ||
|
||
var tmp[16][32] = [ | ||
[ | ||
// constant 0x61707865 | ||
0, 1, 1, 0, 0, 0, 0, 1, 0, | ||
1, 1, 1, 0, 0, 0, 0, 0, 1, | ||
1, 1, 1, 0, 0, 0, 0, 1, 1, | ||
0, 0, 1, 0, 1 | ||
], | ||
[ | ||
// constant 0x3320646e | ||
0, 0, 1, 1, 0, 0, 1, 1, 0, | ||
0, 1, 0, 0, 0, 0, 0, 0, 1, | ||
1, 0, 0, 1, 0, 0, 0, 1, 1, | ||
0, 1, 1, 1, 0 | ||
], | ||
[ | ||
// constant 0x79622d32 | ||
0, 1, 1, 1, 1, 0, 0, 1, 0, | ||
1, 1, 0, 0, 0, 1, 0, 0, 0, | ||
1, 0, 1, 1, 0, 1, 0, 0, 1, | ||
1, 0, 0, 1, 0 | ||
], | ||
[ | ||
// constant 0x6b206574 | ||
0, 1, 1, 0, 1, 0, 1, 1, 0, | ||
0, 1, 0, 0, 0, 0, 0, 0, 1, | ||
1, 0, 0, 1, 0, 1, 0, 1, 1, | ||
1, 0, 1, 0, 0 | ||
], | ||
key[0], key[1], key[2], key[3], | ||
key[4], key[5], key[6], key[7], | ||
counter, nonce[0], nonce[1], nonce[2] | ||
]; | ||
|
||
// 1 in 32-bit words | ||
signal one[32]; | ||
one <== [ | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 1 | ||
]; | ||
|
||
var i = 0; | ||
var j = 0; | ||
|
||
// do the ChaCha20 rounds | ||
component rounds[N/16]; | ||
component xors[N]; | ||
component counter_adder[N/16 - 1]; | ||
|
||
for(i = 0; i < N/16; i++) { | ||
rounds[i] = Round(); | ||
rounds[i].in <== tmp; | ||
// XOR block with input | ||
for(j = 0; j < 16; j++) { | ||
xors[i*16 + j] = XorBits(32); | ||
xors[i*16 + j].a <== in[i*16 + j]; | ||
xors[i*16 + j].b <== rounds[i].out[j]; | ||
out[i*16 + j] <== xors[i*16 + j].out; | ||
} | ||
|
||
if(i < N/16 - 1) { | ||
counter_adder[i] = AddBits(32); | ||
counter_adder[i].a <== tmp[12]; | ||
counter_adder[i].b <== one; | ||
|
||
// increment the counter | ||
tmp[12] = counter_adder[i].out; | ||
} | ||
} | ||
} |
Oops, something went wrong.