Compare commits

...

5 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
arnaucube
e134988b1b Rm .travis.yml 2020-05-22 13:33:01 +02:00
arnaucube
3a9171000b Poseidon & MiMC7 HashBytes remove return of err 2020-05-22 00:42:14 +02:00
Eduard S
b1468fc076 Merge pull request #23 from iden3/feature/expose-method
Expose SkToBigInt for usage from other packages & repos
2020-04-28 18:31:15 +02:00
6 changed files with 48 additions and 69 deletions

View File

@@ -1,15 +0,0 @@
dist: xenial
language: go
go:
- "1.12"
jobs:
include:
- name: "Unit Tests 64 bit arch"
env: GOARCH="amd64"
- name: "Unit Test 32 bit arch"
env: GOARCH="386"
env:
- GO111MODULE=on

View File

@@ -231,7 +231,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
A := k.Public().Point() A := k.Public().Point()
hmInput := [poseidon.T]*big.Int{R8.X, R8.Y, A.X, A.Y, msg, big.NewInt(int64(0))} 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 { if err != nil {
panic(err) 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. // using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool { 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))} 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 { if err != nil {
panic(err) panic(err)
} }

View File

@@ -137,7 +137,7 @@ func Hash(arr []*big.Int, key *big.Int) (*big.Int, error) {
// HashBytes hashes a msg byte slice by blocks of 31 bytes encoded as // HashBytes hashes a msg byte slice by blocks of 31 bytes encoded as
// little-endian // little-endian
func HashBytes(b []byte) (*big.Int, error) { func HashBytes(b []byte) *big.Int {
n := 31 n := 31
bElems := make([]*big.Int, 0, len(b)/n+1) bElems := make([]*big.Int, 0, len(b)/n+1)
for i := 0; i < len(b)/n; i++ { for i := 0; i < len(b)/n; i++ {
@@ -150,5 +150,9 @@ func HashBytes(b []byte) (*big.Int, error) {
utils.SetBigIntFromLEBytes(v, b[(len(b)/n)*n:]) utils.SetBigIntFromLEBytes(v, b[(len(b)/n)*n:])
bElems = append(bElems, v) bElems = append(bElems, v)
} }
return Hash(bElems, nil) h, err := Hash(bElems, nil)
if err != nil {
panic(err)
}
return h
} }

View File

@@ -74,8 +74,7 @@ func TestMIMC7(t *testing.T) {
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h4).Bytes()), "0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb") assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h4).Bytes()), "0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb")
msg := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") msg := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
hmsg, err := HashBytes(msg) hmsg := HashBytes(msg)
assert.Nil(t, err)
assert.Equal(t, "16855787120419064316734350414336285711017110414939748784029922801367685456065", hmsg.String()) assert.Equal(t, "16855787120419064316734350414336285711017110414939748784029922801367685456065", hmsg.String())
} }

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 // Hash computes the Poseidon hash for the given inputs
func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) { func Hash(inpBI [T]*big.Int) (*big.Int, error) {
if !utils.CheckBigIntArrayInField(inpBI[:]) { if !utils.CheckBigIntArrayInField(inpBI[:]) {
return nil, errors.New("inputs values not inside Finite Field") 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 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 // 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)) r := big.NewInt(int64(1))
for i := 0; i < len(arr); i = i + T - 1 { for i := 0; i < len(arr); i = i + T - 1 {
var toHash [T]*big.Int var toHash [T]*big.Int
@@ -167,7 +167,7 @@ func Hash(arr []*big.Int) (*big.Int, error) {
toHash[j] = big.NewInt(0) toHash[j] = big.NewInt(0)
} }
ph, err := PoseidonHash(toHash) ph, err := Hash(toHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -176,22 +176,3 @@ func Hash(arr []*big.Int) (*big.Int, error) {
return r, nil return r, nil
} }
// HashBytes hashes a msg byte slice by blocks of 31 bytes encoded as
// little-endian
func HashBytes(b []byte) (*big.Int, error) {
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)
}
return Hash(bElems)
}

View File

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