Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merkle tree construction #504

Merged
merged 13 commits into from
Aug 15, 2023
Merged

Merkle tree construction #504

merged 13 commits into from
Aug 15, 2023

Conversation

tbekas
Copy link
Contributor

@tbekas tbekas commented Aug 2, 2023

No description provided.

@tbekas tbekas marked this pull request as ready for review August 4, 2023 14:17
benbierens
benbierens previously approved these changes Aug 7, 2023
Copy link
Contributor

@benbierens benbierens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can rap-battle some more about the 1D array index stuff, if you'd like. (Or we can delay it till we get to serialization where we need to do it anyway.)

codex/merkletree/merkletree.nim Outdated Show resolved Hide resolved
benbierens
benbierens previously approved these changes Aug 8, 2023
codex/merkletree/merkletree.nim Outdated Show resolved Hide resolved
@elcritch
Copy link
Contributor

elcritch commented Aug 8, 2023

We can rap-battle some more about the 1D array index stuff, if you'd like. (Or we can delay it till we get to serialization where we need to do it anyway.)

But @benbierens it's like log n less allocations!! ;) You can tell my embedded background shows -- I'm allergic to allocations.

@benbierens
Copy link
Contributor

Oh yeah, no doubt the 1D thing is much better in this way. It's just, we were just starting and needed a way to think about what we were trying to do. So we started with lots of allocs.

Copy link
Member

@gmega gmega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have what are mostly petty comments. 🙂 Overall it looks good, particularly given that it passes the tests.

codex/merkletree/merkletree.nim Show resolved Hide resolved
codex/merkletree/merkletree.nim Outdated Show resolved Hide resolved
codex/merkletree/merkletree.nim Show resolved Hide resolved
digestSize =? leaves.?[0].?size:
return failure("At least one leaf is required")

if not leaves.allIt(it.mcodec == mcodec):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get why you are doing this, but to me this is a symptom that mcodec should be a property of the tree and not a property of the node. Not sure there's much of a way around it though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, initially I started implementing it this way, but the new code has to be compatible with already existing code and it's just easier to do it this way than converting to/from MultiHash in each public function. For the serialization though we will likely use a tree property instead of a node property.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's relevant to check the type of hash of the leafs, in fact we can just treat them as abstract blobs. We should just have this as a property of the entire tree.

In fact, we have some potential use cases, where the leafs can be pretty much anything, for example KZG commitments...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've address this by hardcoding a hashing algorithm for merkle trees tho SHA-256 in #516

codex/merkletree/merkletree.nim Outdated Show resolved Hide resolved
codex/merkletree/merkletree.nim Show resolved Hide resolved
Copy link
Member

@gmega gmega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!


test "tree with three leaves has expected root":
let
expectedRoot = combine(combine(leaves[0], leaves[1]), combine(leaves[2], leaves[2]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you're duplicating the last element when the tree is odd? It would probably be better to use a specific "null node".

The reason comes from reviewing the Bitcoin merkle trees there were some issues with duplicating issues at the end. With a properly constructed dataset in Bitcoin you could do a denial-of-service. See CVE-2012-2459.

There was a proposal for a better merkle design for Bitcoin at BIP-98. It describes the issue better. I didn't dive much into the proof side of things (maybe it's better).

It may all not apply to us, but I think prudence would say to use the fixes others did in case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmega your question about balanced merkle tree reminded me of this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the #516

proc init*(
T: type MerkleTree,
leaves: seq[MerkleHash]
): ?!MerkleTree =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a short description noting the ordering of the nodes? When this comes up later it's nice to know "leaves start at 0..k, with proofs being k+1..n" or something similar.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. you could also add docs to the module. Just use ## like ## about this module as the comment block type and Nim doc gen will turn it into a module doc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the #516

T: type MerkleProof,
index: int,
path: seq[MerkleHash]
): MerkleProof =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above! Just enough details to what the proof is of.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the #516

@elcritch
Copy link
Contributor

elcritch commented Aug 9, 2023

Ok, created an issue to follow up on the pre-image attack thing to get this unblocked: #511

index: int
path: seq[MerkleHash]

# Tree constructed from leaves H0..H2 is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for documenting this!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Note if you use ## here then it'd show up if we ever run docgen. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #516

Copy link
Contributor

@dryajov dryajov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I think this is looking good for a first pass.

We're missing proof validation (or am I blind?) and and tree validation when constructed with a merkle root. We can cover that in a separate PR tho.

We should also address the security concernes, but I'd leave it for a separate PR as well.

@benbierens benbierens self-requested a review August 10, 2023 06:29
@@ -0,0 +1,189 @@
## Nim-Codex
## Copyright (c) 2022 Status Research & Development GmbH
Copy link
Contributor

@dryajov dryajov Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Copyright (c) 2022 Status Research & Development GmbH
## Copyright (c) 2023 Status Research & Development GmbH

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #516

@tbekas
Copy link
Contributor Author

tbekas commented Aug 15, 2023

I'm going to address all of the comments in the upcoming PR.

@tbekas tbekas merged commit e860127 into master Aug 15, 2023
8 checks passed
@tbekas tbekas deleted the merkle-tree-construction branch August 15, 2023 11:23
@jessiebroke jessiebroke assigned tbekas and jessiebroke and unassigned jessiebroke Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants