From c4b4936e26b0867ce134890e3ddb0bb1073cce36 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 20 Nov 2023 11:16:25 +0100 Subject: [PATCH] Handle merkleRoot of empty sequence Co-Authored-By: Balazs Komuves --- poseidon2/merkle.nim | 3 +++ tests/poseidon2/testIo.nim | 8 ++++++++ tests/poseidon2/testMerkle.nim | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/poseidon2/merkle.nim b/poseidon2/merkle.nim index b24c83f..f8b98f4 100644 --- a/poseidon2/merkle.nim +++ b/poseidon2/merkle.nim @@ -15,6 +15,9 @@ func merkleRoot(xs: openArray[F], isBottomLayer: static bool) : F = let b = high(xs) let m = b-a+1 + when isBottomLayer: + assert m > 0, "merkle root of empty sequence is not defined" + when not isBottomLayer: if m==1: return xs[a] diff --git a/tests/poseidon2/testIo.nim b/tests/poseidon2/testIo.nim index cbcc605..97be438 100644 --- a/tests/poseidon2/testIo.nim +++ b/tests/poseidon2/testIo.nim @@ -32,6 +32,14 @@ suite "conversion to/from bytes": let elements = toSeq bytes.elements(F) check bool(elements[^1] == expected) + test "converts empty sequence of bytes to single field element": + let bytes = seq[byte].default + let marker = @[1'u8] + let expected = F.fromBytes(marker.toArray) + let elements = toSeq bytes.elements(F) + check elements.len == 1 + check bool(elements[0] == expected) + test "conversion from bytes pads the last chunk when it's less than 31 bytes": let bytes = toSeq 1'u8..80'u8 let marker = @[1'u8] diff --git a/tests/poseidon2/testMerkle.nim b/tests/poseidon2/testMerkle.nim index 203ae2c..349c830 100644 --- a/tests/poseidon2/testMerkle.nim +++ b/tests/poseidon2/testMerkle.nim @@ -65,3 +65,13 @@ suite "merkle root": let bytes = toSeq 1'u8..80'u8 let rootAsBytes = merkleRoot(bytes).toBytes() check rootAsBytes.toHex == "0x40989b63104f39e3331767883381085bcfc46e2202679123371f1ffe53521b16" + + test "merkle root of empty sequence of elements": + let empty = seq[F].default + expect Exception: + discard merkleRoot(empty) + + test "merkle root of empty sequency of bytes": + # merkle root of empty sequence of bytes is uniquely defined through padding + let empty = seq[byte].default + check merkleRoot(empty).toBytes.toHex == "0xcc8da1d157900e611b89e258d95450e707f4f9eec169422d7c26aba54f803c08"