Skip to content

Vercons easy - #12

Open
phbnf wants to merge 7 commits into
prepareVerfrom
vercons-easy
Open

Vercons easy#12
phbnf wants to merge 7 commits into
prepareVerfrom
vercons-easy

Conversation

@phbnf

@phbnf phbnf commented Jun 22, 2026

Copy link
Copy Markdown
Owner

No description provided.

@phbnf

phbnf commented Jun 22, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces subtree consistency proof verification by adding VerifySubtreeConsistency and RootFromSubtreeConsistencyProof to support arbitrary subtrees [start, end). It also refactors the existing consistency proof verification logic and removes the unused chainInnerRight function. The review feedback suggests using RootFromConsistencyProof in VerifyConsistency to maintain specific error handling and consistency, and removing a redundant isSubtreeValid check in VerifySubtreeConsistency since it is already performed inside RootFromSubtreeConsistencyProof.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread proof/verify.go Outdated
// hashes. Requires 0 < size1 <= size2.
func VerifyConsistency(hasher merkle.LogHasher, size1, size2 uint64, proof [][]byte, root1, root2 []byte) error {
hash2, err := RootFromConsistencyProof(hasher, size1, size2, proof, root1)
hash2, err := RootFromSubtreeConsistencyProof(hasher, 0, size1, size2, proof, root1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Calling RootFromSubtreeConsistencyProof directly here bypasses the dedicated RootFromConsistencyProof function. Using RootFromConsistencyProof instead ensures that standard consistency proof validation benefits from clearer, more specific error messages (such as distinguishing when size1 == 0 or size2 < size1) and keeps the verification path consistent.

Suggested change
hash2, err := RootFromSubtreeConsistencyProof(hasher, 0, size1, size2, proof, root1)
hash2, err := RootFromConsistencyProof(hasher, size1, size2, proof, root1)

Comment thread proof/verify.go Outdated
Comment on lines +114 to +117
if err := isSubtreeValid(start, end); err != nil {
return fmt.Errorf("subtree invalid: %v", err)
}
hash2, err := RootFromSubtreeConsistencyProof(hasher, start, end, size, proof, root1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The call to isSubtreeValid(start, end) is redundant here because RootFromSubtreeConsistencyProof already performs this exact check and returns the identical wrapped error message. Removing this redundant check simplifies the function and avoids duplicate validation.

	hash2, err := RootFromSubtreeConsistencyProof(hasher, start, end, size, proof, root1)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces subtree consistency verification in proof/verify.go by adding VerifySubtreeConsistency and RootFromSubtreeConsistencyProof, along with internal helper functions like chainSubtree to compute subtree roots. It also refactors VerifyConsistency to leverage these new subtree-based implementations. The reviewer suggests simplifying RootFromSubtreeConsistencyProof by removing a redundant check for start == 0 && size == end, as this case is already handled by the underlying rootFromSubtreeConsistencyProof function.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread proof/verify.go Outdated
Comment on lines +158 to +162
case start == 0 && size == end:
if len(proof) > 0 {
return nil, errors.New("start=0 and end=size, but proof is not empty")
}
return root1, nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This special case check for start == 0 && size == end is redundant because the underlying rootFromSubtreeConsistencyProof function already handles the end == size case (which includes start == 0) correctly. Removing this check simplifies the code without changing the behavior.

@phbnf
phbnf force-pushed the prepareVer branch 2 times, most recently from 6c41795 to f78d8cc Compare June 23, 2026 20:04
@phbnf

phbnf commented Jun 23, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces subtree consistency verification by adding the VerifySubtreeConsistency and RootFromSubtreeConsistencyProof functions, and refactoring existing consistency verification to utilize these new subtree-based methods. The review feedback suggests two improvements: first, calling RootFromConsistencyProof instead of RootFromSubtreeConsistencyProof directly inside VerifyConsistency to preserve specific validation checks and error messages; second, removing a redundant isSubtreeValid check in VerifySubtreeConsistency since it is already performed inside RootFromSubtreeConsistencyProof.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread proof/verify.go Outdated
// hashes. Requires 0 < size1 <= size2.
func VerifyConsistency(hasher merkle.LogHasher, size1, size2 uint64, proof [][]byte, root1, root2 []byte) error {
hash2, err := RootFromConsistencyProof(hasher, size1, size2, proof, root1)
hash2, err := RootFromSubtreeConsistencyProof(hasher, 0, size1, size2, proof, root1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Calling RootFromSubtreeConsistencyProof directly here bypasses the specific consistency validation checks and tailored error messages implemented in RootFromConsistencyProof (such as checking if size1 == 0 or size1 == size2). It is better to call RootFromConsistencyProof to ensure consistent and descriptive error messages for consistency verification.

Suggested change
hash2, err := RootFromSubtreeConsistencyProof(hasher, 0, size1, size2, proof, root1)
hash2, err := RootFromConsistencyProof(hasher, size1, size2, proof, root1)

Comment thread proof/verify.go Outdated
Comment on lines +114 to +117
if err := isSubtreeValid(start, end); err != nil {
return fmt.Errorf("subtree invalid: %v", err)
}
hash2, err := RootFromSubtreeConsistencyProof(hasher, start, end, size, proof, root1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The isSubtreeValid(start, end) check is redundant here because RootFromSubtreeConsistencyProof already performs this exact check at its beginning (line 152). Removing this redundant check simplifies the function and avoids duplicate execution.

	hash2, err := RootFromSubtreeConsistencyProof(hasher, start, end, size, proof, root1)

@phbnf

phbnf commented Jun 23, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces subtree consistency verification by adding VerifySubtreeConsistency and RootFromSubtreeConsistencyProof, and refactoring RootFromConsistencyProof to utilize the new subtree logic. Feedback on these changes highlights two potential panic risks: first, the length of root1 should be validated against hasher.Size() to prevent downstream hashing issues, and second, the length of proof must be verified before accessing proof[0] to avoid an out-of-bounds panic.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread proof/verify.go Outdated
Comment on lines +152 to +154
func RootFromSubtreeConsistencyProof(hasher merkle.LogHasher, start, end, size uint64, proof [][]byte, root1 []byte) ([]byte, error) {
// TODO: add tests with invalid subtrees.
err := isSubtreeValid(start, end)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

It is highly recommended to validate the length of root1 against hasher.Size() to ensure correctness and prevent potential panics or unexpected behavior in downstream hashing operations.

func RootFromSubtreeConsistencyProof(hasher merkle.LogHasher, start, end, size uint64, proof [][]byte, root1 []byte) ([]byte, error) {
	if got, want := len(root1), hasher.Size(); got != want {
		return nil, fmt.Errorf("root1 has unexpected size %d, want %d", got, want)
	}
	// TODO: add tests with invalid subtrees.
	err := isSubtreeValid(start, end)

Comment thread proof/verify.go
Comment on lines +202 to +214
seed, pStart := proof[0], 1
// Unless the argument subtree is full, in which case that rightmost subtree
// is the argument subtree itself. Its root is not included in the proof
// since a client verifying a subtree inclusion proof is expected to already
// know what the root of that subtree is.
if (end - start) == 1<<uint(shift) {
seed, pStart = root1, 0
}
proof = proof[start:]
// Now len(proof) == inner+border, and proof is effectively a suffix of
// inclusion proof for entry |size1-1| in a tree of size |size2|.

// Verify the first root, if included in the proof.
if start != 0 {
mask := (size1 - 1) >> uint(shift) // Start chaining from level |shift|.
hash1 := chainInnerRight(hasher, seed, proof[:inner], mask)
hash1 = chainBorderRight(hasher, hash1, proof[inner:])
if err := verifyMatch(hash1, root1); err != nil {
return nil, err
}
wantProofLen := pStart + (forkLevel - shift) + bits.OnesCount64((end-1)>>forkLevel)
if got := len(proof); got != wantProofLen {
return nil, fmt.Errorf("wrong proof size %d, want %d", got, wantProofLen)
}
proof = proof[pStart:]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Accessing proof[0] before validating that len(proof) matches wantProofLen is risky and can lead to an out-of-bounds panic if the proof is empty. It is safer to determine pStart first, validate the proof length, and only then access proof[0] if pStart == 1.

Suggested change
seed, pStart := proof[0], 1
// Unless the argument subtree is full, in which case that rightmost subtree
// is the argument subtree itself. Its root is not included in the proof
// since a client verifying a subtree inclusion proof is expected to already
// know what the root of that subtree is.
if (end - start) == 1<<uint(shift) {
seed, pStart = root1, 0
}
proof = proof[start:]
// Now len(proof) == inner+border, and proof is effectively a suffix of
// inclusion proof for entry |size1-1| in a tree of size |size2|.
// Verify the first root, if included in the proof.
if start != 0 {
mask := (size1 - 1) >> uint(shift) // Start chaining from level |shift|.
hash1 := chainInnerRight(hasher, seed, proof[:inner], mask)
hash1 = chainBorderRight(hasher, hash1, proof[inner:])
if err := verifyMatch(hash1, root1); err != nil {
return nil, err
}
wantProofLen := pStart + (forkLevel - shift) + bits.OnesCount64((end-1)>>forkLevel)
if got := len(proof); got != wantProofLen {
return nil, fmt.Errorf("wrong proof size %d, want %d", got, wantProofLen)
}
proof = proof[pStart:]
var seed []byte
pStart := 1
// Unless the argument subtree is full, in which case that rightmost subtree
// is the argument subtree itself. Its root is not included in the proof
// since a client verifying a subtree inclusion proof is expected to already
// know what the root of that subtree is.
if (end - start) == 1<<uint(shift) {
seed, pStart = root1, 0
}
wantProofLen := pStart + (forkLevel - shift) + bits.OnesCount64((end-1)>>forkLevel)
if got := len(proof); got != wantProofLen {
return nil, fmt.Errorf("wrong proof size %d, want %d", got, wantProofLen)
}
if pStart == 1 {
seed = proof[0]
}
proof = proof[pStart:]

@phbnf
phbnf force-pushed the vercons-easy branch 2 times, most recently from 1d6215b to 1d7c956 Compare June 23, 2026 20:31
@phbnf

phbnf commented Jun 23, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces subtree consistency verification functionality to the proof package by adding VerifySubtreeConsistency and RootFromSubtreeConsistencyProof, along with internal helper functions like chainSubtree. It also refactors RootFromConsistencyProof to leverage these new subtree verification capabilities. The feedback suggests validating the size of the input root1 hash against the hasher's expected size to prevent potential panics or unexpected behavior.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread proof/verify.go Outdated
Comment on lines +170 to +171
func rootFromSubtreeConsistencyProof(hasher merkle.LogHasher, start, end, size uint64, proof [][]byte, root1 []byte) ([]byte, error) {
// If the right end of the subtree overlaps with the right end of the tree,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To ensure robustness and prevent potential panics or unexpected behavior in the underlying hasher, it is highly recommended to validate that the input root1 has the expected hash size (hasher.Size()) before proceeding with any hashing operations.

func rootFromSubtreeConsistencyProof(hasher merkle.LogHasher, start, end, size uint64, proof [][]byte, root1 []byte) ([]byte, error) {
	if got, want := len(root1), hasher.Size(); got != want {
		return nil, fmt.Errorf("root1 has unexpected size %d, want %d", got, want)
	}
	// If the right end of the subtree overlaps with the right end of the tree,

@phbnf
phbnf force-pushed the vercons-easy branch 5 times, most recently from 6d01611 to 12541f2 Compare June 23, 2026 21:34
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.

1 participant