mirror of
https://github.com/arnaucube/go-iden3-crypto.git
synced 2026-02-07 11:36:41 +01:00
Poseidon Sponge Hash with different frame sizes (#52)
* Poseidon Sponge Hash with different frame sizes * Update deps. Bump go version * Update & fix linter. * Refactor a bit. * Reduce gc pressure
This commit is contained in:
committed by
GitHub
parent
edc36bfa52
commit
e5cf066b8b
22
.github/workflows/lint.yml
vendored
22
.github/workflows/lint.yml
vendored
@@ -1,16 +1,18 @@
|
|||||||
name: Lint
|
name: Lint
|
||||||
on: [ push, pull_request ]
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
- uses: actions/checkout@v3
|
||||||
uses: actions/setup-go@v1
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.16.x
|
go-version: 1.20.x
|
||||||
- name: Checkout code
|
- uses: golangci/golangci-lint-action@v3
|
||||||
uses: actions/checkout@v2
|
with:
|
||||||
- name: Lint
|
version: v1.51.1
|
||||||
run: |
|
|
||||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
|
|
||||||
$(go env GOPATH)/bin/golangci-lint run --timeout=5m -c .golangci.yml
|
|
||||||
|
|||||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -4,7 +4,7 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: [ 1.16.x, 1.17.x ]
|
go-version: [ 1.18.x, 1.19.x, 1.20.x ]
|
||||||
goarch: [ "amd64", "386" ]
|
goarch: [ "amd64", "386" ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -1,17 +1,77 @@
|
|||||||
issues:
|
service:
|
||||||
max-same-issues: 0
|
golangci-lint-version: 1.51.x
|
||||||
exclude-use-default: false
|
|
||||||
linters:
|
run:
|
||||||
enable:
|
timeout: 2m
|
||||||
- whitespace
|
skip-dirs:
|
||||||
- gosec
|
- vendor
|
||||||
- gci
|
|
||||||
- misspell
|
|
||||||
- gomnd
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
- lll
|
|
||||||
- golint
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
lll:
|
govet:
|
||||||
line-length: 100
|
check-shadowing: true
|
||||||
|
revive:
|
||||||
|
min-confidence: 0.1
|
||||||
|
rules:
|
||||||
|
- name: package-comments
|
||||||
|
disabled: true
|
||||||
|
maligned:
|
||||||
|
suggest-new: true
|
||||||
|
goconst:
|
||||||
|
min-len: 2
|
||||||
|
min-occurrences: 2
|
||||||
|
misspell:
|
||||||
|
locale: US
|
||||||
|
lll:
|
||||||
|
line-length: 140
|
||||||
|
gocritic:
|
||||||
|
enabled-tags:
|
||||||
|
- performance
|
||||||
|
- style
|
||||||
|
- experimental
|
||||||
|
disabled-checks:
|
||||||
|
- hugeParam
|
||||||
|
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
- bodyclose
|
||||||
|
- megacheck
|
||||||
|
- revive
|
||||||
|
- govet
|
||||||
|
- unconvert
|
||||||
|
- megacheck
|
||||||
|
- gas
|
||||||
|
- gocyclo
|
||||||
|
- dupl
|
||||||
|
- misspell
|
||||||
|
- unparam
|
||||||
|
- typecheck
|
||||||
|
- ineffassign
|
||||||
|
- stylecheck
|
||||||
|
- exportloopref
|
||||||
|
- nakedret
|
||||||
|
- gosimple
|
||||||
|
- prealloc
|
||||||
|
- unused
|
||||||
|
|
||||||
|
## format - fill free to fix
|
||||||
|
# - errcheck
|
||||||
|
# - gofmt
|
||||||
|
# - goimports
|
||||||
|
fast: false
|
||||||
|
disable-all: true
|
||||||
|
|
||||||
|
issues:
|
||||||
|
exclude-rules:
|
||||||
|
# - Fix and remove
|
||||||
|
- text: "at least one file in a package should have a package comment"
|
||||||
|
linters:
|
||||||
|
- stylecheck
|
||||||
|
# - Fix and remove
|
||||||
|
- text: "should have a package comment, unless it's in another file for this package"
|
||||||
|
linters:
|
||||||
|
- revive
|
||||||
|
- path: _test\.go
|
||||||
|
linters:
|
||||||
|
- gosec
|
||||||
|
- dupl
|
||||||
|
exclude-use-default: false
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (p *PointProjective) Affine() *Point {
|
|||||||
|
|
||||||
// Add computes the addition of two points in projective coordinates
|
// Add computes the addition of two points in projective coordinates
|
||||||
// representation
|
// representation
|
||||||
func (p *PointProjective) Add(q *PointProjective, o *PointProjective) *PointProjective {
|
func (p *PointProjective) Add(q, o *PointProjective) *PointProjective {
|
||||||
// add-2008-bbjlp
|
// add-2008-bbjlp
|
||||||
// https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp
|
||||||
a := ff.NewElement().Mul(q.Z, o.Z)
|
a := ff.NewElement().Mul(q.Z, o.Z)
|
||||||
@@ -209,7 +209,7 @@ func PointCoordSign(c *big.Int) bool {
|
|||||||
func PackSignY(sign bool, y *big.Int) [32]byte {
|
func PackSignY(sign bool, y *big.Int) [32]byte {
|
||||||
leBuf := utils.BigIntLEBytes(y)
|
leBuf := utils.BigIntLEBytes(y)
|
||||||
if sign {
|
if sign {
|
||||||
leBuf[31] = leBuf[31] | 0x80 //nolint:gomnd
|
leBuf[31] |= 0x80 //nolint:gomnd
|
||||||
}
|
}
|
||||||
return leBuf
|
return leBuf
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ func UnpackSignY(leBuf [32]byte) (bool, *big.Int) {
|
|||||||
y := big.NewInt(0)
|
y := big.NewInt(0)
|
||||||
if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd
|
if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd
|
||||||
sign = true
|
sign = true
|
||||||
leBuf[31] = leBuf[31] & 0x7F //nolint:gomnd
|
leBuf[31] &= 0x7F //nolint:gomnd
|
||||||
}
|
}
|
||||||
utils.SetBigIntFromLEBytes(y, leBuf[:])
|
utils.SetBigIntFromLEBytes(y, leBuf[:])
|
||||||
return sign, y
|
return sign, y
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Package babyjub eddsa implements the EdDSA over the BabyJubJub curve
|
// Package babyjub eddsa implements the EdDSA over the BabyJubJub curve
|
||||||
|
//
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
package babyjub
|
package babyjub
|
||||||
|
|
||||||
@@ -16,9 +17,9 @@ import (
|
|||||||
// pruneBuffer prunes the buffer during key generation according to RFC 8032.
|
// pruneBuffer prunes the buffer during key generation according to RFC 8032.
|
||||||
// https://tools.ietf.org/html/rfc8032#page-13
|
// https://tools.ietf.org/html/rfc8032#page-13
|
||||||
func pruneBuffer(buf *[32]byte) *[32]byte {
|
func pruneBuffer(buf *[32]byte) *[32]byte {
|
||||||
buf[0] = buf[0] & 0xF8
|
buf[0] &= 0xF8
|
||||||
buf[31] = buf[31] & 0x7F
|
buf[31] &= 0x7F
|
||||||
buf[31] = buf[31] | 0x40
|
buf[31] |= 0x40
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +211,7 @@ func (sComp *SignatureComp) Scan(src interface{}) error {
|
|||||||
if len(srcB) != 64 {
|
if len(srcB) != 64 {
|
||||||
return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
|
return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
|
||||||
}
|
}
|
||||||
copy(sComp[:], srcB[:])
|
copy(sComp[:], srcB)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +230,7 @@ func (s *Signature) Scan(src interface{}) error {
|
|||||||
return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
|
return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
|
||||||
}
|
}
|
||||||
buf := [64]byte{}
|
buf := [64]byte{}
|
||||||
copy(buf[:], srcB[:])
|
copy(buf[:], srcB)
|
||||||
_, err := s.Decompress(buf)
|
_, err := s.Decompress(buf)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
// the original blake from the SHA3 competition and not the new blake2 version.
|
// the original blake from the SHA3 competition and not the new blake2 version.
|
||||||
func Blake512(m []byte) []byte {
|
func Blake512(m []byte) []byte {
|
||||||
h := blake512.New()
|
h := blake512.New()
|
||||||
_, err := h.Write(m[:])
|
_, err := h.Write(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,19 @@
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const qString = "21888242871839275222246405745257275088548364400416034343698204186575808495617"
|
||||||
|
|
||||||
// Q is the order of the integer field (Zq) that fits inside the SNARK.
|
// Q is the order of the integer field (Zq) that fits inside the SNARK.
|
||||||
var Q *big.Int
|
var Q, _ = new(big.Int).SetString(qString, 10)
|
||||||
|
|
||||||
// Zero is 0.
|
// Zero is 0.
|
||||||
var Zero *big.Int
|
var Zero = big.NewInt(0)
|
||||||
|
|
||||||
// One is 1.
|
// One is 1.
|
||||||
var One *big.Int
|
var One = big.NewInt(1)
|
||||||
|
|
||||||
// MinusOne is -1.
|
// MinusOne is -1.
|
||||||
var MinusOne *big.Int
|
var MinusOne = big.NewInt(-1)
|
||||||
|
|
||||||
func init() {
|
|
||||||
Zero = big.NewInt(0)
|
|
||||||
One = big.NewInt(1)
|
|
||||||
MinusOne = big.NewInt(-1)
|
|
||||||
|
|
||||||
qString := "21888242871839275222246405745257275088548364400416034343698204186575808495617"
|
|
||||||
var ok bool
|
|
||||||
Q, ok = new(big.Int).SetString(qString, 10) //nolint:gomnd
|
|
||||||
if !ok {
|
|
||||||
panic(fmt.Sprintf("Bad base 10 string %s", qString))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
19
go.mod
19
go.mod
@@ -1,14 +1,17 @@
|
|||||||
module github.com/iden3/go-iden3-crypto
|
module github.com/iden3/go-iden3-crypto
|
||||||
|
|
||||||
go 1.16
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dchest/blake512 v1.0.0
|
github.com/dchest/blake512 v1.0.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/leanovate/gopter v0.2.9
|
||||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
github.com/stretchr/testify v1.8.2
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
golang.org/x/crypto v0.7.0
|
||||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
golang.org/x/sys v0.6.0
|
||||||
github.com/leanovate/gopter v0.2.9 // indirect
|
)
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
30
go.sum
30
go.sum
@@ -1,5 +1,6 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dchest/blake512 v1.0.0 h1:oDFEQFIqFSeuA34xLtXZ/rWxCXdSjirjzPhey5EUvmA=
|
github.com/dchest/blake512 v1.0.0 h1:oDFEQFIqFSeuA34xLtXZ/rWxCXdSjirjzPhey5EUvmA=
|
||||||
github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI=
|
github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI=
|
||||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||||
@@ -7,21 +8,18 @@ github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ package poseidon
|
|||||||
import "github.com/iden3/go-iden3-crypto/ffg"
|
import "github.com/iden3/go-iden3-crypto/ffg"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NROUNDSF = 8 //nolint:golint
|
// NROUNDSF const from original paper
|
||||||
NROUNDSP = 22 //nolint:golint
|
NROUNDSF = 8
|
||||||
CAPLEN = 4 //nolint:golint
|
// NROUNDSP const from original paper
|
||||||
mLen = 12
|
NROUNDSP = 22
|
||||||
|
// CAPLEN const
|
||||||
|
CAPLEN = 4
|
||||||
|
// mLen const
|
||||||
|
mLen = 12
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ func zero() *ffg.Element {
|
|||||||
return ffg.NewElement()
|
return ffg.NewElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var big7 = big.NewInt(7)
|
||||||
|
|
||||||
// exp7 performs x^7 mod p
|
// exp7 performs x^7 mod p
|
||||||
func exp7(a *ffg.Element) {
|
func exp7(a *ffg.Element) {
|
||||||
a.Exp(*a, big.NewInt(7)) //nolint:gomnd
|
a.Exp(*a, big7)
|
||||||
}
|
}
|
||||||
|
|
||||||
// exp7state perform exp7 for whole state
|
// exp7state perform exp7 for whole state
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package poseidon
|
package poseidon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -99,32 +97,11 @@ func TestPoseidonHashCompare(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPoseidonHash12Inputs(b *testing.B) {
|
|
||||||
bigArray12 := []*big.Int{
|
|
||||||
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(10),
|
|
||||||
big.NewInt(11),
|
|
||||||
big.NewInt(12),
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
poseidon.Hash(bigArray12) //nolint:errcheck,gosec
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkNeptuneHash(b *testing.B) {
|
func BenchmarkNeptuneHash(b *testing.B) {
|
||||||
inp := [NROUNDSF]uint64{1, 2, 3, 4, 5, 6, 7, 8}
|
inp := [NROUNDSF]uint64{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
cap := [CAPLEN]uint64{10, 11, 12, 13}
|
_cap := [CAPLEN]uint64{10, 11, 12, 13}
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Hash(inp, cap) //nolint:errcheck,gosec
|
_, _ = Hash(inp, _cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
keccak256/keccac256_test.go
Normal file
21
keccak256/keccac256_test.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package keccak256
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKeccak256(t *testing.T) {
|
||||||
|
const SEED = "mimc"
|
||||||
|
res := Hash([]byte(SEED))
|
||||||
|
assert.Equal(t,
|
||||||
|
"b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e",
|
||||||
|
hex.EncodeToString(res))
|
||||||
|
c := new(big.Int).SetBytes(Hash([]byte(SEED)))
|
||||||
|
assert.Equal(t,
|
||||||
|
"82724731331859054037315113496710413141112897654334566532528783843265082629790",
|
||||||
|
c.String())
|
||||||
|
}
|
||||||
@@ -23,22 +23,22 @@ type constantsData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateConstantsData() constantsData {
|
func generateConstantsData() constantsData {
|
||||||
var constants constantsData
|
var consts constantsData
|
||||||
|
|
||||||
constants.seedHash = new(big.Int).SetBytes(keccak256.Hash([]byte(SEED)))
|
consts.seedHash = new(big.Int).SetBytes(keccak256.Hash([]byte(SEED)))
|
||||||
c := new(big.Int).SetBytes(keccak256.Hash([]byte(SEED + "_iv")))
|
c := new(big.Int).SetBytes(keccak256.Hash([]byte(SEED + "_iv")))
|
||||||
constants.iv = new(big.Int).Mod(c, _constants.Q)
|
consts.iv = new(big.Int).Mod(c, _constants.Q)
|
||||||
|
|
||||||
constants.nRounds = 91
|
consts.nRounds = 91
|
||||||
cts := getConstants(SEED, constants.nRounds)
|
cts := getConstants(SEED, consts.nRounds)
|
||||||
constants.cts = cts
|
consts.cts = cts
|
||||||
return constants
|
return consts
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConstants(seed string, nRounds int) []*ff.Element {
|
func getConstants(seed string, nRounds int) []*ff.Element {
|
||||||
cts := make([]*ff.Element, nRounds)
|
cts := make([]*ff.Element, nRounds)
|
||||||
cts[0] = ff.NewElement()
|
cts[0] = ff.NewElement()
|
||||||
c := new(big.Int).SetBytes(keccak256.Hash([]byte(SEED)))
|
c := new(big.Int).SetBytes(keccak256.Hash([]byte(seed)))
|
||||||
for i := 1; i < nRounds; i++ {
|
for i := 1; i < nRounds; i++ {
|
||||||
c = new(big.Int).SetBytes(keccak256.Hash(c.Bytes()))
|
c = new(big.Int).SetBytes(keccak256.Hash(c.Bytes()))
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,9 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/iden3/go-iden3-crypto/keccak256"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestKeccak256(t *testing.T) {
|
|
||||||
res := keccak256.Hash([]byte(SEED))
|
|
||||||
assert.Equal(t,
|
|
||||||
"b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e",
|
|
||||||
hex.EncodeToString(res))
|
|
||||||
c := new(big.Int).SetBytes(keccak256.Hash([]byte(SEED)))
|
|
||||||
assert.Equal(t,
|
|
||||||
"82724731331859054037315113496710413141112897654334566532528783843265082629790",
|
|
||||||
c.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMIMC7Generic(t *testing.T) {
|
func TestMIMC7Generic(t *testing.T) {
|
||||||
b1 := big.NewInt(int64(1))
|
b1 := big.NewInt(int64(1))
|
||||||
b2 := big.NewInt(int64(2))
|
b2 := big.NewInt(int64(2))
|
||||||
@@ -36,7 +24,7 @@ func TestMIMC7Generic(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
"6464402164086696096195815557694604139393321133243036833927490113253119343397",
|
"6464402164086696096195815557694604139393321133243036833927490113253119343397",
|
||||||
(*big.Int)(hg).String())
|
hg.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMIMC7(t *testing.T) {
|
func TestMIMC7(t *testing.T) {
|
||||||
@@ -51,7 +39,7 @@ func TestMIMC7(t *testing.T) {
|
|||||||
h1, err := Hash(bigArray1, nil)
|
h1, err := Hash(bigArray1, nil)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
// same hash value than the iden3js and circomlib tests:
|
// same hash value than the iden3js and circomlib tests:
|
||||||
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h1).Bytes()),
|
assert.Equal(t, "0x"+hex.EncodeToString(h1.Bytes()),
|
||||||
"0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd")
|
"0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd")
|
||||||
|
|
||||||
// h2a, hash of 2 elements
|
// h2a, hash of 2 elements
|
||||||
@@ -60,7 +48,7 @@ func TestMIMC7(t *testing.T) {
|
|||||||
h2a, err := Hash(bigArray2a, nil)
|
h2a, err := Hash(bigArray2a, nil)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
// same hash value than the iden3js and circomlib tests:
|
// same hash value than the iden3js and circomlib tests:
|
||||||
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h2a).Bytes()),
|
assert.Equal(t, "0x"+hex.EncodeToString(h2a.Bytes()),
|
||||||
"0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70")
|
"0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70")
|
||||||
|
|
||||||
// h2b, hash of 2 elements
|
// h2b, hash of 2 elements
|
||||||
@@ -68,13 +56,13 @@ func TestMIMC7(t *testing.T) {
|
|||||||
|
|
||||||
mh2b := MIMC7Hash(b12, b45)
|
mh2b := MIMC7Hash(b12, b45)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(mh2b).Bytes()),
|
assert.Equal(t, "0x"+hex.EncodeToString(mh2b.Bytes()),
|
||||||
"0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4")
|
"0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4")
|
||||||
|
|
||||||
h2b, err := Hash(bigArray2b, nil)
|
h2b, err := Hash(bigArray2b, nil)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
// same hash value than the iden3js and circomlib tests:
|
// same hash value than the iden3js and circomlib tests:
|
||||||
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h2b).Bytes()),
|
assert.Equal(t, "0x"+hex.EncodeToString(h2b.Bytes()),
|
||||||
"0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879")
|
"0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879")
|
||||||
|
|
||||||
// h4, hash of 4 elements
|
// h4, hash of 4 elements
|
||||||
@@ -83,7 +71,7 @@ func TestMIMC7(t *testing.T) {
|
|||||||
h4, err := Hash(bigArray4, nil)
|
h4, err := Hash(bigArray4, nil)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
// same hash value than the iden3js and circomlib tests:
|
// same hash value than the iden3js and circomlib tests:
|
||||||
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h4).Bytes()),
|
assert.Equal(t, "0x"+hex.EncodeToString(h4.Bytes()),
|
||||||
"0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb")
|
"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.") //nolint:lll
|
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.") //nolint:lll
|
||||||
@@ -101,6 +89,6 @@ func BenchmarkMIMC7(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, nil) //nolint:errcheck,gosec
|
_, _ = Hash(bigArray4, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:lll
|
//nolint:lll,dupl // long lines, duplicated parts
|
||||||
var cs = constantsStr{
|
var cs = constantsStr{
|
||||||
C: [][]string{{
|
C: [][]string{{
|
||||||
"9c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7",
|
"9c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7",
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ import (
|
|||||||
"github.com/iden3/go-iden3-crypto/utils"
|
"github.com/iden3/go-iden3-crypto/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const NROUNDSF = 8 //nolint:golint
|
// NROUNDSF constant from Poseidon paper
|
||||||
|
const NROUNDSF = 8
|
||||||
|
|
||||||
var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68} //nolint:golint
|
// NROUNDSP constant from Poseidon paper
|
||||||
|
var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68}
|
||||||
|
|
||||||
const spongeChunkSize = 31
|
const spongeChunkSize = 31
|
||||||
const spongeInputs = 16
|
const spongeInputs = 16
|
||||||
@@ -20,10 +22,12 @@ func zero() *ff.Element {
|
|||||||
return ff.NewElement()
|
return ff.NewElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var big5 = big.NewInt(5)
|
||||||
|
|
||||||
// exp5 performs x^5 mod p
|
// exp5 performs x^5 mod p
|
||||||
// https://eprint.iacr.org/2019/458.pdf page 8
|
// https://eprint.iacr.org/2019/458.pdf page 8
|
||||||
func exp5(a *ff.Element) {
|
func exp5(a *ff.Element) {
|
||||||
a.Exp(*a, big.NewInt(5)) //nolint:gomnd
|
a.Exp(*a, big5)
|
||||||
}
|
}
|
||||||
|
|
||||||
// exp5state perform exp5 for whole state
|
// exp5state perform exp5 for whole state
|
||||||
@@ -34,7 +38,7 @@ func exp5state(state []*ff.Element) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ark computes Add-Round Key, from the paper https://eprint.iacr.org/2019/458.pdf
|
// 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) {
|
func ark(state, c []*ff.Element, it int) {
|
||||||
for i := 0; i < len(state); i++ {
|
for i := 0; i < len(state); i++ {
|
||||||
state[i].Add(state[i], c[it+i])
|
state[i].Add(state[i], c[it+i])
|
||||||
}
|
}
|
||||||
@@ -61,12 +65,12 @@ func mix(state []*ff.Element, t int, m [][]*ff.Element) []*ff.Element {
|
|||||||
func Hash(inpBI []*big.Int) (*big.Int, error) {
|
func Hash(inpBI []*big.Int) (*big.Int, error) {
|
||||||
t := len(inpBI) + 1
|
t := len(inpBI) + 1
|
||||||
if len(inpBI) == 0 || len(inpBI) > len(NROUNDSP) {
|
if len(inpBI) == 0 || len(inpBI) > len(NROUNDSP) {
|
||||||
return nil, fmt.Errorf("invalid inputs length %d, max %d", len(inpBI), len(NROUNDSP)) //nolint:gomnd,lll
|
return nil, fmt.Errorf("invalid inputs length %d, max %d", len(inpBI), len(NROUNDSP))
|
||||||
}
|
}
|
||||||
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")
|
||||||
}
|
}
|
||||||
inp := utils.BigIntArrayToElementArray(inpBI[:])
|
inp := utils.BigIntArrayToElementArray(inpBI)
|
||||||
|
|
||||||
nRoundsF := NROUNDSF
|
nRoundsF := NROUNDSF
|
||||||
nRoundsP := NROUNDSP[t-2]
|
nRoundsP := NROUNDSP[t-2]
|
||||||
@@ -77,7 +81,7 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
|
|||||||
|
|
||||||
state := make([]*ff.Element, t)
|
state := make([]*ff.Element, t)
|
||||||
state[0] = zero()
|
state[0] = zero()
|
||||||
copy(state[1:], inp[:])
|
copy(state[1:], inp)
|
||||||
|
|
||||||
ark(state, C, 0)
|
ark(state, C, 0)
|
||||||
|
|
||||||
@@ -90,11 +94,12 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
|
|||||||
ark(state, C, (nRoundsF/2)*t)
|
ark(state, C, (nRoundsF/2)*t)
|
||||||
state = mix(state, t, P)
|
state = mix(state, t, P)
|
||||||
|
|
||||||
|
mul := zero()
|
||||||
for i := 0; i < nRoundsP; i++ {
|
for i := 0; i < nRoundsP; i++ {
|
||||||
exp5(state[0])
|
exp5(state[0])
|
||||||
state[0].Add(state[0], C[(nRoundsF/2+1)*t+i])
|
state[0].Add(state[0], C[(nRoundsF/2+1)*t+i])
|
||||||
|
|
||||||
mul := zero()
|
mul.SetZero()
|
||||||
newState0 := zero()
|
newState0 := zero()
|
||||||
for j := 0; j < len(state); j++ {
|
for j := 0; j < len(state); j++ {
|
||||||
mul.Mul(S[(t*2-1)*i+j], state[j])
|
mul.Mul(S[(t*2-1)*i+j], state[j])
|
||||||
@@ -102,7 +107,7 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k := 1; k < t; k++ {
|
for k := 1; k < t; k++ {
|
||||||
mul = zero()
|
mul.SetZero()
|
||||||
state[k] = state[k].Add(state[k], mul.Mul(state[0], S[(t*2-1)*i+t+k-1]))
|
state[k] = state[k].Add(state[k], mul.Mul(state[0], S[(t*2-1)*i+t+k-1]))
|
||||||
}
|
}
|
||||||
state[0] = newState0
|
state[0] = newState0
|
||||||
@@ -124,9 +129,18 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
|
|||||||
|
|
||||||
// HashBytes returns a sponge hash of a msg byte slice split into blocks of 31 bytes
|
// HashBytes returns a sponge hash of a msg byte slice split into blocks of 31 bytes
|
||||||
func HashBytes(msg []byte) (*big.Int, error) {
|
func HashBytes(msg []byte) (*big.Int, error) {
|
||||||
|
return HashBytesX(msg, spongeInputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HashBytesX returns a sponge hash of a msg byte slice split into blocks of 31 bytes
|
||||||
|
func HashBytesX(msg []byte, frameSize int) (*big.Int, error) {
|
||||||
|
if frameSize < 2 || frameSize > 16 {
|
||||||
|
return nil, errors.New("incorrect frame size")
|
||||||
|
}
|
||||||
|
|
||||||
// not used inputs default to zero
|
// not used inputs default to zero
|
||||||
inputs := make([]*big.Int, spongeInputs)
|
inputs := make([]*big.Int, frameSize)
|
||||||
for j := 0; j < spongeInputs; j++ {
|
for j := 0; j < frameSize; j++ {
|
||||||
inputs[j] = new(big.Int)
|
inputs[j] = new(big.Int)
|
||||||
}
|
}
|
||||||
dirty := false
|
dirty := false
|
||||||
@@ -137,15 +151,15 @@ func HashBytes(msg []byte) (*big.Int, error) {
|
|||||||
for i := 0; i < len(msg)/spongeChunkSize; i++ {
|
for i := 0; i < len(msg)/spongeChunkSize; i++ {
|
||||||
dirty = true
|
dirty = true
|
||||||
inputs[k].SetBytes(msg[spongeChunkSize*i : spongeChunkSize*(i+1)])
|
inputs[k].SetBytes(msg[spongeChunkSize*i : spongeChunkSize*(i+1)])
|
||||||
if k == spongeInputs-1 {
|
if k == frameSize-1 {
|
||||||
hash, err = Hash(inputs)
|
hash, err = Hash(inputs)
|
||||||
dirty = false
|
dirty = false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
inputs = make([]*big.Int, spongeInputs)
|
inputs = make([]*big.Int, frameSize)
|
||||||
inputs[0] = hash
|
inputs[0] = hash
|
||||||
for j := 1; j < spongeInputs; j++ {
|
for j := 1; j < frameSize; j++ {
|
||||||
inputs[j] = new(big.Int)
|
inputs[j] = new(big.Int)
|
||||||
}
|
}
|
||||||
k = 1
|
k = 1
|
||||||
@@ -174,3 +188,55 @@ func HashBytes(msg []byte) (*big.Int, error) {
|
|||||||
|
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SpongeHash returns a sponge hash of inputs (using Poseidon with frame size of 16 inputs)
|
||||||
|
func SpongeHash(inputs []*big.Int) (*big.Int, error) {
|
||||||
|
return SpongeHashX(inputs, spongeInputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpongeHashX returns a sponge hash of inputs using Poseidon with configurable frame size
|
||||||
|
func SpongeHashX(inputs []*big.Int, frameSize int) (*big.Int, error) {
|
||||||
|
if frameSize < 2 || frameSize > 16 {
|
||||||
|
return nil, errors.New("incorrect frame size")
|
||||||
|
}
|
||||||
|
|
||||||
|
// not used frame default to zero
|
||||||
|
frame := make([]*big.Int, frameSize)
|
||||||
|
for j := 0; j < frameSize; j++ {
|
||||||
|
frame[j] = new(big.Int)
|
||||||
|
}
|
||||||
|
dirty := false
|
||||||
|
var hash *big.Int
|
||||||
|
var err error
|
||||||
|
|
||||||
|
k := 0
|
||||||
|
for i := 0; i < len(inputs); i++ {
|
||||||
|
dirty = true
|
||||||
|
frame[k] = inputs[i]
|
||||||
|
if k == frameSize-1 {
|
||||||
|
hash, err = Hash(frame)
|
||||||
|
dirty = false
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
frame = make([]*big.Int, frameSize)
|
||||||
|
frame[0] = hash
|
||||||
|
for j := 1; j < frameSize; j++ {
|
||||||
|
frame[j] = new(big.Int)
|
||||||
|
}
|
||||||
|
k = 1
|
||||||
|
} else {
|
||||||
|
k++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dirty {
|
||||||
|
// we haven't hashed something in the main sponge loop and need to do hash here
|
||||||
|
hash, err = Hash(frame)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash, nil
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -46,7 +46,7 @@ func SetBigIntFromLEBytes(v *big.Int, leBuf []byte) *big.Int {
|
|||||||
return v.SetBytes(beBuf)
|
return v.SetBytes(beBuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hex is a byte slice type that can be marshalled and unmarshaled in hex
|
// Hex is a byte slice type that can be marshaled and unmarshaled in hex
|
||||||
type Hex []byte
|
type Hex []byte
|
||||||
|
|
||||||
// MarshalText encodes buf as hex
|
// MarshalText encodes buf as hex
|
||||||
@@ -72,7 +72,7 @@ func HexDecode(h string) ([]byte, error) {
|
|||||||
|
|
||||||
// HexDecodeInto decodes a hex string into an array of bytes (dst), verifying
|
// HexDecodeInto decodes a hex string into an array of bytes (dst), verifying
|
||||||
// that the decoded array has the same length as dst.
|
// that the decoded array has the same length as dst.
|
||||||
func HexDecodeInto(dst []byte, h []byte) error {
|
func HexDecodeInto(dst, h []byte) error {
|
||||||
if bytes.HasPrefix(h, []byte("0x")) {
|
if bytes.HasPrefix(h, []byte("0x")) {
|
||||||
h = h[2:]
|
h = h[2:]
|
||||||
}
|
}
|
||||||
@@ -105,21 +105,21 @@ func CheckBigIntArrayInField(arr []*big.Int) bool {
|
|||||||
|
|
||||||
// BigIntArrayToElementArray converts an array of *big.Int into an array of *ff.Element
|
// BigIntArrayToElementArray converts an array of *big.Int into an array of *ff.Element
|
||||||
func BigIntArrayToElementArray(bi []*big.Int) []*ff.Element {
|
func BigIntArrayToElementArray(bi []*big.Int) []*ff.Element {
|
||||||
var o []*ff.Element
|
o := make([]*ff.Element, len(bi))
|
||||||
for i := range bi {
|
for i := range bi {
|
||||||
o = append(o, ff.NewElement().SetBigInt(bi[i]))
|
o[i] = ff.NewElement().SetBigInt(bi[i])
|
||||||
}
|
}
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
// ElementArrayToBigIntArray converts an array of *ff.Element into an array of *big.Int
|
// ElementArrayToBigIntArray converts an array of *ff.Element into an array of *big.Int
|
||||||
func ElementArrayToBigIntArray(e []*ff.Element) []*big.Int {
|
func ElementArrayToBigIntArray(e []*ff.Element) []*big.Int {
|
||||||
var o []*big.Int
|
o := make([]*big.Int, len(e))
|
||||||
for i := range e {
|
for i := range e {
|
||||||
ei := e[i]
|
ei := e[i]
|
||||||
bi := big.NewInt(0)
|
bi := big.NewInt(0)
|
||||||
ei.ToBigIntRegular(bi)
|
ei.ToBigIntRegular(bi)
|
||||||
o = append(o, bi)
|
o[i] = bi
|
||||||
}
|
}
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user