Browse Source

Poseidon Sponge Hash implemented (#45)

* Poseidon Sponge Hash implemented
* Linter fixes and GHA go versions updated
fix/bbjj-err
Oleksandr Brezhniev 2 years ago
committed by GitHub
parent
commit
f4972de131
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 2 deletions
  1. +1
    -1
      .github/workflows/lint.yml
  2. +1
    -1
      .github/workflows/test.yml
  3. +56
    -0
      poseidon/poseidon.go
  4. +58
    -0
      poseidon/poseidon_test.go

+ 1
- 1
.github/workflows/lint.yml

@ -7,7 +7,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v1 uses: actions/setup-go@v1
with: with:
go-version: 1.14.x
go-version: 1.16.x
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Lint - name: Lint

+ 1
- 1
.github/workflows/test.yml

@ -4,7 +4,7 @@ jobs:
test: test:
strategy: strategy:
matrix: matrix:
go-version: [ 1.13.x, 1.14.x ]
go-version: [ 1.16.x, 1.17.x ]
goarch: [ "amd64", "386" ] goarch: [ "amd64", "386" ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

+ 56
- 0
poseidon/poseidon.go

@ -13,6 +13,9 @@ const NROUNDSF = 8 //nolint:golint
var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68} //nolint:golint var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68} //nolint:golint
const spongeChunkSize = 31
const spongeInputs = 16
func zero() *ff.Element { func zero() *ff.Element {
return ff.NewElement() return ff.NewElement()
} }
@ -118,3 +121,56 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
rE.ToBigIntRegular(r) rE.ToBigIntRegular(r)
return r, nil return r, nil
} }
// HashBytes returns a sponge hash of a msg byte slice split into blocks of 31 bytes
func HashBytes(msg []byte) (*big.Int, error) {
// not used inputs default to zero
inputs := make([]*big.Int, spongeInputs)
for j := 0; j < spongeInputs; j++ {
inputs[j] = new(big.Int)
}
dirty := false
var hash *big.Int
var err error
k := 0
for i := 0; i < len(msg)/spongeChunkSize; i++ {
dirty = true
inputs[k].SetBytes(msg[spongeChunkSize*i : spongeChunkSize*(i+1)])
if k == spongeInputs-1 {
hash, err = Hash(inputs)
dirty = false
if err != nil {
return nil, err
}
inputs = make([]*big.Int, spongeInputs)
inputs[0] = hash
for j := 1; j < spongeInputs; j++ {
inputs[j] = new(big.Int)
}
k = 1
} else {
k++
}
}
if len(msg)%spongeChunkSize != 0 {
// the last chunk of the message is less than 31 bytes
// zero padding it, so that 0xdeadbeaf becomes
// 0xdeadbeaf000000000000000000000000000000000000000000000000000000
var buf [spongeChunkSize]byte
copy(buf[:], msg[(len(msg)/spongeChunkSize)*spongeChunkSize:])
inputs[k] = new(big.Int).SetBytes(buf[:])
dirty = true
}
if dirty {
// we haven't hashed something in the main sponge loop and need to do hash here
hash, err = Hash(inputs)
if err != nil {
return nil, err
}
}
return hash, nil
}

+ 58
- 0
poseidon/poseidon_test.go
File diff suppressed because it is too large
View File


Loading…
Cancel
Save