Skip to content

Commit

Permalink
feat: Caelum (#111)
Browse files Browse the repository at this point in the history
* bls signature for basic account

* benchmark for bls and ed25519

* added bls sig verify cost to genesis

* Revert "Merge branch 'fetchai:master' into bls"

This reverts commit a5dd8ea, reversing
changes made to 082e071.

* format using go tools

* nuisance golangci-lint errors

* Bls (#104)

* bls signature for basic account

* benchmark for bls and ed25519

* added bls sig verify cost to genesis

* Revert "Merge branch 'fetchai:master' into bls"

This reverts commit a5dd8ea, reversing
changes made to 082e071.

* format using go tools

* nuisance golangci-lint errors

* POP interfaces in accounts and authentication

* add bls multsig operations

* fixed golangci-lint error

* changes after comments

* initial commit from regen-ledger/x/group v1.0.0

* minor changes to bls12381 key generation

* initial commit from regen-ledger/proto/regen/group v1.0.0

* group module compatibility for fetchai cosomos-sdk

* add bls account restriction to group members

* fix bug in setting pop

* make msg uniqueness checking optional

* add bls basic/aggregate vote

* add checking on empty messages/public keys

* add gas caclulation/consumption for verifying aggregated votes

* minor change to gas calculation for voteagg

* initial commit for orm and types from regen-ledger v2.0.0-beta1

* upgrade testsuite to regen-ledger v2.0.0-beta1

* make bls requirement for group members optional

* add tests for bls related group operations

* client and server for poll and aggregated votes and integration tests

* fix bls related test errors

* fix proto-lint errors

* goimport format

* proto comments

* update blst to v0.3.5 and more tests for bls

* Update x/auth/ante/sigverify.go

Co-authored-by: daeMOn <[email protected]>

* Update x/group/client/util.go

Co-authored-by: daeMOn <[email protected]>

Co-authored-by: daeMOn <[email protected]>
  • Loading branch information
kitounliu and daeMOn63 authored Oct 11, 2021
1 parent dc0f978 commit 63cc12b
Show file tree
Hide file tree
Showing 120 changed files with 55,264 additions and 83 deletions.
9 changes: 7 additions & 2 deletions crypto/keys/bls12381/bls12381.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func genPrivKey(rand io.Reader) []byte {

sk := blst.KeyGen(ikm[:])
if sk == nil {
panic("Failed to generate secret key!")
panic("failed to generate secret key!")
}

skBytes := sk.Serialize()
Expand All @@ -136,7 +136,12 @@ func genPrivKey(rand io.Reader) []byte {
// if it's derived from user input.
func GenPrivKeyFromSecret(secret []byte) *PrivKey {
ikm := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes.
skBytes := blst.KeyGen(ikm).Serialize()

sk := blst.KeyGen(ikm)
if sk == nil {
panic("failed to generate secret key from ikm")
}
skBytes := sk.Serialize()

return &PrivKey{Key: skBytes}
}
Expand Down
170 changes: 169 additions & 1 deletion crypto/keys/bls12381/bls12381_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package bls12381_test

import (
"encoding/base64"
"testing"

"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/bls12381"
bench "github.com/cosmos/cosmos-sdk/crypto/keys/internal/benchmarking"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"testing"
)

func TestSignAndValidateBls12381(t *testing.T) {
Expand All @@ -22,6 +30,166 @@ func TestSignAndValidateBls12381(t *testing.T) {

}

func TestKeyFromSecret(t *testing.T) {
insecureSeed := []byte("a random number for testing")
privKey := bls12381.GenPrivKeyFromSecret(insecureSeed)
pubKey := privKey.PubKey()

msg := []byte("hello")
sig, err := privKey.Sign(msg)
require.Nil(t, err)
assert.True(t, pubKey.VerifySignature(msg, sig))
}

func TestPubKeyEquals(t *testing.T) {
bls12381PubKey := bls12381.GenPrivKey().PubKey().(*bls12381.PubKey)

testCases := []struct {
msg string
pubKey cryptotypes.PubKey
other cryptotypes.PubKey
expectEq bool
}{
{
"different bytes",
bls12381PubKey,
bls12381.GenPrivKey().PubKey(),
false,
},
{
"equals",
bls12381PubKey,
&bls12381.PubKey{
Key: bls12381PubKey.Key,
},
true,
},
{
"different types",
bls12381PubKey,
secp256k1.GenPrivKey().PubKey(),
false,
},
}

for _, tc := range testCases {
t.Run(tc.msg, func(t *testing.T) {
eq := tc.pubKey.Equals(tc.other)
require.Equal(t, eq, tc.expectEq)
})
}
}

func TestPrivKeyEquals(t *testing.T) {
bls12381PrivKey := bls12381.GenPrivKey()

testCases := []struct {
msg string
privKey cryptotypes.PrivKey
other cryptotypes.PrivKey
expectEq bool
}{
{
"different bytes",
bls12381PrivKey,
bls12381.GenPrivKey(),
false,
},
{
"equals",
bls12381PrivKey,
&bls12381.PrivKey{
Key: bls12381PrivKey.Key,
},
true,
},
{
"different types",
bls12381PrivKey,
secp256k1.GenPrivKey(),
false,
},
}

for _, tc := range testCases {
t.Run(tc.msg, func(t *testing.T) {
eq := tc.privKey.Equals(tc.other)
require.Equal(t, eq, tc.expectEq)
})
}
}

func TestMarshalAmino(t *testing.T) {
aminoCdc := codec.NewLegacyAmino()
privKey := bls12381.GenPrivKey()
pubKey := privKey.PubKey().(*bls12381.PubKey)

testCases := []struct {
desc string
msg codec.AminoMarshaler
typ interface{}
expBinary []byte
expJSON string
}{
{
"bls12381 private key",
privKey,
&bls12381.PrivKey{},
append([]byte{32}, privKey.Bytes()...), // Length-prefixed.
"\"" + base64.StdEncoding.EncodeToString(privKey.Bytes()) + "\"",
},
{
"bls12381 public key",
pubKey,
&bls12381.PubKey{},
append([]byte{96}, pubKey.Bytes()...), // Length-prefixed.
"\"" + base64.StdEncoding.EncodeToString(pubKey.Bytes()) + "\"",
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
// Do a round trip of encoding/decoding binary.
bz, err := aminoCdc.Marshal(tc.msg)
require.NoError(t, err)
require.Equal(t, tc.expBinary, bz)

err = aminoCdc.Unmarshal(bz, tc.typ)
require.NoError(t, err)

require.Equal(t, tc.msg, tc.typ)

// Do a round trip of encoding/decoding JSON.
bz, err = aminoCdc.MarshalJSON(tc.msg)
require.NoError(t, err)
require.Equal(t, tc.expJSON, string(bz))

err = aminoCdc.UnmarshalJSON(bz, tc.typ)
require.NoError(t, err)

require.Equal(t, tc.msg, tc.typ)
})
}
}

func TestMarshalJSON(t *testing.T) {
require := require.New(t)
privKey := bls12381.GenPrivKey()
pk := privKey.PubKey()

registry := types.NewInterfaceRegistry()
cryptocodec.RegisterInterfaces(registry)
cdc := codec.NewProtoCodec(registry)

bz, err := cdc.MarshalInterfaceJSON(pk)
require.NoError(err)

var pk2 cryptotypes.PubKey
err = cdc.UnmarshalInterfaceJSON(bz, &pk2)
require.NoError(err)
require.True(pk2.Equals(pk))
}

func BenchmarkSignBls(b *testing.B) {
privKey := bls12381.GenPrivKey()

Expand Down
22 changes: 18 additions & 4 deletions crypto/keys/bls12381/multisig.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func AggregateSignature(sigs [][]byte) ([]byte, error) {

// VerifyMultiSignature assumes public key is already validated
func VerifyMultiSignature(msg []byte, sig []byte, pks []*PubKey) error {
return VerifyAggregateSignature([][]byte{msg}, sig, [][]*PubKey{pks})
return VerifyAggregateSignature([][]byte{msg}, false, sig, [][]*PubKey{pks})
}

func Unique(msgs [][]byte) bool {
Expand All @@ -65,18 +65,32 @@ func Unique(msgs [][]byte) bool {
return true
}

func VerifyAggregateSignature(msgs [][]byte, sig []byte, pkss [][]*PubKey) error {
func VerifyAggregateSignature(msgs [][]byte, msgCheck bool, sig []byte, pkss [][]*PubKey) error {
n := len(msgs)
if n == 0 {
return fmt.Errorf("messages cannot be empty")
}

for i, msg := range msgs {
if len(msg) == 0 {
return fmt.Errorf("%d-th message is empty", i)
}
}

if len(pkss) != n {
return fmt.Errorf("the number of messages and public key sets must match")
}

if !Unique(msgs) {
return fmt.Errorf("messages must be pairwise distinct")
for i, pks := range pkss {
if len(pks) == 0 {
return fmt.Errorf("%d-th public key set is empty", i)
}
}

if msgCheck {
if !Unique(msgs) {
return fmt.Errorf("messages must be pairwise distinct")
}
}

apks := make([]*blst.P1Affine, len(pkss))
Expand Down
5 changes: 2 additions & 3 deletions crypto/keys/bls12381/multisig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ func TestBlsAggSig(t *testing.T) {
aggSig, err := bls.AggregateSignature(sigs)
require.Nil(t, err)

assert.Nil(t, bls.VerifyAggregateSignature(msgs, aggSig, pks))

assert.Nil(t, bls.VerifyAggregateSignature(msgs, true, aggSig, pks))
}

func benchmarkBlsVerifyMulti(total int, b *testing.B) {
Expand Down Expand Up @@ -113,7 +112,7 @@ func benchmarkBlsVerifyAgg(total int, b *testing.B) {
b.ResetTimer()

for i := 0; i < b.N; i++ {
bls.VerifyAggregateSignature(msgs, aggSig, pks)
bls.VerifyAggregateSignature(msgs, false, aggSig, pks)
}
}

Expand Down
3 changes: 1 addition & 2 deletions crypto/keys/ed25519/ed25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ package ed25519_test
import (
stded25519 "crypto/ed25519"
"encoding/base64"
"testing"

bench "github.com/cosmos/cosmos-sdk/crypto/keys/internal/benchmarking"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/bgentry/speakeasy v0.1.0
github.com/btcsuite/btcd v0.22.0-beta
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cockroachdb/apd/v2 v2.0.2
github.com/coinbase/rosetta-sdk-go v0.6.10
github.com/confio/ics23/go v0.6.6
github.com/cosmos/go-bip39 v1.0.0
Expand All @@ -27,6 +28,7 @@ require (
github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87
github.com/improbable-eng/grpc-web v0.14.0
github.com/jhump/protoreflect v1.8.2
github.com/lib/pq v1.10.2 // indirect
github.com/magiconair/properties v1.8.5
github.com/mattn/go-isatty v0.0.13
github.com/otiai10/copy v1.6.0
Expand All @@ -41,18 +43,19 @@ require (
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.8.0
github.com/stretchr/testify v1.7.0
github.com/supranational/blst v0.3.4
github.com/supranational/blst v0.3.5
github.com/tendermint/btcd v0.1.1
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15
github.com/tendermint/go-amino v0.16.0
github.com/tendermint/tendermint v0.34.11
github.com/tendermint/tm-db v0.6.4
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c
google.golang.org/grpc v1.38.0
google.golang.org/protobuf v1.26.0
gopkg.in/yaml.v2 v2.4.0
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v0.4.7
)

replace google.golang.org/grpc => google.golang.org/grpc v1.33.2
Expand Down
17 changes: 12 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E=
github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coinbase/rosetta-sdk-go v0.6.10 h1:rgHD/nHjxLh0lMEdfGDqpTtlvtSBwULqrrZ2qPdNaCM=
Expand Down Expand Up @@ -480,6 +482,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
Expand Down Expand Up @@ -725,8 +729,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/supranational/blst v0.3.4 h1:iZE9lBMoywK2uy2U/5hDOvobQk9FnOQ2wNlu9GmRCoA=
github.com/supranational/blst v0.3.4/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/supranational/blst v0.3.5 h1:/pey7U712GgJBSD1XTiJ5iBqjYIH3QNdrjRoGXlJJ60=
github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok=
Expand Down Expand Up @@ -817,8 +821,8 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down Expand Up @@ -997,8 +1001,9 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand Down Expand Up @@ -1212,6 +1217,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g=
pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
Expand Down
Loading

0 comments on commit 63cc12b

Please sign in to comment.