-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement polyval #79
Changes from all commits
e70b9d2
4be68c3
1cb74e3
99f26bc
9a3b18c
80e049d
0734562
328c654
bdfbfbe
1ca08c9
43b7cb0
a2102ea
6ea0512
139251a
eb0ff72
1659151
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
pragma circom 2.1.9; | ||
include "polyval_gfmul.circom"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delete file, one will be merged with the other PR |
||
include "gfmulx.circom"; | ||
|
||
template GHASH_GFMUL() { | ||
signal input a[2][64]; | ||
signal input b[2][64]; | ||
signal output out[2][64]; | ||
|
||
// TODO(TK 2024-09-18): produce a ghash mul wrapper | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ include "circomlib/circuits/bitify.circom"; | |
include "circomlib/circuits/gates.circom"; | ||
include "circomlib/circuits/comparators.circom"; | ||
|
||
// parse LE bits to int | ||
template ParseLEBytes64() { | ||
signal input in[64]; | ||
signal output out; | ||
|
@@ -22,6 +23,43 @@ template ParseLEBytes64() { | |
out <-- temp; | ||
} | ||
|
||
// parse BE bits as bytes and log them. Assumes that the number of bytes logged is a multiple of 8. | ||
template ParseAndLogBitsAsBytes(N_BYTES){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice! |
||
var N_BITS = N_BYTES * 8; | ||
signal input in[N_BITS]; | ||
component Parser = ParseBEBitsToBytes(N_BYTES); | ||
for (var i=0; i<N_BITS; i++){ | ||
Parser.in[i] <== in[i]; | ||
} | ||
for (var i=0; i<N_BYTES / 8; i++){ | ||
log("in[", i, "]=", | ||
Parser.out[i*8+0], Parser.out[i*8+1], Parser.out[i*8+2], Parser.out[i*8+3], | ||
Parser.out[i*8+4], Parser.out[i*8+5], Parser.out[i*8+6], Parser.out[i*8+7] | ||
); | ||
} | ||
} | ||
|
||
// parse BE bits to bytes. | ||
template ParseBEBitsToBytes(N_BYTES) { | ||
var N_BITS = N_BYTES * 8; | ||
signal input in[N_BITS]; | ||
signal output out[N_BYTES]; | ||
// var temp[8] = [0,0,0,0,0,0,0,0]; | ||
|
||
// Iterate through the input bits | ||
var temp[N_BYTES]; | ||
for (var i = 0; i < N_BYTES; i++) { | ||
temp[i] = 0; | ||
for (var j = 7; j >= 0; j--) { | ||
temp[i] += 2**j * in[i*8 + 7 - j]; | ||
} | ||
} | ||
|
||
for (var i=0; i< N_BYTES; i++) { | ||
out[i] <-- temp[i]; | ||
} | ||
} | ||
|
||
// parse 64-bits to integer value | ||
template ParseBEBytes64() { | ||
signal input in[64]; | ||
|
@@ -334,18 +372,8 @@ template IndexSelector(total) { | |
out <== calcTotal.sum; | ||
} | ||
|
||
// reverse the order in an n-bit array | ||
template ReverseArray(n) { | ||
signal input in[n]; | ||
signal output out[n]; | ||
|
||
for (var i = 0; i < n; i++) { | ||
out[i] <== in[n-i-1]; | ||
} | ||
} | ||
|
||
// reverse the byte order in a 16 byte array | ||
template ReverseByteArray() { | ||
template ReverseByteArray128() { | ||
signal input in[128]; | ||
signal output out[128]; | ||
|
||
|
@@ -354,4 +382,37 @@ template ReverseByteArray() { | |
out[j + 8*i] <== in[(15-i)*8 +j]; | ||
} | ||
} | ||
} | ||
} | ||
// in a 128-bit array, reverse the byte order in the first 64 bits, and the second 64 bits | ||
template ReverseByteArrayHalves128() { | ||
signal input in[128]; | ||
signal output out[128]; | ||
|
||
for (var i=0; i<8; i++){ | ||
for (var j=0; j<8; j++){ | ||
var SWAP_IDX = 56-(i*8)+j; | ||
out[i*8+j] <== in[SWAP_IDX]; | ||
} | ||
} | ||
for (var i=0; i<8; i++){ | ||
for (var j=0; j<8; j++){ | ||
var SWAP_IDX = 56-(i*8)+j+64; | ||
out[i*8+j+64] <== in[SWAP_IDX]; | ||
} | ||
} | ||
} | ||
|
||
// in a 128-bit array, reverse the halves. | ||
template ReverseHalves128() { | ||
signal input in[128]; | ||
signal output out[128]; | ||
|
||
for (var i=0; i<64; i++){ | ||
var SWAP_IDX = 64+i; | ||
out[i] <== in[SWAP_IDX]; | ||
} | ||
for (var i=64; i<128; i++){ | ||
var SWAP_IDX = i-64; | ||
out[i] <== in[SWAP_IDX]; | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,49 @@ | ||
template POLYVAL(n_msg_bits) | ||
{ | ||
signal input msg[n_msg_bits]; | ||
pragma circom 2.1.9; | ||
|
||
include "polyval_gfmul.circom"; | ||
|
||
template POLYVAL(BLOCKS) { | ||
signal input msg[BLOCKS][128]; | ||
signal input H[128]; | ||
// signal input T[2][64]; // TODO | ||
signal output out[128]; | ||
|
||
for (var i = 0; i < 128; i++) { | ||
out[i] <== 1; | ||
// LE adjustments: reverse msg and H, store in msg_ and H_ | ||
signal H_[128]; | ||
signal msg_[BLOCKS][128]; | ||
component ReverseByteHalves[BLOCKS+2]; | ||
for (var i=0; i<BLOCKS+2; i++){ ReverseByteHalves[i] = ReverseByteArrayHalves128();} | ||
ReverseByteHalves[0].in <-- H; H_ <-- ReverseByteHalves[0].out; | ||
for (var i=2; i<BLOCKS+2; i++){ ReverseByteHalves[i].in <-- msg[i-2]; msg_[i-2] <-- ReverseByteHalves[i].out; } | ||
|
||
component XORS[BLOCKS]; component POLYVAL_GFMUL[BLOCKS]; | ||
for (var i=0; i<BLOCKS; i++){ XORS[i] = BitwiseXor(128); } | ||
for (var i=0; i<BLOCKS; i++){ POLYVAL_GFMUL[i] = POLYVAL_GFMUL(); } | ||
|
||
signal mids[BLOCKS+1][128]; | ||
for (var i=0; i<128; i++){ mids[0][i] <-- 0; } | ||
|
||
// xor and multiply | ||
for (var block=0; block<BLOCKS; block++){ | ||
// xor | ||
XORS[block].a <== mids[block]; | ||
XORS[block].b <== msg_[block]; | ||
|
||
// multiply XORS[block].out * H_ | ||
for (var i=0; i<2; i++){ for (var j=0; j<64; j++){ | ||
POLYVAL_GFMUL[block].a[i][j] <== XORS[block].out[i*64+j]; | ||
POLYVAL_GFMUL[block].b[i][j] <== H_[i*64+j]; | ||
} } | ||
for (var i=0; i<2; i++){ for (var j=0; j<64; j++){ | ||
mids[block+1][i*64+j] <== POLYVAL_GFMUL[block].out[i][j]; | ||
} } | ||
} | ||
|
||
} | ||
// need to reverse for BE once more | ||
signal _out[128]; _out <== mids[BLOCKS]; | ||
ReverseByteHalves[1].in <== _out; | ||
out <-- ReverseByteHalves[1].out; | ||
|
||
// component Logger3 = ParseAndLogBitsAsBytes(16); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||
// log("out"); | ||
// Logger3.in <== out; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach on the surface seems dramatically more efficient than the one currently used in Waylon's PR, because it only does this GFMULX once at the end.
Would be good to put our heads together and find a potentially combined approach of these code paths that is less constraint consumptive.