Compare commits

...

2 Commits

Author SHA1 Message Date
arnaucube
f22be3cdee Update Poseidon Hash function names, rm HashBytes
Since Poseidon Hash is used because of compatibility in zkSNARK circuits, due
circuit constraints number, the hash method of [T]*big.Int is the one directly
compatible with the circuits, is the method which have the `Hash` name on it.
The method that can take arbitrary length of []*big.Int putting them in chunks
of [T]*big.Int and iterating, is called `HashSlice`. The `HashBytes` has been
removed, as is a method that will not be used in zkSNARK circuits due high
constraints number.

For zkSNARK circuits, should be used `poseidon.Hash([poseidon.T]*big.Int)`.
2020-07-23 07:59:59 +02:00
Eduard S
2c471ab545 Merge pull request #24 from iden3/fix/hashbytes-err
Poseidon & MiMC7 HashBytes remove return of err
2020-05-25 12:05:45 +02:00
3 changed files with 41 additions and 53 deletions

View File

@@ -231,7 +231,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
A := k.Public().Point()
hmInput := [poseidon.T]*big.Int{R8.X, R8.Y, A.X, A.Y, msg, big.NewInt(int64(0))}
hm, err := poseidon.PoseidonHash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
if err != nil {
panic(err)
}
@@ -248,7 +248,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
// using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
hmInput := [poseidon.T]*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg, big.NewInt(int64(0))}
hm, err := poseidon.PoseidonHash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
if err != nil {
panic(err)
}

View File

@@ -120,8 +120,8 @@ func mix(state [T]*ff.Element, newState [T]*ff.Element, m [T][T]*ff.Element) {
}
}
// PoseidonHash computes the Poseidon hash for the given inputs
func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) {
// Hash computes the Poseidon hash for the given inputs
func Hash(inpBI [T]*big.Int) (*big.Int, error) {
if !utils.CheckBigIntArrayInField(inpBI[:]) {
return nil, errors.New("inputs values not inside Finite Field")
}
@@ -148,9 +148,9 @@ func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) {
return r, nil
}
// Hash performs the Poseidon hash over a ff.Element array
// HashSlice performs the Poseidon hash over a ff.Element array
// in chunks of 5 elements
func Hash(arr []*big.Int) (*big.Int, error) {
func HashSlice(arr []*big.Int) (*big.Int, error) {
r := big.NewInt(int64(1))
for i := 0; i < len(arr); i = i + T - 1 {
var toHash [T]*big.Int
@@ -167,7 +167,7 @@ func Hash(arr []*big.Int) (*big.Int, error) {
toHash[j] = big.NewInt(0)
}
ph, err := PoseidonHash(toHash)
ph, err := Hash(toHash)
if err != nil {
return nil, err
}
@@ -176,26 +176,3 @@ func Hash(arr []*big.Int) (*big.Int, error) {
return r, nil
}
// HashBytes hashes a msg byte slice by blocks of 31 bytes encoded as
// little-endian
func HashBytes(b []byte) *big.Int {
n := 31
bElems := make([]*big.Int, 0, len(b)/n+1)
for i := 0; i < len(b)/n; i++ {
v := big.NewInt(int64(0))
utils.SetBigIntFromLEBytes(v, b[n*i:n*(i+1)])
bElems = append(bElems, v)
}
if len(b)%n != 0 {
v := big.NewInt(int64(0))
utils.SetBigIntFromLEBytes(v, b[(len(b)/n)*n:])
bElems = append(bElems, v)
}
h, err := Hash(bElems)
if err != nil {
panic(err)
}
return h
}

View File

@@ -15,16 +15,31 @@ func TestBlake2bVersion(t *testing.T) {
assert.Equal(t, "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", hex.EncodeToString(h[:]))
}
func TestPoseidon(t *testing.T) {
func TestPoseidonHash(t *testing.T) {
b0 := big.NewInt(0)
b1 := big.NewInt(1)
b2 := big.NewInt(2)
h, err := Hash([]*big.Int{b1, b2})
h, err := Hash([T]*big.Int{b1, b2, b0, b0, b0, b0})
assert.Nil(t, err)
assert.Equal(t, "12242166908188651009877250812424843524687801523336557272219921456462821518061", h.String())
b3 := big.NewInt(3)
b4 := big.NewInt(4)
h, err = Hash([T]*big.Int{b3, b4, b0, b0, b0, b0})
assert.Nil(t, err)
assert.Equal(t, "17185195740979599334254027721507328033796809509313949281114643312710535000993", h.String())
}
func TestPoseidonHashArbitraryLen(t *testing.T) {
b1 := big.NewInt(1)
b2 := big.NewInt(2)
h, err := HashSlice([]*big.Int{b1, b2})
assert.Nil(t, err)
assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154855", h.String())
b3 := big.NewInt(3)
b4 := big.NewInt(4)
h, err = Hash([]*big.Int{b3, b4})
h, err = HashSlice([]*big.Int{b3, b4})
assert.Nil(t, err)
assert.Equal(t, "4635491972858758537477743930622086396911540895966845494943021655521913507504", h.String())
@@ -36,7 +51,7 @@ func TestPoseidon(t *testing.T) {
b10 := big.NewInt(10)
b11 := big.NewInt(11)
b12 := big.NewInt(12)
h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12})
h, err = HashSlice([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12})
assert.Nil(t, err)
assert.Equal(t, "15278801138972282646981503374384603641625274360649669926363020545395022098027", h.String())
@@ -53,7 +68,7 @@ func TestPoseidon(t *testing.T) {
utils.SetBigIntFromLEBytes(v, msg[(len(msg)/n)*n:])
msgElems = append(msgElems, v)
}
hmsg, err := Hash(msgElems)
hmsg, err := HashSlice(msgElems)
assert.Nil(t, err)
assert.Equal(t, "16019700159595764790637132363672701294192939959594423814006267756172551741065", hmsg.String())
@@ -69,33 +84,30 @@ func TestPoseidon(t *testing.T) {
utils.SetBigIntFromLEBytes(v, msg2[(len(msg2)/n)*n:])
msg2Elems = append(msg2Elems, v)
}
hmsg2, err := Hash(msg2Elems)
hmsg2, err := HashSlice(msg2Elems)
assert.Nil(t, err)
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
hmsg2 = HashBytes(msg2)
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
}
func TestPoseidonBrokenChunks(t *testing.T) {
h1, err := Hash([]*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4),
func TestPoseidonHashArbitraryLenBrokenChunks(t *testing.T) {
h1, err := HashSlice([]*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4),
big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9)})
assert.Nil(t, err)
h2, err := Hash([]*big.Int{big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9),
h2, err := HashSlice([]*big.Int{big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9),
big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4)})
assert.Nil(t, err)
assert.NotEqual(t, h1, h2)
}
func TestPoseidonBrokenPadding(t *testing.T) {
h1, err := Hash([]*big.Int{big.NewInt(int64(1))})
func TestPoseidonHashArbitraryLenBrokenPadding(t *testing.T) {
h1, err := HashSlice([]*big.Int{big.NewInt(int64(1))})
assert.Nil(t, err)
h2, err := Hash([]*big.Int{big.NewInt(int64(1)), big.NewInt(int64(0))})
h2, err := HashSlice([]*big.Int{big.NewInt(int64(1)), big.NewInt(int64(0))})
assert.Nil(t, err)
assert.NotEqual(t, h1, h2)
}
func BenchmarkPoseidon(b *testing.B) {
func BenchmarkPoseidonHashSmallValues(b *testing.B) {
b12 := big.NewInt(int64(12))
b45 := big.NewInt(int64(45))
b78 := big.NewInt(int64(78))
@@ -103,17 +115,16 @@ func BenchmarkPoseidon(b *testing.B) {
bigArray4 := []*big.Int{b12, b45, b78, b41}
for i := 0; i < b.N; i++ {
Hash(bigArray4) //nolint:errcheck
HashSlice(bigArray4) //nolint:errcheck
}
}
func BenchmarkPoseidonLarge(b *testing.B) {
b12 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
b45 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
b78 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
b41 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
func BenchmarkPoseidonHash(b *testing.B) {
b0 := big.NewInt(0)
b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061")
b2 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061")
bigArray4 := []*big.Int{b12, b45, b78, b41}
bigArray4 := [T]*big.Int{b1, b2, b0, b0, b0, b0}
for i := 0; i < b.N; i++ {
Hash(bigArray4) //nolint:errcheck