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

Fix VerifyMembership proof #11

Merged
merged 6 commits into from
Jan 31, 2024
Merged
Changes from 4 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
35 changes: 34 additions & 1 deletion modules/light-clients/xx-mock/types/client_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package types
import (
"bytes"
"crypto/sha256"
"math/big"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
)

Expand Down Expand Up @@ -113,7 +115,38 @@ func (cs ClientState) VerifyMembership(
return sdkerrors.Wrap(clienttypes.ErrConsensusStateNotFound, "please ensure the proof was constructed against a height that exists on the client")
}

h := sha256.Sum256(value)
// sha256(abi.encodePacked(height.toUint128(), sha256(prefix), sha256(path), sha256(value)))
revisionNumber := height.GetRevisionNumber()
revisionHeight := height.GetRevisionHeight()

heightBig := new(big.Int)
revisionNumberBig := new(big.Int).SetUint64(revisionNumber)
revisionNumberBig = revisionNumberBig.Lsh(revisionNumberBig, 64)
revisionHeightBig := new(big.Int).SetUint64(revisionHeight)
heightBig.Or(revisionNumberBig, revisionHeightBig)
hashHeight := sha256.Sum256(heightBig.Bytes())
Copy link
Contributor

@siburu siburu Dec 21, 2023

Choose a reason for hiding this comment

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

There are two mistakes.

  • Look at the spec again. height is concatenated to the other stuffs before hashing.
  • The byte length of heightBig.Bytes() can be less than 16.
    • For example, if revisionNumber == 0, it will be 8.
    • You should use FillBytes instead of Bytes.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can use encoding/binary to do this easilier.
https://pkg.go.dev/encoding/binary#example-ByteOrder-Put

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks
Change to use encoding/binary
28f2d67


merklePath := path.(commitmenttypes.MerklePath)
mPrefix, err := merklePath.GetKey(0)
if err != nil {
return sdkerrors.Wrapf(err, "invalid merkle path key at index 0")
}
mPath, err := merklePath.GetKey(1)
if err != nil {
return sdkerrors.Wrapf(err, "invalid merkle path key at index 1")
}

hashPrefix := sha256.Sum256([]byte(mPrefix))
hashPath := sha256.Sum256([]byte(mPath))
hashValue := sha256.Sum256([]byte(value))

var combined []byte
combined = append(combined, hashHeight[:]...)
combined = append(combined, hashPrefix[:]...)
combined = append(combined, hashPath[:]...)
combined = append(combined, hashValue[:]...)
h := sha256.Sum256(combined)

if !bytes.Equal(proof, h[:]) {
return sdkerrors.Wrapf(ErrInvalidProof, "expected the proof '%X', actually got '%X'", h, proof)
}
Expand Down
Loading