mirror of
https://github.com/arnaucube/keccak256-circom.git
synced 2026-01-11 08:21:32 +01:00
Different nBits for keccak input&output
This commit is contained in:
25
README.md
25
README.md
@@ -4,3 +4,28 @@ Keccak256 hash function (ethereum version) implemented in [circom](https://githu
|
||||
|
||||
**Warning**: WIP, this is an experimental repo.
|
||||
|
||||
## Status
|
||||
Initial version works, compatible with Ethereum version of Keccak256.
|
||||
|
||||
It needs around `150848` (`151k`) constraints.
|
||||
> For context: [Rapidsnark](https://github.com/iden3/rapidsnark) proof generation time:
|
||||
> - 1.1M constraints -> 7 seconds (8 CPU)
|
||||
> - 128M constraints -> <2min (64 CPU)
|
||||
|
||||
## Usage
|
||||
- import the lib in the `package.json`:
|
||||
```
|
||||
"dependencies": {
|
||||
"keccak256-circom": "git+https://github.com/vocdoni/keccak256-circom"
|
||||
}
|
||||
```
|
||||
|
||||
- Usage:
|
||||
```
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "../node_modules/keccak256-circom/circuits/keccak.circom";
|
||||
|
||||
// for a input & output of 32 bytes:
|
||||
component main = Keccak(32*8, 32*8);
|
||||
```
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// Keccak256 hash function (ethereum version).
|
||||
// For LICENSE check https://github.com/vocdoni/keccak256-circom/blob/master/LICENSE
|
||||
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "./utils.circom";
|
||||
@@ -164,20 +167,20 @@ template Keccakf() {
|
||||
}
|
||||
}
|
||||
|
||||
template Keccak(nBits) {
|
||||
signal input in[nBits];
|
||||
signal output out[nBits];
|
||||
template Keccak(nBitsIn, nBitsOut) {
|
||||
signal input in[nBitsIn];
|
||||
signal output out[nBitsOut];
|
||||
var i;
|
||||
|
||||
component f = Final(nBits);
|
||||
for (i=0; i<nBits; i++) {
|
||||
component f = Final(nBitsIn);
|
||||
for (i=0; i<nBitsIn; i++) {
|
||||
f.in[i] <== in[i];
|
||||
}
|
||||
component squeeze = Squeeze(nBits);
|
||||
component squeeze = Squeeze(nBitsOut);
|
||||
for (i=0; i<25*64; i++) {
|
||||
squeeze.s[i] <== f.out[i];
|
||||
}
|
||||
for (i=0; i<nBits; i++) {
|
||||
for (i=0; i<nBitsOut; i++) {
|
||||
out[i] <== squeeze.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// Keccak256 hash function (ethereum version).
|
||||
// For LICENSE check https://github.com/vocdoni/keccak256-circom/blob/master/LICENSE
|
||||
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "./utils.circom";
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// Keccak256 hash function (ethereum version).
|
||||
// For LICENSE check https://github.com/vocdoni/keccak256-circom/blob/master/LICENSE
|
||||
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "../node_modules/circomlib/circuits/gates.circom";
|
||||
|
||||
5
test/circuits/keccak_256_256_test.circom
Normal file
5
test/circuits/keccak_256_256_test.circom
Normal file
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "../../circuits/keccak.circom";
|
||||
|
||||
component main = Keccak(32*8, 32*8);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.0.0;
|
||||
|
||||
include "../../circuits/keccak.circom";
|
||||
|
||||
component main = Keccak(32*8);
|
||||
component main = Keccak(4*8, 32*8);
|
||||
@@ -8,12 +8,12 @@ const c_tester = require("circom_tester").c;
|
||||
const utils = require("./utils");
|
||||
const keccak256 = require("keccak256");
|
||||
|
||||
describe("Keccak full hash test", function () {
|
||||
describe("Keccak 32bytes full hash test", function () {
|
||||
this.timeout(100000);
|
||||
|
||||
let cir;
|
||||
before(async () => {
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "keccak256_test.circom"));
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "keccak_256_256_test.circom"));
|
||||
await cir.loadConstraints();
|
||||
console.log("n_constraints", cir.constraints.length);
|
||||
});
|
||||
@@ -109,3 +109,50 @@ describe("Keccak full hash test", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Keccak input: 4bytes, output: 32bytes, full hash test", function () {
|
||||
this.timeout(100000);
|
||||
|
||||
let cir;
|
||||
before(async () => {
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "keccak_32_256_test.circom"));
|
||||
await cir.loadConstraints();
|
||||
console.log("n_constraints", cir.constraints.length);
|
||||
});
|
||||
|
||||
it ("Keccak inputSize==32bits: 1 (testvector generated from go)", async () => {
|
||||
const input = [116, 101, 115, 116];
|
||||
const expectedOut = [156, 34, 255, 95, 33, 240, 184, 27, 17, 62, 99,
|
||||
247, 219, 109, 169, 79, 237, 239, 17, 178, 17, 155, 64, 136, 184,
|
||||
150, 100, 251, 154, 60, 182, 88];
|
||||
|
||||
const inIn = utils.bytesToBits(input);
|
||||
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true);
|
||||
|
||||
const stateOut = witness.slice(1, 1+(32*8));
|
||||
const stateOutBytes = utils.bitsToBytes(stateOut);
|
||||
// console.log(stateOutBytes, expectedOut);
|
||||
assert.deepEqual(stateOutBytes, expectedOut);
|
||||
});
|
||||
|
||||
it ("Keccak256 inputSize==32bits, circom-js 1", async () => {
|
||||
let input, inputBits, expectedOut, witness, stateOut, stateOutBytes;
|
||||
input = Buffer.from("test");
|
||||
for(let i=0; i<10; i++) {
|
||||
inputBits = utils.bytesToBits(input);
|
||||
|
||||
let jsOutRaw = keccak256(input);
|
||||
expectedOut = utils.bufferToBytes(jsOutRaw);
|
||||
console.log(i, "in:", input.toString('hex'), "\n out:", jsOutRaw.toString('hex'));
|
||||
|
||||
witness = await cir.calculateWitness({ "in": inputBits }, true);
|
||||
stateOut = witness.slice(1, 1+(32*8));
|
||||
stateOutBytes = utils.bitsToBytes(stateOut);
|
||||
assert.deepEqual(stateOutBytes, expectedOut);
|
||||
|
||||
// assign output[0:4] into input for next iteration
|
||||
input = jsOutRaw.slice(0, 4);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user