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

Verification logic does not ensure lexicographical ordering #87

Closed
liamsi opened this issue Dec 15, 2022 · 3 comments
Closed

Verification logic does not ensure lexicographical ordering #87

liamsi opened this issue Dec 15, 2022 · 3 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@liamsi
Copy link
Member

liamsi commented Dec 15, 2022

The NMT guarantees lexicographical ordering and hence generated proofs follow this ordering as well. The verification logic does not enforce this though currently. This might not be a big deal as verification would fail if ordering is different though it makes it harder to reason about this and it is obviously better to enforce ordering there too.

@musalbas suggested to enforce ordering in the hasher directly. While it might seem better to follow the current pattern and fail much earlier (when adding data to the tree and not only later when hashing/creating the root), having the ordering enforced while hashing is better from a consistency perspective. it would also immediately resolve the ordering guarantee during verification as well.

@liamsi
Copy link
Member Author

liamsi commented Dec 15, 2022

The only downside I can think of, when incorporating the ordering into the hasher, is that it will have to happen on every inner node (instead of currently every leaf only), which will make proving and verification slower (probs negligible but should be confirmed in a benchmark too).

Not really a downside but sth to keep in mind is that the hasher will need to return an error. This might affect other parts of the API as well.

@liamsi liamsi added enhancement New feature or request good first issue Good for newcomers labels Dec 16, 2022
@liamsi
Copy link
Member Author

liamsi commented Dec 16, 2022

Note that the hasher is also exposed directly and indpependently of an NMT here:

nmt/hasher.go

Lines 22 to 54 in 7d31915

// Sha256Namespace8FlaggedLeaf uses sha256 as a base-hasher, 8 bytes
// for the namespace IDs and ignores the maximum possible namespace.
//
// Sha256Namespace8FlaggedLeaf(namespacedData) results in:
// ns(rawData) || ns(rawData) || sha256(LeafPrefix || rawData),
// where rawData is the leaf's data minus the namespace.ID prefix
// (namely namespacedData[NamespaceLen:]).
//
// Note that different from other cryptographic hash functions, this here
// makes assumptions on the input:
// len(namespacedData) >= DefaultNamespaceIDLen has to hold,
// as the first DefaultNamespaceIDLen bytes are interpreted as the namespace ID).
// If the input does not fulfil this, we will panic.
// The output will be of length 2*DefaultNamespaceIDLen+sha256.Size = 48 bytes.
func Sha256Namespace8FlaggedLeaf(namespacedData []byte) []byte {
return defaultHasher.HashLeaf(namespacedData)
}
// Sha256Namespace8FlaggedInner hashes inner nodes to:
// minNID || maxNID || sha256(NodePrefix || leftRight), where leftRight consists of the full
// left and right child node bytes, including their respective min and max namespace IDs.
// Hence, the input has to be of size:
// 48 = 32 + 8 + 8 = sha256.Size + 2*DefaultNamespaceIDLen bytes.
// If the input does not fulfil this, we will panic.
// The output will also be of length 2*DefaultNamespaceIDLen+sha256.Size = 48 bytes.
func Sha256Namespace8FlaggedInner(leftRight []byte) []byte {
const flagLen = DefaultNamespaceIDLen * 2
sha256Len := defaultHasher.Size()
left := leftRight[:flagLen+sha256Len]
right := leftRight[flagLen+sha256Len:]
return defaultHasher.HashNode(left, right)
}

We should remove this code (looks like celestia-node is the only user of it and even that is about to change here . If we keep these functions there we actually must enforce the ordering in the hasher as otherwise this part of the public API can be misused.

@liamsi
Copy link
Member Author

liamsi commented Feb 9, 2023

closing in favour of #95 (more actionable)

@liamsi liamsi closed this as completed Feb 9, 2023
staheri14 added a commit that referenced this issue Feb 17, 2023
…ha256Namespace8FlaggedInner from the hasher (#103)

## Overview
The following two functions `Sha256Namespace8FlaggedLeaf` and
`Sha256Namespace8FlaggedInner` are part of the public APIs, however,
they are no longer needed as mentioned by @liamsi in
#87 (comment). I
also verified it against the main branch and the latest release
(v0.7.0-rc4@8b9937f) of celestia-node codebase and no usage was found.
Likewise, no usage was available in the clestia-core repo.

**Summary of changes:**
- This PR deletes these `Sha256Namespace8FlaggedLeaf` and
`Sha256Namespace8FlaggedInner` functions and the relevant tests.
- After performing this update, it was found that there was no longer
any use case for the `defaultHasher` in the main hasher file, and it is
now only being used in the test file. As a result, it has been moved
accordingly.

## Checklist
- [x] New and updated code has appropriate documentation
- [x] New and updated code has new and/or updated testing
- [x] Required CI checks are passing
- [x] Visual proof for any user facing features like CLI or
documentation updates (based on the responses from code-owners, it is
safe to say there is no mention to these functions in any doc)
- [x] Linked issues closed with keywords

This change is inline with
celestiaorg/celestia-app#1296 and
#95.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant