Skip to content

Commit

Permalink
fix hash authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
0xJepsen committed Nov 18, 2024
1 parent 4da1781 commit d1df539
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 44 deletions.
23 changes: 11 additions & 12 deletions circuits/chacha20/nivc/chacha20_nivc.circom
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,17 @@ template ChaCha20_NIVC(N) {
}
}

var packedPlaintext[N]; // Each element will be a 32-bit word
for(var i = 0; i < N; i++) {
packedPlaintext[i] = 0;
for(var j = 0; j < 32; j++) { // Loop through all 32 bits
packedPlaintext[i] += plainText[i][j] * 2**j; // Now we shift by single bits
component toBytes[N];
signal bigEndianPlaintext[N*4];
for(var i = 0 ; i < N; i++) {
toBytes[i] = fromLittleEndianToWords32();
for(var j = 0 ; j < 32 ; j++) {
toBytes[i].data[j] <== plainText[i][j];
}
for(var j = 0; j < 4; j++) {
bigEndianPlaintext[i*4 + j] <== toBytes[i].words[j];
}
}

signal hash[N];
hash[0] <== PoseidonChainer()([step_in[0], packedPlaintext[0]]);
for(var i = 1 ; i < N ; i++) {
hash[i] <== PoseidonChainer()([hash[i-1], packedPlaintext[i]]);
}
step_out[0] <== hash[N-1];
signal data_hash <== DataHasher(N*4)(bigEndianPlaintext);
step_out[0] <== data_hash;
}
5 changes: 2 additions & 3 deletions circuits/http/nivc/http_nivc.circom
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ template HttpNIVC(DATA_BYTES, MAX_NUMBER_OF_HEADERS) {

// Authenticate the plaintext we are passing in
signal input data[DATA_BYTES];
// TODO(WJ 2024-11-18): FIX AUTHENTICATION
// signal data_hash <== ChaCha20DataHasher(DATA_BYTES)(data);
// data_hash === step_in[0];
signal data_hash <== DataHasher(DATA_BYTES)(data);
data_hash === step_in[0];

signal input start_line_hash;
signal input header_hashes[MAX_NUMBER_OF_HEADERS];
Expand Down
8 changes: 4 additions & 4 deletions circuits/test/full/full.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { assert } from "chai";
import { circomkit, WitnessTester, toByte, uintArray32ToBits } from "../common";
import { circomkit, WitnessTester, toByte, uintArray32ToBits, toUint32Array } from "../common";
import { DataHasher, chacha20_packed_hash } from "../common/poseidon";
import { toInput } from "../chacha20/chacha20-nivc.test";
import { buffer } from "stream/consumers";

// HTTP/1.1 200 OK
// content-type: application/json; charset=utf-8
Expand Down Expand Up @@ -264,10 +265,9 @@ describe("NIVC_FULL", async () => {
const ctIn = toInput(Buffer.from(http_response_ciphertext));
const keyIn = toInput(Buffer.from(Array(32).fill(0)));
const nonceIn = toInput(Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00]));

let chacha20 = await chacha20Circuit.compute({ key: keyIn, nonce: nonceIn, counter: counterBits, plainText: ptIn, cipherText: ctIn, step_in: init_nivc_input }, ["step_out"]);
console.log("ChaCha20 `step_out`:", chacha20.step_out);
assert.deepEqual(chacha20_packed_hash(ptIn), chacha20.step_out);
assert.deepEqual(DataHasher(http_response_plaintext), chacha20.step_out);

let http = await httpCircuit.compute({ step_in: chacha20.step_out, data: http_response_plaintext, start_line_hash: http_start_line_hash, header_hashes: [http_header_0_hash, http_header_1_hash], body_hash: http_body_mask_hash }, ["step_out"]);
console.log("HttpNIVC `step_out`:", http.step_out);
Expand Down Expand Up @@ -375,7 +375,7 @@ describe("NIVC_FULL_2", async () => {

let chacha20 = await chacha20Circuit.compute({ key: keyIn, nonce: nonceIn, counter: counterBits, plainText: ptIn, cipherText: ctIn, step_in: init_nivc_input }, ["step_out"]);
console.log("ChaCha20 `step_out`:", chacha20.step_out);
assert.deepEqual(chacha20_packed_hash(ptIn), chacha20.step_out);
assert.deepEqual(DataHasher(http_response_plaintext), chacha20.step_out);

let http = await httpCircuit.compute({ step_in: chacha20.step_out, data: http_response_plaintext, start_line_hash: http_start_line_hash, header_hashes: [http_header_0_hash, http_header_1_hash], body_hash: http_body_mask_hash }, ["step_out"]);
console.log("HttpNIVC `step_out`:", http.step_out);
Expand Down
23 changes: 22 additions & 1 deletion circuits/test/utils/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,4 +461,25 @@ describe("ToBlocks", () => {
}
);
});
});
});


describe("fromLittleEndianToWords32", () => {
let circuit: WitnessTester<["data"], ["words"]>;
it("fromLittleEndianToWords32", async () => {
circuit = await circomkit.WitnessTester(`fromLittleEndianToWords32`, {
file: "utils/array",
template: "fromLittleEndianToWords32",
});
console.log("#constraints:", await circuit.getConstraintCount());

let input = [
0, 1, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 0, 0, 1,
0, 1, 0, 1, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0
];
await circuit.expectPass({data: input}, {words: [72, 84, 84, 80]})
});
});

21 changes: 21 additions & 0 deletions circuits/utils/array.circom
Original file line number Diff line number Diff line change
Expand Up @@ -511,4 +511,25 @@ template IncrementWord() {
carry[i - 1] <== IsGreaterThan[i].out;
}
}
}

// // from little endian to 32 bit words
// // example:
// 0, 1, 0, 1, 0, 0, 0, 0, => 80
// 0, 1, 0, 1, 0, 1, 0, 0, => 84
// 0, 1, 0, 1, 0, 1, 0, 0, => 84
// 0, 1, 0, 0, 1, 0, 0, 0, => 72 // getting ten here
// shoud be encoded as
// 72, 84, 84, 80
template fromLittleEndianToWords32() {
signal input data[32];
signal output words[4];
component Bits2Num[4];
for(var i = 3; i >= 0; i--) {
Bits2Num[i] = Bits2Num(8);
for(var j = 7; j >= 0; j--) {
Bits2Num[i].in[7-j] <== data[i*8 + j];
}
words[3-i] <== Bits2Num[i].out;
}
}
24 changes: 0 additions & 24 deletions circuits/utils/hash.circom
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,4 @@ template DataHasher(DATA_BYTES) {
hashes[i+1] <== not_to_hash[i] * (hashes[i] - option_hash[i]) + option_hash[i]; // same as: (1 - not_to_hash[i]) * option_hash[i] + not_to_hash[i] * hash[i];
}
out <== hashes[DATA_BYTES \ 16];
}

template ChaCha20DataHasher(DATA_BYTES) {
// TODO: add this assert back after witnesscalc supports
// assert(DATA_BYTES % 16 == 0);
signal input in[DATA_BYTES];
signal output out;

signal not_to_hash[DATA_BYTES \ 16];
signal option_hash[DATA_BYTES \ 16];
signal hashes[DATA_BYTES \ 16 + 1];
hashes[0] <== 0;
for(var i = 0 ; i < DATA_BYTES \ 16 ; i++) {
var packedInput = 0;
for(var j = 0 ; j < 4 ; j++) {
packedInput += in[4 * i + j] * 2**(8*j);
}
log(packedInput);
not_to_hash[i] <== IsZero()(packedInput);
option_hash[i] <== PoseidonChainer()([hashes[i],packedInput]);
hashes[i+1] <== not_to_hash[i] * (hashes[i] - option_hash[i]) + option_hash[i]; // same as: (1 - not_to_hash[i]) * option_hash[i] + not_to_hash[i] * hash[i];
}
out <== hashes[DATA_BYTES \ 16];
log("out", out);
}

0 comments on commit d1df539

Please sign in to comment.