mirror of
https://github.com/arnaucube/keccak256-circom.git
synced 2026-01-10 16:01:28 +01:00
Add Circom Pad impl
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# keccak256-circom [](https://github.com/arnaucube/keccak256-circom/actions?query=workflow%3ATest)
|
||||
|
||||
WIP repo. Once ready, will do a PR into [circomlib](https://github.com/iden3/circomlib).
|
||||
Keccak256 hash function (ethereum version) implemented in [circom](https://github.com/iden3/circom). Spec: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
|
||||
**Warning**: WIP, this is an experimental repo.
|
||||
|
||||
Spec: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
|
||||
46
circuits/keccak256.circom
Normal file
46
circuits/keccak256.circom
Normal file
@@ -0,0 +1,46 @@
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "./utils.circom";
|
||||
|
||||
template Pad(nBits) {
|
||||
signal input in[nBits];
|
||||
var blockSize=136*8;
|
||||
signal output out[blockSize];
|
||||
signal out2[blockSize];
|
||||
var i;
|
||||
|
||||
for (i=0; i<nBits; i++) {
|
||||
out2[i] <== in[i];
|
||||
}
|
||||
var domain = 0x01;
|
||||
for (i=0; i<8; i++) {
|
||||
out2[nBits+i] <== (domain >> i) & 1;
|
||||
}
|
||||
for (i=nBits+8; i<blockSize; i++) {
|
||||
out2[i] <== 0;
|
||||
}
|
||||
component aux = OrArray(8);
|
||||
for (i=0; i<8; i++) {
|
||||
aux.a[i] <== out2[blockSize-8+i];
|
||||
aux.b[i] <== (0x80 >> i) & 1;
|
||||
}
|
||||
for (i=0; i<8; i++) {
|
||||
out[blockSize-8+i] <== aux.out[i];
|
||||
}
|
||||
for (i=0; i<blockSize-8; i++) {
|
||||
out[i]<==out2[i];
|
||||
}
|
||||
}
|
||||
|
||||
template Keccak256(nBits) {
|
||||
signal input in[nBits];
|
||||
signal output out[256];
|
||||
var i;
|
||||
|
||||
// pad
|
||||
component pad = Pad(nBits);
|
||||
for (i=0; i<nBits; i++) {
|
||||
pad.in[i] <== in[i];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package keccak
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
@@ -23,3 +24,29 @@ func testKeccak(t *testing.T, input []byte, expectedHex string) {
|
||||
qt.Assert(t, h, qt.DeepEquals, expected)
|
||||
qt.Assert(t, hex.EncodeToString(h), qt.Equals, expectedHex)
|
||||
}
|
||||
|
||||
func TestPad(t *testing.T) {
|
||||
b := make([]byte, 32)
|
||||
for i := 0; i < len(b); i++ {
|
||||
b[i] = byte(i)
|
||||
}
|
||||
fmt.Println(b)
|
||||
bBits := bytesToBits(b)
|
||||
fBits := pad(bBits)
|
||||
|
||||
qt.Assert(t, bitsToBytes(fBits[:]), qt.DeepEquals,
|
||||
[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128})
|
||||
}
|
||||
|
||||
func TestFinal(t *testing.T) {
|
||||
b := make([]byte, 32)
|
||||
for i := 0; i < len(b); i++ {
|
||||
b[i] = byte(i)
|
||||
}
|
||||
fmt.Println(b)
|
||||
bBits := bytesToBits(b)
|
||||
fBits := final(bBits)
|
||||
|
||||
qt.Assert(t, bitsToU64Array(fBits[:]), qt.DeepEquals,
|
||||
[]uint64{16953415415620100490, 7495738965189503699, 12723370805759944158, 3295955328722933810, 12121371508560456016, 174876831679863147, 15944933357501475584, 7502339663607726274, 12048918224562833898, 16715284461100269102, 15582559130083209842, 1743886467337678829, 2424196198791253761, 1116417308245482383, 10367365997906434042, 1849801549382613906, 13294939539683415102, 4478091053375708790, 2969967870313332958, 14618962068930014237, 2721742233407503451, 12003265593030191290, 8109318293656735684, 6346795302983965746, 12210038122000333046})
|
||||
}
|
||||
|
||||
5
test/circuits/pad_test.circom
Normal file
5
test/circuits/pad_test.circom
Normal file
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "../../circuits/keccak256.circom";
|
||||
|
||||
component main = Pad(32*8);
|
||||
@@ -218,3 +218,24 @@ describe("Iota test", function () {
|
||||
assert.deepEqual(stateOutU64, expectedOut);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Keccak-Pad test", function () {
|
||||
this.timeout(100000);
|
||||
|
||||
it ("Pad (testvector generated from go)", async () => {
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "pad_test.circom"));
|
||||
|
||||
const input = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
|
||||
const expectedOut = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128];
|
||||
|
||||
const stateIn = bytesToBits(input);
|
||||
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true);
|
||||
|
||||
const stateOut = witness.slice(1, 1+(136*8));
|
||||
const stateOutBytes = bitsToBytes(stateOut);
|
||||
// console.log(stateOutBytes, expectedOut);
|
||||
assert.deepEqual(stateOutBytes, expectedOut);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user