Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 19 additions & 25 deletions draft-davidben-tls-merkle-tree-certs.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,32 +516,26 @@ The following procedure can be used to verify a subtree consistency proof.

Given a Merkle Tree over `n` elements, a subtree defined by `[start, end)`, a consistency proof `proof`, a subtree hash `node_hash`, and a root hash `root_hash`:

1. If `end` is `n`, run the following:
1. Set `fn` to `start` and `sn` to `end - 1`.
2. Set `r` to `node_hash`.
3. Until `LSB(fn)` is set or `sn` is `0`, right-shift `fn` and `sn` equally.
4. For each value `p` in the `proof` array:
1. If `sn` is `0`, then stop iteration and fail the proof verification.
2. Set `r` to `HASH(0x01 || p || r)`.
3. Until `LSB(sn)` is set, right-shift `sn`.
4. Right-shift `sn` once more.
5. Compare `sn` to `0` and `r` to `root_hash`. If either is not equal, fail the proof verification. If all are equal, accept the proof.
2. Otherwise, run the following:
1. Check that `[start, end)` is a valid subtree ({{definition-of-a-subtree}}), and that `end <= n`. If either do not hold, fail proof verification. These checks imply `0 <= start < end <= end`.
1. Set `fn` to `start`, `sn` to `end - 1`, and `tn` to `n - 1`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

As I'm re-implementing this logic, I found a panic in the original version of my code when n = 0 due to an underflow. The fact that [start, end) is a subtree of the tree of size n implies that 0 <= start < end <= n so it must be the case that end > 0 and n > 0, but maybe we should add an explicit note about that?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hmm... how about we just make the function check the preconditions? It's fallible anyway, and makes it consistent with the inclusion proof version. Arguably it's redundant with the "type signature" but people will be sloppy.

1. If `sn` is `tn`, then:
Comment thread
lukevalenta marked this conversation as resolved.
1. Until `fn` is `sn`, right-shift `fn`, `sn`, and `tn` equally.
1. Otherwise:
1. Until `LSB(sn)` is not set or `fn` is `sn`, right-shift `fn`, `sn`, and `tn` equally.
1. If `fn` is `sn`, set `fr` and `sr` to `node_hash`.
1. Otherwise:
1. If `proof` is an empty array, stop and fail verification.
2. If `end - start` is an exact power of two, prepend `node_hash` to the `proof` array.
3. Set `fn` to `start`, `sn` to `end - 1`, and `tn` to `n - 1`.
4. Until `LSB(sn)` is not set or `fn` is equal to `sn`, right-shift `fn`, `sn`, and `tn` equally.
5. Set both `fr` and `sr` to the first value in the `proof` array.
6. For each subsequent value `c` in the `proof` array:
1. If `tn` is `0`, then stop the iteration and fail the proof verification.
2. If `LSB(sn)` is set, or if `sn` is equal to `tn`, then:
1. If `fn < sn`, set `fr` to `HASH(0x01 || c || fr)`.
2. Set `sr` to `HASH(0x01 || c || sr)`.
3. Until `LSB(sn)` is set, right-shift `fn`, `sn`, and `tn` equally.
3. Otherwise:
1. Set `sr` to `HASH(0x01 || sr || c)`.
4. Right-shift `fn`, `sn`, and `tn` once more.
7. Compare `tn` to `0`, `fr` to `node_hash`, and `sr` to `root_hash`. If any are not equal, fail the proof verification. If all are equal, accept the proof.
1. Remove the first value of the `proof` array and set `fr` and `sr` to the removed value.
1. For each value `c` in the `proof` array:
1. If `tn` is `0`, then stop the iteration and fail the proof verification.
1. If `LSB(sn)` is set, or if `sn` is equal to `tn`, then:
1. If `fn < sn`, set `fr` to `HASH(0x01 || c || fr)`.
1. Set `sr` to `HASH(0x01 || c || sr)`.
1. Until `LSB(sn)` is set, right-shift `fn`, `sn`, and `tn` equally.
1. Otherwise:
1. Set `sr` to `HASH(0x01 || sr || c)`.
1. Right-shift `fn`, `sn`, and `tn` once more.
1. Compare `tn` to `0`, `fr` to `node_hash`, and `sr` to `root_hash`. If any are not equal, fail the proof verification. If all are equal, accept the proof.

## Arbitrary Intervals

Expand Down