Add sponge-merkle digest

This commit is contained in:
Mark Spanbroek 2023-11-22 11:24:53 +01:00 committed by markspanbroek
parent cfb4f97023
commit c4569bcba0
4 changed files with 64 additions and 0 deletions

View File

@ -3,10 +3,12 @@ import poseidon2/io
import poseidon2/sponge
import poseidon2/compress
import poseidon2/merkle
import poseidon2/spongemerkle
export sponge
export compress
export merkle
export spongemerkle
export toBytes
export toF
export elements

View File

@ -0,0 +1,28 @@
import ./types
import ./merkle
import ./sponge
type SpongeMerkle* = object
merkle: Merkle
func init*(_: type SpongeMerkle): SpongeMerkle =
SpongeMerkle(merkle: Merkle.init())
func update*(spongemerkle: var SpongeMerkle, chunk: openArray[byte]) =
let digest = Sponge.digest(chunk, rate = 2)
spongemerkle.merkle.update(digest)
func finish*(spongemerkle: var SpongeMerkle): F =
return spongemerkle.merkle.finish()
func digest*(_: type SpongeMerkle, bytes: openArray[byte], chunkSize: int): F =
## Hashes chunks of data with a sponge of rate 2, and combines the
## resulting chunk hashes in a merkle root.
var spongemerkle = SpongeMerkle.init()
var index = 0
while index < bytes.len:
let start = index
let finish = min(index + chunkSize, bytes.len)
spongemerkle.update(bytes.toOpenArray(start, finish - 1))
index += chunkSize
return spongemerkle.finish()

View File

@ -0,0 +1,33 @@
import std/unittest
import std/sequtils
import std/random
import constantine/math/arithmetic
import poseidon2/sponge
import poseidon2/merkle
import poseidon2/spongemerkle
suite "sponge - merkle root":
const KB = 1024
test "hashes chunks of data with sponge, and combines them in merkle root":
let bytes = newSeqWith(64*KB, rand(byte))
var merkle = Merkle.init()
for i in 0..<32:
let chunk = bytes[(i*2*KB)..<((i+1)*2*KB)]
let digest = Sponge.digest(chunk, rate = 2)
merkle.update(digest)
let expected = merkle.finish()
check bool(SpongeMerkle.digest(bytes, chunkSize = 2*KB) == expected)
test "handles partial chunk at the end":
let bytes = newSeqWith(63*KB, rand(byte))
var merkle = Merkle.init()
for i in 0..<31:
let chunk = bytes[(i*2*KB)..<((i+1)*2*KB)]
let digest = Sponge.digest(chunk, rate = 2)
merkle.update(digest)
let partialChunk = bytes[(62*KB)..<(63*KB)]
merkle.update(Sponge.digest(partialChunk, rate = 2))
let expected = merkle.finish()
check bool(SpongeMerkle.digest(bytes, chunkSize = 2*KB) == expected)

View File

@ -2,6 +2,7 @@ import ./poseidon2/testPermutation
import ./poseidon2/testSponge
import ./poseidon2/testCompress
import ./poseidon2/testMerkle
import ./poseidon2/testSpongeMerkle
import ./poseidon2/testIo
import ./poseidon2/testReadme