From 9fbcbc1ac8c4da9726ab33803e91ff5700926b4f Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 13 Aug 2019 21:43:29 -0700 Subject: [PATCH] bls message signature verification --- chain/messagepool.go | 18 ++++++------------ chain/types/signature.go | 21 +++++++++++++++++++++ cli/send.go | 4 ++-- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/chain/messagepool.go b/chain/messagepool.go index 4761fc9f0..6c6aeebd0 100644 --- a/chain/messagepool.go +++ b/chain/messagepool.go @@ -92,21 +92,21 @@ func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) { return act.Nonce, nil } -func (mp *MessagePool) Remove(m *types.SignedMessage) { +func (mp *MessagePool) Remove(from address.Address, nonce uint64) { mp.lk.Lock() defer mp.lk.Unlock() - mset, ok := mp.pending[m.Message.From] + mset, ok := mp.pending[from] if !ok { return } // NB: This deletes any message with the given nonce. This makes sense // as two messages with the same sender cannot have the same nonce - delete(mset.msgs, m.Message.Nonce) + delete(mset.msgs, nonce) if len(mset.msgs) == 0 { - delete(mp.pending, m.Message.From) + delete(mp.pending, from) } } @@ -160,17 +160,11 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet) return errors.Wrapf(err, "failed to get messages for apply block %s(height %d) (msgroot = %s)", b.Cid(), b.Height, b.Messages) } for _, msg := range smsgs { - mp.Remove(msg) + mp.Remove(msg.Message.From, msg.Message.Nonce) } for _, msg := range bmsgs { - smsg := mp.RecoverSig(msg) - if smsg != nil { - mp.Remove(smsg) - } else { - // TODO: this one is likely fine - log.Warnf("could not recover signature for bls message %s during a reorg apply", msg.Cid()) - } + mp.Remove(msg.From, msg.Nonce) } } } diff --git a/chain/types/signature.go b/chain/types/signature.go index 67fa4d114..82226fb03 100644 --- a/chain/types/signature.go +++ b/chain/types/signature.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "fmt" + bls "github.com/filecoin-project/go-bls-sigs" "github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/lib/crypto" cbor "github.com/ipfs/go-ipld-cbor" @@ -45,6 +46,8 @@ func SignatureFromBytes(x []byte) (Signature, error) { switch val { case 1: ts = KTSecp256k1 + case 2: + ts = KTBLS default: return Signature{}, fmt.Errorf("unsupported signature type: %d", val) } @@ -56,6 +59,9 @@ func SignatureFromBytes(x []byte) (Signature, error) { } func (s *Signature) Verify(addr address.Address, msg []byte) error { + if addr.Protocol() == address.ID { + return fmt.Errorf("must resolve ID addresses before using them to verify a signature") + } b2sum := blake2b.Sum256(msg) switch s.Type { @@ -74,6 +80,21 @@ func (s *Signature) Verify(addr address.Address, msg []byte) error { return fmt.Errorf("signature did not match") } + return nil + case KTBLS: + digests := []bls.Digest{bls.Hash(bls.Message(msg))} + + var pubk bls.PublicKey + copy(pubk[:], addr.Payload()) + pubkeys := []bls.PublicKey{pubk} + + var sig bls.Signature + copy(sig[:], s.Data) + + if !bls.Verify(sig, digests, pubkeys) { + return fmt.Errorf("bls signature failed to verify") + } + return nil default: return fmt.Errorf("cannot verify signature of unsupported type: %s", s.Type) diff --git a/cli/send.go b/cli/send.go index 47837c747..21a4d84e0 100644 --- a/cli/send.go +++ b/cli/send.go @@ -66,8 +66,8 @@ var sendCmd = &cli.Command{ To: toAddr, Value: val, Nonce: nonce, - GasLimit: types.NewInt(10000), - GasPrice: types.NewInt(1), + GasLimit: types.NewInt(1000), + GasPrice: types.NewInt(0), } sermsg, err := msg.Serialize()