// pragma circom 2.0.0; include "poseidon2_perm.circom"; //------------------------------------------------------------------------------ function min(a,b) { return (a <= b) ? a : b; } //------------------------------------------------------------------------------ // // Poseidon sponge construction // // t = size of state (currently fixed to 3) // c = capacity (1 or 2) // r = rate = t - c // // everything is measured in number of field elements // // we use the padding `10*` from the original Poseidon paper, // and initial state constant zero. Note that this is different // from the "SAFE padding" recommended in the Poseidon2 paper // (which uses `0*` padding and a nontrivial initial state) // template PoseidonSponge(t, capacity, input_len, output_len) { var rate = t - capacity; assert( t == 3); assert( capacity > 0 ); assert( rate > 0 ); assert( capacity < t ); assert( rate < t ); signal input inp[ input_len]; signal output out[output_len]; // round up to rate the input + 1 field element ("10*" padding) var nblocks = ((input_len + 1) + (rate-1)) \ rate; var nout = (output_len + (rate-1)) \ rate; var padded_len = nblocks * rate; signal padded[padded_len]; for(var i=0; i state[m+1]; } var q = min(rate, output_len); for(var i=0; i out[i]; } var out_ptr = rate; for(var n=1; n state[nblocks+n ]; var q = min(rate, output_len-out_ptr); for(var i=0; i out[out_ptr+i]; } out_ptr += rate; } } //------------------------------------------------------------------------------ // // sponge hash with rate=1 // template Poseidon2_sponge_hash_rate_1(n) { signal input inp[n]; signal output out; component sponge = PoseidonSponge(3, 2, n, 1); sponge.inp <== inp; sponge.out[0] ==> out; } // // sponge hash with rate=2 // template Poseidon2_sponge_hash_rate_2(n) { signal input inp[n]; signal output out; component sponge = PoseidonSponge(3, 1, n, 1); sponge.inp <== inp; sponge.out[0] ==> out; } //------------------------------------------------------------------------------