Merge pull request #1188 from filecoin-project/feat/sigs-standalone
Don't depend on ffi
This commit is contained in:
commit
955b86deea
@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageMarketActor struct{}
|
type StorageMarketActor struct{}
|
||||||
@ -131,7 +132,7 @@ func (sdp *StorageDealProposal) Verify(worker address.Address) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sdp.ProposerSignature.Verify(sdp.Client, buf.Bytes()); err != nil {
|
if err := sigs.Verify(sdp.ProposerSignature, sdp.Client, buf.Bytes()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StoragePowerActor struct{}
|
type StoragePowerActor struct{}
|
||||||
@ -170,11 +171,11 @@ func (spa StoragePowerActor) ArbitrateConsensusFault(act *types.Actor, vmctx typ
|
|||||||
return nil, aerrors.Absorb(oerr, 3, "response from 'GetWorkerAddr' was not a valid address")
|
return nil, aerrors.Absorb(oerr, 3, "response from 'GetWorkerAddr' was not a valid address")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := params.Block1.CheckBlockSignature(vmctx.Context(), worker); err != nil {
|
if err := sigs.CheckBlockSignature(params.Block1, vmctx.Context(), worker); err != nil {
|
||||||
return nil, aerrors.Absorb(err, 4, "block1 did not have valid signature")
|
return nil, aerrors.Absorb(err, 4, "block1 did not have valid signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := params.Block2.CheckBlockSignature(vmctx.Context(), worker); err != nil {
|
if err := sigs.CheckBlockSignature(params.Block2, vmctx.Context(), worker); err != nil {
|
||||||
return nil, aerrors.Absorb(err, 5, "block2 did not have valid signature")
|
return nil, aerrors.Absorb(err, 5, "block2 did not have valid signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
|
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
|
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
hamt "github.com/ipfs/go-hamt-ipld"
|
||||||
|
@ -9,34 +9,33 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
block "github.com/ipfs/go-block-format"
|
||||||
|
|
||||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
|
||||||
|
|
||||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
|
||||||
"github.com/ipfs/go-blockservice"
|
"github.com/ipfs/go-blockservice"
|
||||||
"github.com/ipfs/go-car"
|
"github.com/ipfs/go-car"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/ipfs/go-merkledag"
|
"github.com/ipfs/go-merkledag"
|
||||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||||
"go.opencensus.io/trace"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
|
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
||||||
"github.com/filecoin-project/lotus/genesis"
|
"github.com/filecoin-project/lotus/genesis"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
"go.opencensus.io/trace"
|
||||||
"github.com/ipfs/go-cid"
|
"golang.org/x/xerrors"
|
||||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("gen")
|
var log = logging.Logger("gen")
|
||||||
@ -631,7 +630,7 @@ func VerifyVRF(ctx context.Context, worker, miner address.Address, p uint64, inp
|
|||||||
Data: vrfproof,
|
Data: vrfproof,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sig.Verify(worker, vrfBase); err != nil {
|
if err := sigs.Verify(sig, worker, vrfBase); err != nil {
|
||||||
return xerrors.Errorf("vrf was invalid: %w", err)
|
return xerrors.Errorf("vrf was invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -303,7 +304,7 @@ func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet) error
|
|||||||
return ErrMessageValueTooHigh
|
return ErrMessageValueTooHigh
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.Signature.Verify(m.Message.From, m.Message.Cid().Bytes()); err != nil {
|
if err := sigs.Verify(&m.Signature, m.Message.From, m.Message.Cid().Bytes()); err != nil {
|
||||||
log.Warnf("mpooladd signature verification failed: %s", err)
|
log.Warnf("mpooladd signature verification failed: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
|
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
|
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
)
|
)
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("chain")
|
var log = logging.Logger("chain")
|
||||||
@ -604,7 +605,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockSigCheck := async.Err(func() error {
|
blockSigCheck := async.Err(func() error {
|
||||||
if err := h.CheckBlockSignature(ctx, waddr); err != nil {
|
if err := sigs.CheckBlockSignature(h, ctx, waddr); err != nil {
|
||||||
return xerrors.Errorf("check block signature failed: %w", err)
|
return xerrors.Errorf("check block signature failed: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -787,7 +788,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
|||||||
return xerrors.Errorf("failed to resolve key addr: %w", err)
|
return xerrors.Errorf("failed to resolve key addr: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.Signature.Verify(kaddr, m.Message.Cid().Bytes()); err != nil {
|
if err := sigs.Verify(&m.Signature, kaddr, m.Message.Cid().Bytes()); err != nil {
|
||||||
return xerrors.Errorf("secpk message %s has invalid signature: %w", m.Cid(), err)
|
return xerrors.Errorf("secpk message %s has invalid signature: %w", m.Cid(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
//+build cgo
|
|
||||||
|
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"go.opencensus.io/trace"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (blk *BlockHeader) CheckBlockSignature(ctx context.Context, worker address.Address) error {
|
|
||||||
_, span := trace.StartSpan(ctx, "checkBlockSignature")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if blk.BlockSig == nil {
|
|
||||||
return xerrors.New("block signature not present")
|
|
||||||
}
|
|
||||||
|
|
||||||
sigb, err := blk.SigningBytes()
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("failed to get block signing bytes: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return blk.BlockSig.Verify(worker, sigb)
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
//+build cgo
|
|
||||||
|
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
bls "github.com/filecoin-project/filecoin-ffi"
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-crypto"
|
|
||||||
"github.com/minio/blake2b-simd"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Signature) Verify(addr address.Address, msg []byte) error {
|
|
||||||
if s == nil {
|
|
||||||
return xerrors.Errorf("signature is nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
case KTSecp256k1:
|
|
||||||
pubk, err := crypto.EcRecover(b2sum[:], s.Data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
maybeaddr, err := address.NewSecp256k1Address(pubk)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if addr != maybeaddr {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/state"
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/lib/bufbstore"
|
"github.com/filecoin-project/lotus/lib/bufbstore"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("vm")
|
var log = logging.Logger("vm")
|
||||||
@ -196,7 +197,7 @@ func (vmctx *VMContext) VerifySignature(sig *types.Signature, act address.Addres
|
|||||||
act = kaddr
|
act = kaddr
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sig.Verify(act, data); err != nil {
|
if err := sigs.Verify(sig, act, data); err != nil {
|
||||||
return aerrors.New(2, "signature verification failed")
|
return aerrors.New(2, "signature verification failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,20 +2,16 @@ package wallet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
bls "github.com/filecoin-project/filecoin-ffi"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/minio/blake2b-simd"
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-crypto"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("wallet")
|
var log = logging.Logger("wallet")
|
||||||
@ -61,31 +57,7 @@ func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*t
|
|||||||
return nil, xerrors.Errorf("signing using key '%s': %w", addr.String(), types.ErrKeyInfoNotFound)
|
return nil, xerrors.Errorf("signing using key '%s': %w", addr.String(), types.ErrKeyInfoNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ki.Type {
|
return sigs.Sign(ki.Type, ki.PrivateKey, msg)
|
||||||
case types.KTSecp256k1:
|
|
||||||
b2sum := blake2b.Sum256(msg)
|
|
||||||
sig, err := crypto.Sign(ki.PrivateKey, b2sum[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Signature{
|
|
||||||
Type: types.KTSecp256k1,
|
|
||||||
Data: sig,
|
|
||||||
}, nil
|
|
||||||
case types.KTBLS:
|
|
||||||
var pk bls.PrivateKey
|
|
||||||
copy(pk[:], ki.PrivateKey)
|
|
||||||
sig := bls.PrivateKeySign(pk, msg)
|
|
||||||
|
|
||||||
return &types.Signature{
|
|
||||||
Type: types.KTBLS,
|
|
||||||
Data: sig[:],
|
|
||||||
}, nil
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("cannot sign with unsupported key type: %q", ki.Type)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wallet) findKey(addr address.Address) (*Key, error) {
|
func (w *Wallet) findKey(addr address.Address) (*Key, error) {
|
||||||
@ -204,29 +176,15 @@ func (w *Wallet) SetDefault(a address.Address) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GenerateKey(typ string) (*Key, error) {
|
func GenerateKey(typ string) (*Key, error) {
|
||||||
switch typ {
|
pk, err := sigs.Generate(typ)
|
||||||
case types.KTSecp256k1:
|
if err != nil {
|
||||||
priv, err := crypto.GenerateKey()
|
return nil, err
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ki := types.KeyInfo{
|
|
||||||
Type: typ,
|
|
||||||
PrivateKey: priv,
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewKey(ki)
|
|
||||||
case types.KTBLS:
|
|
||||||
priv := bls.PrivateKeyGenerate()
|
|
||||||
ki := types.KeyInfo{
|
|
||||||
Type: typ,
|
|
||||||
PrivateKey: priv[:],
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewKey(ki)
|
|
||||||
default:
|
|
||||||
return nil, xerrors.Errorf("invalid key type: %s", typ)
|
|
||||||
}
|
}
|
||||||
|
ki := types.KeyInfo{
|
||||||
|
Type: typ,
|
||||||
|
PrivateKey: pk,
|
||||||
|
}
|
||||||
|
return NewKey(ki)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Wallet) GenerateKey(typ string) (address.Address, error) {
|
func (w *Wallet) GenerateKey(typ string) (address.Address, error) {
|
||||||
@ -277,28 +235,23 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
|
|||||||
KeyInfo: keyinfo,
|
KeyInfo: keyinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
k.PublicKey, err = sigs.ToPublic(k.Type, k.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
switch k.Type {
|
switch k.Type {
|
||||||
case types.KTSecp256k1:
|
case types.KTSecp256k1:
|
||||||
k.PublicKey = crypto.PublicKey(k.PrivateKey)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
k.Address, err = address.NewSecp256k1Address(k.PublicKey)
|
k.Address, err = address.NewSecp256k1Address(k.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err)
|
return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
case types.KTBLS:
|
case types.KTBLS:
|
||||||
var pk bls.PrivateKey
|
|
||||||
copy(pk[:], k.PrivateKey)
|
|
||||||
pub := bls.PrivateKeyPublicKey(pk)
|
|
||||||
k.PublicKey = pub[:]
|
|
||||||
|
|
||||||
var err error
|
|
||||||
k.Address, err = address.NewBLSAddress(k.PublicKey)
|
k.Address, err = address.NewBLSAddress(k.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("converting BLS to address: %w", err)
|
return nil, xerrors.Errorf("converting BLS to address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, xerrors.Errorf("unknown key type")
|
return nil, xerrors.Errorf("unknown key type")
|
||||||
}
|
}
|
||||||
|
52
lib/sigs/bls/init.go
Normal file
52
lib/sigs/bls/init.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package bls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type blsSigner struct{}
|
||||||
|
|
||||||
|
func (blsSigner) GenPrivate() ([]byte, error) {
|
||||||
|
pk := ffi.PrivateKeyGenerate()
|
||||||
|
return pk[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blsSigner) ToPublic(priv []byte) ([]byte, error) {
|
||||||
|
var pk ffi.PrivateKey
|
||||||
|
copy(pk[:], priv)
|
||||||
|
pub := ffi.PrivateKeyPublicKey(pk)
|
||||||
|
return pub[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blsSigner) Sign(p []byte, msg []byte) ([]byte, error) {
|
||||||
|
var pk ffi.PrivateKey
|
||||||
|
copy(pk[:], p)
|
||||||
|
sig := ffi.PrivateKeySign(pk, msg)
|
||||||
|
return sig[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error {
|
||||||
|
digests := []ffi.Digest{ffi.Hash(ffi.Message(msg))}
|
||||||
|
|
||||||
|
var pubk ffi.PublicKey
|
||||||
|
copy(pubk[:], a.Payload())
|
||||||
|
pubkeys := []ffi.PublicKey{pubk}
|
||||||
|
|
||||||
|
var s ffi.Signature
|
||||||
|
copy(s[:], sig)
|
||||||
|
|
||||||
|
if !ffi.Verify(&s, digests, pubkeys) {
|
||||||
|
return fmt.Errorf("bls signature failed to verify")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sigs.RegisterSignature(types.KTBLS, blsSigner{})
|
||||||
|
}
|
9
lib/sigs/doc.go
Normal file
9
lib/sigs/doc.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Sigs package allows for signing, verifying signatures and key generation
|
||||||
|
// using key types selected by package user.
|
||||||
|
//
|
||||||
|
// For support of secp256k1 import:
|
||||||
|
// _ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
|
//
|
||||||
|
// For support of Filecoin BLS import:
|
||||||
|
// _ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
|
package sigs
|
58
lib/sigs/secp/init.go
Normal file
58
lib/sigs/secp/init.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package secp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-crypto"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
|
"github.com/minio/blake2b-simd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type secpSigner struct{}
|
||||||
|
|
||||||
|
func (secpSigner) GenPrivate() ([]byte, error) {
|
||||||
|
priv, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return priv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (secpSigner) ToPublic(pk []byte) ([]byte, error) {
|
||||||
|
return crypto.PublicKey(pk), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (secpSigner) Sign(pk []byte, msg []byte) ([]byte, error) {
|
||||||
|
b2sum := blake2b.Sum256(msg)
|
||||||
|
sig, err := crypto.Sign(pk, b2sum[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (secpSigner) Verify(sig []byte, a address.Address, msg []byte) error {
|
||||||
|
b2sum := blake2b.Sum256(msg)
|
||||||
|
pubk, err := crypto.EcRecover(b2sum[:], sig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeaddr, err := address.NewSecp256k1Address(pubk)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if a != maybeaddr {
|
||||||
|
return fmt.Errorf("signature did not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sigs.RegisterSignature(types.KTSecp256k1, secpSigner{})
|
||||||
|
}
|
102
lib/sigs/sigs.go
Normal file
102
lib/sigs/sigs.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package sigs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sign takes in signature type, private key and message. Returns a signature for that message.
|
||||||
|
// Valid sigTypes are: "secp256k1" and "bls"
|
||||||
|
func Sign(sigType string, privkey []byte, msg []byte) (*types.Signature, error) {
|
||||||
|
sv, ok := sigs[sigType]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot sign message with signature of unsupported type: %s", sigType)
|
||||||
|
}
|
||||||
|
|
||||||
|
sb, err := sv.Sign(privkey, msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &types.Signature{
|
||||||
|
Type: sigType,
|
||||||
|
Data: sb,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify verifies signatures
|
||||||
|
func Verify(sig *types.Signature, addr address.Address, msg []byte) error {
|
||||||
|
if sig == nil {
|
||||||
|
return xerrors.Errorf("signature is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if addr.Protocol() == address.ID {
|
||||||
|
return fmt.Errorf("must resolve ID addresses before using them to verify a signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
sv, ok := sigs[sig.Type]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("cannot verify signature of unsupported type: %s", sig.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.Verify(sig.Data, addr, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate generates private key of given type
|
||||||
|
func Generate(sigType string) ([]byte, error) {
|
||||||
|
sv, ok := sigs[sigType]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot generate private key of unsupported type: %s", sigType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.GenPrivate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToPublic converts private key to public key
|
||||||
|
func ToPublic(sigType string, pk []byte) ([]byte, error) {
|
||||||
|
sv, ok := sigs[sigType]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot generate public key of unsupported type: %s", sigType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.ToPublic(pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckBlockSignature(blk *types.BlockHeader, ctx context.Context, worker address.Address) error {
|
||||||
|
_, span := trace.StartSpan(ctx, "checkBlockSignature")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if blk.BlockSig == nil {
|
||||||
|
return xerrors.New("block signature not present")
|
||||||
|
}
|
||||||
|
|
||||||
|
sigb, err := blk.SigningBytes()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to get block signing bytes: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = sigb
|
||||||
|
return Verify(blk.BlockSig, worker, sigb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SigShim is used for introducing signature functions
|
||||||
|
type SigShim interface {
|
||||||
|
GenPrivate() ([]byte, error)
|
||||||
|
ToPublic(pk []byte) ([]byte, error)
|
||||||
|
Sign(pk []byte, msg []byte) ([]byte, error)
|
||||||
|
Verify(sig []byte, a address.Address, msg []byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
var sigs map[string]SigShim
|
||||||
|
|
||||||
|
// RegisterSig should be only used during init
|
||||||
|
func RegisterSignature(name string, vs SigShim) {
|
||||||
|
if sigs == nil {
|
||||||
|
sigs = make(map[string]SigShim)
|
||||||
|
}
|
||||||
|
sigs[name] = vs
|
||||||
|
}
|
@ -37,6 +37,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
|
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
|
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
"github.com/filecoin-project/lotus/markets/storageadapter"
|
"github.com/filecoin-project/lotus/markets/storageadapter"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
"github.com/filecoin-project/lotus/miner"
|
||||||
"github.com/filecoin-project/lotus/node/config"
|
"github.com/filecoin-project/lotus/node/config"
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
"github.com/filecoin-project/lotus/node/impl/full"
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ func (pm *Manager) CheckVoucherValid(ctx context.Context, ch address.Address, sv
|
|||||||
// TODO: technically, either party may create and sign a voucher.
|
// TODO: technically, either party may create and sign a voucher.
|
||||||
// However, for now, we only accept them from the channel creator.
|
// However, for now, we only accept them from the channel creator.
|
||||||
// More complex handling logic can be added later
|
// More complex handling logic can be added later
|
||||||
if err := sv.Signature.Verify(pca.From, vb); err != nil {
|
if err := sigs.Verify(sv.Signature, pca.From, vb); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user