Fix merkle root of odd number of elements

This commit is contained in:
Mark Spanbroek 2023-11-09 10:20:10 +01:00 committed by markspanbroek
parent 9c1d18e1a2
commit 3cbd9a3a4c
2 changed files with 20 additions and 11 deletions

View File

@ -92,17 +92,16 @@ func merkleRoot*(xs: openArray[F]) : F =
let n : int = 2*halfn let n : int = 2*halfn
let isOdd : bool = (n != m) let isOdd : bool = (n != m)
var ys : seq[F] = newSeq[F](halfn) var ys : seq[F]
if not isOdd: if not isOdd:
ys = newSeq[F](halfn)
else:
ys = newSeq[F](halfn+1)
for i in 0..<halfn: for i in 0..<halfn:
ys[i] = compress( xs[a+2*i], xs[a+2*i+1] ) ys[i] = compress( xs[a+2*i], xs[a+2*i+1] )
if isOdd:
else: ys[halfn] = compress( xs[n], zero )
for i in 0..<halfn-1:
ys[i] = compress( xs[a+2*i], xs[a+2*i+1] )
# and the last one:
ys[halfn-1] = compress( xs[a+n-2], zero )
return merkleRoot(ys) return merkleRoot(ys)

View File

@ -75,12 +75,22 @@ suite "poseidon2":
let root = merkleRoot(xs) let root = merkleRoot(xs)
check root.toHex(littleEndian) == "0xd1111b3515a663bb48278bfe453fe2508487014a1c6093d3ec5a6db764bbab1e" check root.toHex(littleEndian) == "0xd1111b3515a663bb48278bfe453fe2508487014a1c6093d3ec5a6db764bbab1e"
test "merkle root of even elements":
let elements = toSeq(1..4).mapIt(toF(it))
let expected = compress(compress(1.toF, 2.toF), compress(3.toF, 4.toF))
check bool(merkleRoot(elements) == expected)
test "merkle root of odd elements":
let elements = toSeq(1..3).mapIt(toF(it))
let expected = compress(compress(1.toF, 2.toF), compress(3.toF, 0.toF))
check bool(merkleRoot(elements) == expected)
test "merkle root of bytes": test "merkle root of bytes":
let bytes = toSeq 1'u8..80'u8 let bytes = toSeq 1'u8..80'u8
let root = merkleRoot(bytes) let root = merkleRoot(bytes)
check root.toHex(littleEndian) == "0x00f5c12fabdf0fce1a69b9f0920f60e0c0ea4d8a880ae297559e0ad2276f2d2d" check root.toHex(littleEndian) == "0xa1dffa3f60d166283d60396023d95a1d7996d119e5290fe31131e7c6a7a27817"
test "merkle root of bytes converted to bytes": test "merkle root of bytes converted to bytes":
let bytes = toSeq 1'u8..80'u8 let bytes = toSeq 1'u8..80'u8
let rootAsBytes = merkleRoot(bytes).toBytes() let rootAsBytes = merkleRoot(bytes).toBytes()
check rootAsBytes.toHex == "0x00f5c12fabdf0fce1a69b9f0920f60e0c0ea4d8a880ae297559e0ad2276f2d2d" check rootAsBytes.toHex == "0xa1dffa3f60d166283d60396023d95a1d7996d119e5290fe31131e7c6a7a27817"