Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
56fda78
buf plugin draft
pompon0 Dec 10, 2025
9e34cae
plugin has been placed
pompon0 Dec 10, 2025
e4ecde6
fmt
pompon0 Dec 11, 2025
29364aa
WIP
pompon0 Dec 11, 2025
e74e728
separate module
pompon0 Dec 12, 2025
3f5798b
added canonical encoding
pompon0 Dec 12, 2025
f8753b7
IsHashable
pompon0 Dec 12, 2025
510c3b9
fix and test
pompon0 Dec 12, 2025
d1b30ff
test updates
pompon0 Dec 12, 2025
9ad06cf
everything in place
pompon0 Dec 12, 2025
117563c
go fmt
pompon0 Dec 12, 2025
c27f7e6
Merge remote-tracking branch 'origin/main' into gprusak-proto
pompon0 Dec 12, 2025
77dc3a7
Merge branch 'main' into gprusak-proto
pompon0 Dec 12, 2025
4c7826a
changed location of the plugin
pompon0 Dec 12, 2025
24a2e25
Merge branch 'gprusak-proto' of https://github.com/sei-protocol/sei-c…
pompon0 Dec 12, 2025
118d566
nits
pompon0 Dec 12, 2025
0189653
panic msg
pompon0 Dec 12, 2025
c0a0ec5
moved all hashable stuff together
pompon0 Dec 15, 2025
15faaa5
moved testonly proto to internal
pompon0 Dec 15, 2025
9794896
fmt
pompon0 Dec 15, 2025
a82ac92
moved under internal
pompon0 Dec 15, 2025
50ae626
comment fix
pompon0 Dec 15, 2025
6160058
Merge branch 'main' into gprusak-proto
pompon0 Dec 15, 2025
51c83d6
ed25519 cleanup wip
pompon0 Dec 15, 2025
e571075
missing changes
pompon0 Dec 15, 2025
bf6e999
compilation fix
pompon0 Dec 15, 2025
f435bee
Merge branch 'gprusak-proto' of https://github.com/sei-protocol/sei-c…
pompon0 Dec 15, 2025
ac44467
Merge branch 'gprusak-proto' into gprusak-validator-proto
pompon0 Dec 15, 2025
9a3edcb
wip - what about non-validator mode?
pompon0 Dec 15, 2025
28bd678
wip
pompon0 Dec 15, 2025
f007432
wip; json is shit
pompon0 Dec 16, 2025
111028e
crypto test
pompon0 Dec 17, 2025
788f2c7
cleanup of typeRegistry
pompon0 Dec 17, 2025
09a5926
test for sig
pompon0 Dec 17, 2025
45766d7
fmt
pompon0 Dec 17, 2025
b0ce59f
copied from sei-v3
pompon0 Dec 17, 2025
ba9aedd
test
pompon0 Dec 17, 2025
afcacab
codex
pompon0 Dec 17, 2025
025fd15
codex tests
pompon0 Dec 18, 2025
72a985f
optional sig
pompon0 Dec 18, 2025
5b90ba9
codex tests
pompon0 Dec 18, 2025
cd7ed89
tests wip
pompon0 Dec 18, 2025
efd3576
Merge remote-tracking branch 'origin/main' into gprusak-validator-proto
pompon0 Dec 18, 2025
a9975f7
tendermint tests pass
pompon0 Dec 18, 2025
e866fc2
all tests compile
pompon0 Dec 18, 2025
e0043d0
fmt
pompon0 Dec 18, 2025
50d521b
Merge remote-tracking branch 'origin/main' into gprusak-validator-proto
pompon0 Dec 18, 2025
7aacf5b
moved roles to separate pr
pompon0 Dec 18, 2025
408f6b4
gofmt
pompon0 Dec 18, 2025
469c57d
stupid encoder
pompon0 Dec 18, 2025
b9c22b9
cachingVerifier
pompon0 Dec 18, 2025
adfabe9
Revert "moved roles to separate pr"
pompon0 Dec 19, 2025
b2ef6a7
partial refactor of SecretConnection
pompon0 Dec 19, 2025
1cd257d
slight refactor of secret connection
pompon0 Dec 22, 2025
cf932f1
dst for ed25519
pompon0 Dec 22, 2025
2fd8910
tm tests compile
pompon0 Dec 22, 2025
124731f
fmt
pompon0 Dec 22, 2025
2b6d4e2
regenerated
pompon0 Jan 1, 2026
4cf6982
Merge remote-tracking branch 'origin/main' into gprusak-validator-proto
pompon0 Jan 1, 2026
2a4d507
Merge branch 'gprusak-validator-proto' into gprusak-validator-proto2
pompon0 Jan 1, 2026
531b712
lint
pompon0 Jan 1, 2026
27e9f94
reverted validator
pompon0 Jan 1, 2026
4de17dc
generate
pompon0 Jan 1, 2026
1395734
Merge branch 'main' into gprusak-validator-proto2
pompon0 Jan 5, 2026
6420423
Merge branch 'main' into gprusak-validator-proto2
pompon0 Jan 5, 2026
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
37 changes: 18 additions & 19 deletions sei-cosmos/crypto/codec/tm.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package codec

import (
tmcrypto "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/encoding"
tmprotocrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
"github.com/tendermint/tendermint/crypto"
pb "github.com/tendermint/tendermint/proto/tendermint/crypto"

"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// FromTmProtoPublicKey converts a TM's tmprotocrypto.PublicKey into our own PubKey.
func FromTmProtoPublicKey(protoPk tmprotocrypto.PublicKey) (cryptotypes.PubKey, error) {
// FromTmProtoPublicKey converts a TM's pb.PublicKey into our own PubKey.
func FromTmProtoPublicKey(protoPk pb.PublicKey) (cryptotypes.PubKey, error) {
switch protoPk := protoPk.Sum.(type) {
case *tmprotocrypto.PublicKey_Ed25519:
case *pb.PublicKey_Ed25519:
return &ed25519.PubKey{
Key: protoPk.Ed25519,
}, nil
Expand All @@ -23,33 +22,33 @@ func FromTmProtoPublicKey(protoPk tmprotocrypto.PublicKey) (cryptotypes.PubKey,
}
}

// ToTmProtoPublicKey converts our own PubKey to TM's tmprotocrypto.PublicKey.
func ToTmProtoPublicKey(pk cryptotypes.PubKey) (tmprotocrypto.PublicKey, error) {
// ToTmProtoPublicKey converts our own PubKey to TM's pb.PublicKey.
func ToTmProtoPublicKey(pk cryptotypes.PubKey) (pb.PublicKey, error) {
switch pk := pk.(type) {
case *ed25519.PubKey:
return tmprotocrypto.PublicKey{
Sum: &tmprotocrypto.PublicKey_Ed25519{
return pb.PublicKey{
Sum: &pb.PublicKey_Ed25519{
Ed25519: pk.Key,
},
}, nil
case *secp256k1.PubKey:
return tmprotocrypto.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "secp256k1 consensus keys are not supported")
return pb.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "secp256k1 consensus keys are not supported")
default:
return tmprotocrypto.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v to Tendermint public key", pk)
return pb.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v to Tendermint public key", pk)
}
}

// FromTmPubKeyInterface converts TM's tmcrypto.PubKey to our own PubKey.
func FromTmPubKeyInterface(tmPk tmcrypto.PubKey) (cryptotypes.PubKey, error) {
return FromTmProtoPublicKey(encoding.PubKeyToProto(tmPk))
// FromTmPubKeyInterface converts TM's crypto.PubKey to our own PubKey.
func FromTmPubKeyInterface(tmPk crypto.PubKey) (cryptotypes.PubKey, error) {
return FromTmProtoPublicKey(crypto.PubKeyToProto(tmPk))
}

// ToTmPubKeyInterface converts our own PubKey to TM's tmcrypto.PubKey.
func ToTmPubKeyInterface(pk cryptotypes.PubKey) (tmcrypto.PubKey, error) {
// ToTmPubKeyInterface converts our own PubKey to TM's crypto.PubKey.
func ToTmPubKeyInterface(pk cryptotypes.PubKey) (crypto.PubKey, error) {
tmProtoPk, err := ToTmProtoPublicKey(pk)
if err != nil {
return tmcrypto.PubKey{}, err
return crypto.PubKey{}, err
}

return encoding.PubKeyFromProto(tmProtoPk)
return crypto.PubKeyFromProto(tmProtoPk)
}
6 changes: 3 additions & 3 deletions sei-cosmos/x/simulation/mock_tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"time"

abci "github.com/tendermint/tendermint/abci/types"
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/crypto"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
Expand Down Expand Up @@ -69,7 +69,7 @@ func (vals mockValidators) randomProposer(r *rand.Rand) tmbytes.HexBytes {
key := keys[r.Intn(len(keys))]

proposer := vals[key].val
pk, err := cryptoenc.PubKeyFromProto(proposer.PubKey)
pk, err := crypto.PubKeyFromProto(proposer.PubKey)
if err != nil { //nolint:wsl
panic(err)
}
Expand Down Expand Up @@ -149,7 +149,7 @@ func RandomRequestBeginBlock(r *rand.Rand, params Params,
event("begin_block", "signing", "missed")
}

pubkey, err := cryptoenc.PubKeyFromProto(mVal.val.PubKey)
pubkey, err := crypto.PubKeyFromProto(mVal.val.PubKey)
if err != nil {
panic(err)
}
Expand Down
5 changes: 4 additions & 1 deletion sei-tendermint/abci/example/kvstore/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ func RandVals(cnt int) []types.ValidatorUpdate {
if err != nil {
panic(err)
}
res[i] = types.UpdateValidator(pubKey, int64(power), "")
res[i] = types.ValidatorUpdate{
PubKey: crypto.PubKeyToProto(pubKey),
Power: int64(power),
}
}
return res
}
Expand Down
8 changes: 4 additions & 4 deletions sei-tendermint/abci/example/kvstore/kvstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (

"github.com/tendermint/tendermint/abci/example/code"
"github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/libs/log"
cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto"
"github.com/tendermint/tendermint/version"
Expand Down Expand Up @@ -329,7 +329,7 @@ func (app *Application) Validators() (validators []types.ValidatorUpdate) {
}

func MakeValSetChangeTx(pubkey cryptoproto.PublicKey, power int64) []byte {
pk, err := encoding.PubKeyFromProto(pubkey)
pk, err := crypto.PubKeyFromProto(pubkey)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -379,12 +379,12 @@ func (app *Application) execValidatorTx(tx []byte) *types.ExecTxResult {
Log: fmt.Sprintf("can't decode ed25519 key: %v", err),
}
}
return app.updateValidator(types.UpdateValidator(key, power, ""))
return app.updateValidator(types.ValidatorUpdate{PubKey: crypto.PubKeyToProto(key), Power: power})
}

// add, update, or remove a validator
func (app *Application) updateValidator(v types.ValidatorUpdate) *types.ExecTxResult {
pubkey, err := encoding.PubKeyFromProto(v.PubKey)
pubkey, err := crypto.PubKeyFromProto(v.PubKey)
if err != nil {
panic(fmt.Errorf("can't decode public key: %w", err))
}
Expand Down
5 changes: 4 additions & 1 deletion sei-tendermint/abci/tests/server/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ func InitChain(ctx context.Context, client abciclient.Client) error {
}
// nolint:gosec // G404: Use of weak random number generator
power := mrand.Int()
vals[i] = types.UpdateValidator(pubkey, int64(power), "")
vals[i] = types.ValidatorUpdate{
PubKey: crypto.PubKeyToProto(pubkey),
Power: int64(power),
}
}
_, err := client.InitChain(ctx, &types.RequestInitChain{
Validators: vals,
Expand Down
13 changes: 0 additions & 13 deletions sei-tendermint/abci/types/pubkey.go

This file was deleted.

5 changes: 2 additions & 3 deletions sei-tendermint/abci/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/gogo/protobuf/jsonpb"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/internal/jsontypes"
)

Expand Down Expand Up @@ -133,7 +132,7 @@ type validatorUpdateJSON struct {
}

func (v *ValidatorUpdate) MarshalJSON() ([]byte, error) {
key, err := encoding.PubKeyFromProto(v.PubKey)
key, err := crypto.PubKeyFromProto(v.PubKey)
if err != nil {
return nil, err
}
Expand All @@ -156,7 +155,7 @@ func (v *ValidatorUpdate) UnmarshalJSON(data []byte) error {
if err := jsontypes.Unmarshal(vu.PubKey, &key); err != nil {
return err
}
v.PubKey = encoding.PubKeyToProto(key)
v.PubKey = crypto.PubKeyToProto(key)
v.Power = vu.Power
return nil
}
Expand Down
35 changes: 35 additions & 0 deletions sei-tendermint/crypto/conv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package crypto

import (
"fmt"

"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/internal/jsontypes"
"github.com/tendermint/tendermint/libs/utils"
pb "github.com/tendermint/tendermint/proto/tendermint/crypto"
)

func init() {
jsontypes.MustRegister((*pb.PublicKey)(nil))
jsontypes.MustRegister((*pb.PublicKey_Ed25519)(nil))
}

var PubKeyConv = utils.ProtoConv[PubKey, *pb.PublicKey]{
Encode: func(k PubKey) *pb.PublicKey { return utils.Alloc(PubKeyToProto(k)) },
Decode: func(x *pb.PublicKey) (PubKey, error) { return PubKeyFromProto(*x) },
}

// PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey
func PubKeyToProto(k PubKey) pb.PublicKey {
return pb.PublicKey{Sum: &pb.PublicKey_Ed25519{Ed25519: k.Bytes()}}
}

// PubKeyFromProto takes a protobuf Pubkey and transforms it to a crypto.Pubkey
func PubKeyFromProto(k pb.PublicKey) (PubKey, error) {
switch k := k.Sum.(type) {
case *pb.PublicKey_Ed25519:
return ed25519.PublicKeyFromBytes(k.Ed25519)
default:
return PubKey{}, fmt.Errorf("fromproto: key type %v is not supported", k)
}
}
49 changes: 44 additions & 5 deletions sei-tendermint/crypto/ed25519/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const cacheSize = 4096
// curve25519-voi's Ed25519 implementation supports configurable
// verification behavior, and tendermint uses the ZIP-215 verification
// semantics.
var verifyOptions = &ed25519.Options{Verify: ed25519.VerifyOptionsZIP_215}
var verifyOptions = ed25519.VerifyOptionsZIP_215
var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize))

// SecretKey represents a secret key in the Ed25519 signature scheme.
Expand Down Expand Up @@ -129,26 +129,65 @@ func (k SecretKey) Sign(message []byte) Signature {
}
}

// Domain separation tag.
type Tag struct{ tag string }

func NewTag(tag string) (Tag, error) {
if len(tag) > ed25519.ContextMaxSize {
return Tag{}, fmt.Errorf("len(%q) = %v, want <= %v", tag, len(tag), ed25519.ContextMaxSize)
}
return Tag{tag}, nil
}

// SignWithTag signs a message with a domain separation tag.
// It is safe to assume that signatures for messages with different tags do not collide.
// It is also safe to assume that Sign() signatures do not collide with SignWithTag() signatures.
// It is secure to use the same secret key for signing with both Sign() and SignWithTag() [https://datatracker.ietf.org/doc/html/rfc8032#section-8.6].
func (k SecretKey) SignWithTag(tag Tag, msg []byte) Signature {
opts := &ed25519.Options{Context: tag.tag}
// Returns no error if opts.Context is of correct size.
sig := utils.OrPanic1(ed25519.PrivateKey((*k.key)[:]).Sign(nil, msg, opts))
return Signature{sig: [ed25519.SignatureSize]byte(sig)}
}

// Compare defines a total order on public keys.
func (k PublicKey) Compare(other PublicKey) int {
return bytes.Compare(k.key[:], other.key[:])
}

// Verify verifies a signature using the public key.
// Verify verifies a signature.
func (k PublicKey) Verify(msg []byte, sig Signature) error {
if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], verifyOptions) {
opts := &ed25519.Options{Verify: verifyOptions}
if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], opts) {
return ErrBadSig{}
}
return nil
}

// Verify verifies a signature, given domain separation tag.
func (k PublicKey) VerifyWithTag(tag Tag, msg []byte, sig Signature) error {
opts := &ed25519.Options{Context: tag.tag, Verify: verifyOptions}
if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], opts) {
return ErrBadSig{}
}
return nil
}

// BatchVerifier implements batch verification for ed25519.
type BatchVerifier struct{ inner *ed25519.BatchVerifier }
type BatchVerifier struct {
inner *ed25519.BatchVerifier
}

func NewBatchVerifier() *BatchVerifier { return &BatchVerifier{ed25519.NewBatchVerifier()} }

func (b *BatchVerifier) Add(key PublicKey, msg []byte, sig Signature) {
cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], verifyOptions)
opts := &ed25519.Options{Verify: verifyOptions}
cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], opts)
}

func (b *BatchVerifier) AddWithTag(key PublicKey, tag Tag, msg []byte, sig Signature) {
opts := &ed25519.Options{Context: tag.tag, Verify: verifyOptions}
cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], opts)
}

// Verify verifies the batched signatures using OS entropy.
Expand Down
54 changes: 48 additions & 6 deletions sei-tendermint/crypto/ed25519/ed25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ed25519

import (
"fmt"
"github.com/tendermint/tendermint/libs/utils"
"github.com/tendermint/tendermint/libs/utils/require"
"testing"
)
Expand All @@ -22,22 +23,63 @@ func TestSign(t *testing.T) {
}
}

func TestBatchSafe(t *testing.T) {
func TestSignWithTag(t *testing.T) {
var keys []SecretKey
for i := range byte(3) {
keys = append(keys, TestSecretKey([]byte{i}))
}
t.Logf("keys = %+v", keys)
msg := []byte("test message")
tag := utils.OrPanic1(NewTag("testTag"))
for i := range keys {
for j := range keys {
if wantErr, err := i != j, keys[j].Public().VerifyWithTag(tag, msg, keys[i].SignWithTag(tag, msg)); wantErr != (err != nil) {
t.Errorf("keys[%d].Verify(keys[%d].Sign()) = %v, wantErr = %v", j, i, err, wantErr)
}
}
}
}

func TestDomainSeparation(t *testing.T) {
msg := []byte("test message")
tag1 := utils.OrPanic1(NewTag("testTag"))
tag2 := utils.OrPanic1(NewTag("testTag2"))
k := TestSecretKey([]byte{34, 33})
sigs := map[utils.Option[Tag]]Signature{}
sigs[utils.Some(tag1)] = k.SignWithTag(tag1, msg)
sigs[utils.Some(tag2)] = k.SignWithTag(tag2, msg)
sigs[utils.None[Tag]()] = k.Sign(msg)
for _, tag := range utils.Slice(utils.Some(tag1), utils.Some(tag2), utils.None[Tag]()) {
for wantTag, sig := range sigs {
var err error
if tag, ok := tag.Get(); ok {
err = k.Public().VerifyWithTag(tag, msg, sig)
} else {
err = k.Public().Verify(msg, sig)
}
require.Equal(t, err == nil, tag == wantTag, "err = %v", err)
}
}
}

func TestBatchVerifier(t *testing.T) {
v := NewBatchVerifier()
tag := utils.OrPanic1(NewTag("testTag"))

for i := 0; i <= 38; i++ {
for i := range 100 {
priv := TestSecretKey(fmt.Appendf(nil, "test-%v", i))
pub := priv.Public()

var msg []byte
if i%2 == 0 {
msg = []byte("easter")
} else {
msg = []byte("egg")
}

v.Add(pub, msg, priv.Sign(msg))
if i%3 == 0 {
v.AddWithTag(pub, tag, msg, priv.SignWithTag(tag, msg))
} else {
v.Add(pub, msg, priv.Sign(msg))
}
}

require.NoError(t, v.Verify())
}
Loading
Loading