mirror of
https://github.com/arnaucube/go-iden3-crypto.git
synced 2026-02-07 11:36:41 +01:00
implemented optimized poseidon (#38)
* implemented optimized poseidon * added comment to poseidon hash function * deleted poseidonslow
This commit is contained in:
28285
poseidon/constants.go
28285
poseidon/constants.go
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
package poseidon
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
@@ -17,6 +16,19 @@ func zero() *ff.Element {
|
||||
return ff.NewElement()
|
||||
}
|
||||
|
||||
// exp5 performs x^5 mod p
|
||||
// https://eprint.iacr.org/2019/458.pdf page 8
|
||||
func exp5(a *ff.Element) {
|
||||
a.Exp(*a, 5)
|
||||
}
|
||||
|
||||
// exp5state perform exp5 for whole state
|
||||
func exp5state(state []*ff.Element) {
|
||||
for i := 0; i < len(state); i++ {
|
||||
exp5(state[i])
|
||||
}
|
||||
}
|
||||
|
||||
// ark computes Add-Round Key, from the paper https://eprint.iacr.org/2019/458.pdf
|
||||
func ark(state []*ff.Element, c []*ff.Element, it int) {
|
||||
for i := 0; i < len(state); i++ {
|
||||
@@ -24,33 +36,21 @@ func ark(state []*ff.Element, c []*ff.Element, it int) {
|
||||
}
|
||||
}
|
||||
|
||||
// exp5 performs x^5 mod p
|
||||
// https://eprint.iacr.org/2019/458.pdf page 8
|
||||
func exp5(a *ff.Element) {
|
||||
a.Exp(*a, 5)
|
||||
}
|
||||
|
||||
// sbox https://eprint.iacr.org/2019/458.pdf page 6
|
||||
func sbox(nRoundsF, nRoundsP int, state []*ff.Element, i int) {
|
||||
if (i < nRoundsF/2) || (i >= nRoundsF/2+nRoundsP) {
|
||||
for j := 0; j < len(state); j++ {
|
||||
exp5(state[j])
|
||||
}
|
||||
} else {
|
||||
exp5(state[0])
|
||||
}
|
||||
}
|
||||
|
||||
// mix returns [[matrix]] * [vector]
|
||||
func mix(state []*ff.Element, newState []*ff.Element, m [][]*ff.Element) {
|
||||
func mix(state []*ff.Element, t int, m [][]*ff.Element) []*ff.Element {
|
||||
mul := zero()
|
||||
newState := make([]*ff.Element, t)
|
||||
for i := 0; i < t; i++ {
|
||||
newState[i] = zero()
|
||||
}
|
||||
for i := 0; i < len(state); i++ {
|
||||
newState[i].SetUint64(0)
|
||||
for j := 0; j < len(state); j++ {
|
||||
mul.Mul(m[i][j], state[j])
|
||||
mul.Mul(m[j][i], state[j])
|
||||
newState[i].Add(newState[i], mul)
|
||||
}
|
||||
}
|
||||
return newState
|
||||
}
|
||||
|
||||
// Hash computes the Poseidon hash for the given inputs
|
||||
@@ -59,29 +59,56 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
|
||||
if len(inpBI) == 0 || len(inpBI) >= len(NROUNDSP)-1 {
|
||||
return nil, fmt.Errorf("invalid inputs length %d, max %d", len(inpBI), len(NROUNDSP)-1)
|
||||
}
|
||||
if !utils.CheckBigIntArrayInField(inpBI[:]) {
|
||||
return nil, errors.New("inputs values not inside Finite Field")
|
||||
}
|
||||
inp := utils.BigIntArrayToElementArray(inpBI[:])
|
||||
|
||||
nRoundsF := NROUNDSF
|
||||
nRoundsP := NROUNDSP[t-2]
|
||||
C := c.c[t-2]
|
||||
S := c.s[t-2]
|
||||
M := c.m[t-2]
|
||||
P := c.p[t-2]
|
||||
|
||||
state := make([]*ff.Element, t)
|
||||
state[0] = zero()
|
||||
copy(state[1:], inp[:])
|
||||
|
||||
nRoundsF := NROUNDSF
|
||||
nRoundsP := NROUNDSP[t-2]
|
||||
ark(state, C, 0)
|
||||
|
||||
newState := make([]*ff.Element, t)
|
||||
for i := 0; i < t; i++ {
|
||||
newState[i] = zero()
|
||||
for i := 0; i < nRoundsF/2-1; i++ {
|
||||
exp5state(state)
|
||||
ark(state, C, (i+1)*t)
|
||||
state = mix(state, t, M)
|
||||
}
|
||||
exp5state(state)
|
||||
ark(state, C, (nRoundsF/2)*t)
|
||||
state = mix(state, t, P)
|
||||
|
||||
for i := 0; i < nRoundsP; i++ {
|
||||
exp5(state[0])
|
||||
state[0].Add(state[0], C[(nRoundsF/2+1)*t+i])
|
||||
|
||||
mul := zero()
|
||||
newState0 := zero()
|
||||
for j := 0; j < len(state); j++ {
|
||||
mul.Mul(S[(t*2-1)*i+j], state[j])
|
||||
newState0.Add(newState0, mul)
|
||||
}
|
||||
|
||||
for k := 1; k < t; k++ {
|
||||
mul = zero()
|
||||
state[k] = state[k].Add(state[k], mul.Mul(state[0], S[(t*2-1)*i+t+k-1]))
|
||||
}
|
||||
state[0] = newState0
|
||||
}
|
||||
|
||||
// ARK --> SBox --> M, https://eprint.iacr.org/2019/458.pdf pag.5
|
||||
for i := 0; i < nRoundsF+nRoundsP; i++ {
|
||||
ark(state, c.c[t-2], i*t)
|
||||
sbox(nRoundsF, nRoundsP, state, i)
|
||||
mix(state, newState, c.m[t-2])
|
||||
state, newState = newState, state
|
||||
for i := 0; i < nRoundsF/2-1; i++ {
|
||||
exp5state(state)
|
||||
ark(state, C, (nRoundsF/2+1)*t+nRoundsP+i*t)
|
||||
state = mix(state, t, M)
|
||||
}
|
||||
exp5state(state)
|
||||
state = mix(state, t, M)
|
||||
|
||||
rE := state[0]
|
||||
r := big.NewInt(0)
|
||||
rE.ToBigIntRegular(r)
|
||||
|
||||
Reference in New Issue
Block a user