mirror of
https://github.com/arnaucube/keccak256-circom.git
synced 2026-01-10 16:01:28 +01:00
Absorb circuit implemented
This commit is contained in:
@@ -65,6 +65,38 @@ template KeccakfRound(r) {
|
||||
}
|
||||
}
|
||||
|
||||
template Absorb() {
|
||||
var blockSizeBytes=136;
|
||||
|
||||
signal input s[25*64];
|
||||
signal input block[blockSizeBytes*8];
|
||||
signal output out[25*64];
|
||||
var i;
|
||||
var j;
|
||||
|
||||
component aux[blockSizeBytes/8];
|
||||
component newS = Keccakf();
|
||||
|
||||
for (i=0; i<blockSizeBytes/8; i++) {
|
||||
aux[i] = XorArray(64);
|
||||
for (j=0; j<64; j++) {
|
||||
aux[i].a[j] <== s[i*64+j];
|
||||
aux[i].b[j] <== block[i*64+j];
|
||||
}
|
||||
for (j=0; j<64; j++) {
|
||||
newS.in[i*64+j] <== aux[i].out[j];
|
||||
}
|
||||
}
|
||||
// fill the missing s that was not covered by the loop over
|
||||
// blockSizeBytes/8
|
||||
for (i=(blockSizeBytes/8)*64; i<25*64; i++) {
|
||||
newS.in[i] <== s[i];
|
||||
}
|
||||
for (i=0; i<25*64; i++) {
|
||||
out[i] <== newS.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template Keccakf() {
|
||||
signal input in[25*64];
|
||||
signal output out[25*64];
|
||||
|
||||
@@ -2,6 +2,7 @@ package keccak
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
@@ -107,6 +108,62 @@ func TestKeccakf(t *testing.T) {
|
||||
13518516210247555620})
|
||||
}
|
||||
|
||||
func printBytes(name string, b []byte) {
|
||||
fmt.Printf("%s\n", name)
|
||||
for _, v := range b {
|
||||
fmt.Printf("\"%v\", ", v)
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
func printU64Array(name string, b []uint64) {
|
||||
fmt.Printf("%s\n", name)
|
||||
for _, v := range b {
|
||||
fmt.Printf("\"%v\", ", v)
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func TestAbsorb(t *testing.T) {
|
||||
s, _ := newS()
|
||||
block := []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}
|
||||
// printU64Array("s", bitsToU64Array(s[:]))
|
||||
// printBytes("block", block[:])
|
||||
|
||||
absorbed := absorb(s, bytesToBits(block))
|
||||
// printU64Array("absorbed", bitsToU64Array(absorbed[:]))
|
||||
|
||||
qt.Assert(t, bitsToU64Array(absorbed[:]), qt.DeepEquals,
|
||||
[]uint64{8342348566319207042, 319359607942176202, 14410076088654599075,
|
||||
15666111399434436772, 9558421567405313402, 3396178318116504023,
|
||||
794353847439963108, 12717011319735989377, 3503398863218919239,
|
||||
5517201702366862678, 15999361614129160496, 1325524015888689985,
|
||||
11971708408118944333, 14874486179441062217, 12554876384974234666,
|
||||
11129975558302206043, 11257826431949606534, 2740710607956478714,
|
||||
15000019752453010167, 15593606854132419294, 2598425978562809333,
|
||||
8872504799797239246, 1212062965004664308, 5443427421087086722,
|
||||
10946808592826700411})
|
||||
|
||||
absorbed = absorb(absorbed, bytesToBits(block))
|
||||
// printU64Array("absorbed", bitsToU64Array(absorbed[:]))
|
||||
|
||||
qt.Assert(t, bitsToU64Array(absorbed[:]), qt.DeepEquals,
|
||||
[]uint64{8909243822027471379, 1111840847970088140,
|
||||
12093072708540612559, 11255033638786021658, 2082116894939842214,
|
||||
12821085060245261575, 6901785969834988344, 3182430130277914993,
|
||||
2164708585929408975, 14402143231999718904, 16231444410553803968,
|
||||
1850945423480060493, 12856855675247400303, 1137248620532111171,
|
||||
7389129221921446308, 12932467982741614601, 1350606937385760406,
|
||||
10983682292859713641, 10305595434820307765, 13958651111365489854,
|
||||
17206620388135196198, 4238113785249530092, 7230868147643218103,
|
||||
603011106238724524, 16480095441097880488})
|
||||
}
|
||||
|
||||
func TestFinal(t *testing.T) {
|
||||
b := make([]byte, 32)
|
||||
for i := 0; i < len(b); i++ {
|
||||
|
||||
5
test/circuits/absorb_test.circom
Normal file
5
test/circuits/absorb_test.circom
Normal file
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "../../circuits/keccak256.circom";
|
||||
|
||||
component main = Absorb();
|
||||
@@ -350,12 +350,15 @@ describe("keccakfRound test", function () {
|
||||
describe("keccakf test", function () {
|
||||
this.timeout(100000);
|
||||
|
||||
it ("keccakf 1 (testvector generated from go)", async () => {
|
||||
let cir;
|
||||
before(async () => {
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
await cir.loadConstraints();
|
||||
console.log("n_constraints", cir.constraints.length);
|
||||
});
|
||||
|
||||
it ("keccakf 1 (testvector generated from go)", async () => {
|
||||
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];
|
||||
const expectedOut = strsToBigInts(["9472389783892099349", "2159377575142921216", "17826682512249813373", "2325963263767348549", "15086930817298358378", "11661812091723830419", "3517755057770134847", "5223775837645169598", "933274647126506074", "3451250694486589320", "825065683101361807", "6192414258352188799", "14426505790672879210", "3326742392640380689", "16749975585634164134", "17847697619892908514", "11598434253200954839", "6049795840392747215", "8610635351954084385", "18234131770974529925", "15330347418010067760", "12047099911907354591", "4763389569697138851", "6779624089296570504", "15083668107635345971"]);
|
||||
|
||||
@@ -371,11 +374,6 @@ describe("keccakf test", function () {
|
||||
});
|
||||
|
||||
it ("keccakf 2 (testvector generated from go)", async () => {
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
await cir.loadConstraints();
|
||||
console.log("n_constraints", cir.constraints.length);
|
||||
|
||||
const input = strsToBigInts(["9472389783892099349", "2159377575142921216", "17826682512249813373", "2325963263767348549", "15086930817298358378", "11661812091723830419", "3517755057770134847", "5223775837645169598", "933274647126506074", "3451250694486589320", "825065683101361807", "6192414258352188799", "14426505790672879210", "3326742392640380689", "16749975585634164134", "17847697619892908514", "11598434253200954839", "6049795840392747215", "8610635351954084385", "18234131770974529925", "15330347418010067760", "12047099911907354591", "4763389569697138851", "6779624089296570504", "15083668107635345971"]);
|
||||
const expectedOut = strsToBigInts(["269318771259381490", "15892848561416382510", "12485559500958802382", "4360182510883008729", "14284025675983944434", "8800366419087562177", "7881853509112258378", "9503857914080778528", "17110477940977988953", "13825318756568052601", "11460650932194163315", "13272167288297399439", "13599957064256729412", "12730838251751851758", "13736647180617564382", "5651695613583298166", "15496251216716036782", "9748494184433838858", "3637745438296580159", "3821184813198767406", "15603239432236101315", "3726326332491237029", "7819962668913661099", "2285898735263816116", "13518516210247555620"]);
|
||||
|
||||
@@ -390,3 +388,54 @@ describe("keccakf test", function () {
|
||||
assert.deepEqual(stateOutU64, expectedOut);
|
||||
});
|
||||
});
|
||||
|
||||
describe("absorb test", function () {
|
||||
this.timeout(100000);
|
||||
|
||||
let cir;
|
||||
|
||||
before(async () => {
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "absorb_test.circom"));
|
||||
await cir.loadConstraints();
|
||||
console.log("n_constraints", cir.constraints.length);
|
||||
});
|
||||
|
||||
it ("absorb 1 (testvector generated from go)", async () => {
|
||||
const s = strsToBigInts(["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"]);
|
||||
|
||||
const block = strsToBigInts(["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 expectedOut = strsToBigInts(["8342348566319207042", "319359607942176202", "14410076088654599075", "15666111399434436772", "9558421567405313402", "3396178318116504023", "794353847439963108", "12717011319735989377", "3503398863218919239", "5517201702366862678", "15999361614129160496", "1325524015888689985", "11971708408118944333", "14874486179441062217", "12554876384974234666", "11129975558302206043", "11257826431949606534", "2740710607956478714", "15000019752453010167", "15593606854132419294", "2598425978562809333","8872504799797239246", "1212062965004664308", "5443427421087086722", "10946808592826700411"]);
|
||||
|
||||
const sIn = u64ArrayToBits(s);
|
||||
const blockIn = bytesToBits(block);
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut);
|
||||
|
||||
const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true);
|
||||
|
||||
const stateOut = witness.slice(1, 1+(25*64));
|
||||
const stateOutU64 = bitsToU64Array(stateOut);
|
||||
// console.log(stateOutU64, expectedOut);
|
||||
assert.deepEqual(stateOutU64, expectedOut);
|
||||
});
|
||||
|
||||
it ("absorb 2 (testvector generated from go)", async () => {
|
||||
const s = strsToBigInts(["8342348566319207042", "319359607942176202", "14410076088654599075", "15666111399434436772", "9558421567405313402", "3396178318116504023", "794353847439963108", "12717011319735989377", "3503398863218919239", "5517201702366862678", "15999361614129160496", "1325524015888689985", "11971708408118944333", "14874486179441062217", "12554876384974234666", "11129975558302206043", "11257826431949606534", "2740710607956478714", "15000019752453010167", "15593606854132419294", "2598425978562809333","8872504799797239246", "1212062965004664308", "5443427421087086722", "10946808592826700411"]);
|
||||
|
||||
const block = strsToBigInts(["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 expectedOut = strsToBigInts(["8909243822027471379", "1111840847970088140", "12093072708540612559", "11255033638786021658", "2082116894939842214", "12821085060245261575", "6901785969834988344", "3182430130277914993", "2164708585929408975", "14402143231999718904", "16231444410553803968", "1850945423480060493", "12856855675247400303", "1137248620532111171", "7389129221921446308", "12932467982741614601", "1350606937385760406", "10983682292859713641", "10305595434820307765", "13958651111365489854", "17206620388135196198", "4238113785249530092", "7230868147643218103", "603011106238724524", "16480095441097880488"]);
|
||||
|
||||
const sIn = u64ArrayToBits(s);
|
||||
const blockIn = bytesToBits(block);
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut);
|
||||
|
||||
const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true);
|
||||
|
||||
const stateOut = witness.slice(1, 1+(25*64));
|
||||
const stateOutU64 = bitsToU64Array(stateOut);
|
||||
// console.log(stateOutU64, expectedOut);
|
||||
assert.deepEqual(stateOutU64, expectedOut);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user