Integrate blst signature library: https://github.com/supranational/blst
This commit is contained in:
parent
c459a13dca
commit
0f3105a01f
@ -3,7 +3,6 @@ package gen
|
||||
import (
|
||||
"context"
|
||||
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
@ -17,6 +16,7 @@ import (
|
||||
"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/lib/sigs/bls"
|
||||
)
|
||||
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
@ -142,28 +142,27 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
||||
}
|
||||
|
||||
func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) {
|
||||
var blsSigs []bls.Signature
|
||||
for _, s := range sigs {
|
||||
var bsig bls.Signature
|
||||
copy(bsig[:], s.Data)
|
||||
blsSigs = append(blsSigs, bsig)
|
||||
sigsS := make([][]byte, len(sigs))
|
||||
for i := 0; i < len(sigs); i++ {
|
||||
sigsS[i] = sigs[i].Data
|
||||
}
|
||||
|
||||
aggSig := bls.Aggregate(blsSigs)
|
||||
if aggSig == nil {
|
||||
aggregator := new(bls.AggregateSignature).AggregateCompressed(sigsS)
|
||||
if aggregator == nil {
|
||||
if len(sigs) > 0 {
|
||||
return nil, xerrors.Errorf("bls.Aggregate returned nil with %d signatures", len(sigs))
|
||||
}
|
||||
|
||||
// Note: for blst this condition should not happen - nil should not be returned
|
||||
return &crypto.Signature{
|
||||
Type: crypto.SigTypeBLS,
|
||||
Data: new(bls.Signature)[:],
|
||||
Data: new(bls.Signature).Compress(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
aggSig := aggregator.ToAffine().Compress()
|
||||
return &crypto.Signature{
|
||||
Type: crypto.SigTypeBLS,
|
||||
Data: aggSig[:],
|
||||
Data: aggSig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
@ -433,7 +432,7 @@ func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Ad
|
||||
return vm.ResolveToKeyAddr(tree, cst, addr)
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetBlsPublicKey(ctx context.Context, addr address.Address, ts *types.TipSet) (pubk bls.PublicKey, err error) {
|
||||
func (sm *StateManager) GetBlsPublicKey(ctx context.Context, addr address.Address, ts *types.TipSet) (pubk []byte, err error) {
|
||||
kaddr, err := sm.ResolveToKeyAddress(ctx, addr, ts)
|
||||
if err != nil {
|
||||
return pubk, xerrors.Errorf("failed to resolve address to key address: %w", err)
|
||||
@ -443,8 +442,7 @@ func (sm *StateManager) GetBlsPublicKey(ctx context.Context, addr address.Addres
|
||||
return pubk, xerrors.Errorf("address must be BLS address to load bls public key")
|
||||
}
|
||||
|
||||
copy(pubk[:], kaddr.Payload())
|
||||
return pubk, nil
|
||||
return kaddr.Payload(), nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) LookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
blst "github.com/supranational/blst/bindings/go"
|
||||
"github.com/filecoin-project/go-address"
|
||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||
@ -46,6 +46,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
)
|
||||
|
||||
@ -915,7 +916,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block
|
||||
func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error {
|
||||
{
|
||||
var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type
|
||||
var pubks []bls.PublicKey
|
||||
var pubks [][]byte
|
||||
|
||||
for _, m := range b.BlsMessages {
|
||||
sigCids = append(sigCids, m.Cid())
|
||||
@ -1036,24 +1037,28 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
||||
return nil
|
||||
}
|
||||
|
||||
func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig *crypto.Signature, msgs []cid.Cid, pubks []bls.PublicKey) error {
|
||||
func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig *crypto.Signature, msgs []cid.Cid, pubks [][]byte) error {
|
||||
_, span := trace.StartSpan(ctx, "syncer.verifyBlsAggregate")
|
||||
defer span.End()
|
||||
span.AddAttributes(
|
||||
trace.Int64Attribute("msgCount", int64(len(msgs))),
|
||||
)
|
||||
|
||||
bmsgs := make([]bls.Message, len(msgs))
|
||||
for i, m := range msgs {
|
||||
bmsgs[i] = m.Bytes()
|
||||
msgsS := make([]blst.Message, len(msgs))
|
||||
for i := 0; i < len(msgs); i++ {
|
||||
msgsS[i] = msgs[i].Bytes()
|
||||
}
|
||||
|
||||
var bsig bls.Signature
|
||||
copy(bsig[:], sig.Data)
|
||||
if !bls.HashVerify(&bsig, bmsgs, pubks) {
|
||||
// TODO: empty aggregates are considered valid?
|
||||
if len(msgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
valid := new(bls.Signature).AggregateVerifyCompressed(sig.Data, pubks,
|
||||
msgsS, []byte(bls.DST))
|
||||
if !valid {
|
||||
return xerrors.New("bls aggregate signature failed to verify")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
1
go.mod
1
go.mod
@ -106,6 +106,7 @@ require (
|
||||
github.com/opentracing/opentracing-go v1.1.0
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/supranational/blst v0.1.1
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
|
||||
|
4
go.sum
4
go.sum
@ -1316,6 +1316,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/supranational/blst v0.1.0 h1:2LzeBbOidhTD87UezqGvIffWZAd3FOCfhi2b7IbJCMc=
|
||||
github.com/supranational/blst v0.1.0/go.mod h1:Z70pOaiBHpXP+JFNOwIyCHKjec/He56CC5UdLaYpuzY=
|
||||
github.com/supranational/blst v0.1.1 h1:GsK4oq7QZ7yfHI6dCh2NQsUe4imjlFwm5NXF5PWAWoo=
|
||||
github.com/supranational/blst v0.1.1/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
|
@ -1,51 +1,57 @@
|
||||
package bls
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
blst "github.com/supranational/blst/bindings/go"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
)
|
||||
|
||||
const DST = string("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_")
|
||||
|
||||
type SecretKey = blst.SecretKey
|
||||
type PublicKey = blst.P1Affine
|
||||
type Signature = blst.P2Affine
|
||||
type AggregateSignature = blst.P2Aggregate
|
||||
|
||||
type blsSigner struct{}
|
||||
|
||||
func (blsSigner) GenPrivate() ([]byte, error) {
|
||||
pk := ffi.PrivateKeyGenerate()
|
||||
return pk[:], nil
|
||||
// Generate 32 bytes of randomness
|
||||
var ikm [32]byte
|
||||
_, err := rand.Read(ikm[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bls signature error generating random data")
|
||||
}
|
||||
pk := blst.KeyGen(ikm[:]).Serialize()
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
func (blsSigner) ToPublic(priv []byte) ([]byte, error) {
|
||||
var pk ffi.PrivateKey
|
||||
copy(pk[:], priv)
|
||||
pub := ffi.PrivateKeyPublicKey(pk)
|
||||
return pub[:], nil
|
||||
pk := new(SecretKey).Deserialize(priv)
|
||||
if pk == nil {
|
||||
return nil, fmt.Errorf("bls signature invalid private key")
|
||||
}
|
||||
return new(PublicKey).From(pk).Compress(), 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
|
||||
pk := new(SecretKey).Deserialize(p)
|
||||
if pk == nil {
|
||||
return nil, fmt.Errorf("bls signature invalid private key")
|
||||
}
|
||||
return new(Signature).Sign(pk, msg, []byte(DST)).Compress(), nil
|
||||
}
|
||||
|
||||
func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error {
|
||||
|
||||
var pubk ffi.PublicKey
|
||||
copy(pubk[:], a.Payload())
|
||||
pubkeys := []ffi.PublicKey{pubk}
|
||||
digests := []ffi.Message{msg}
|
||||
|
||||
var s ffi.Signature
|
||||
copy(s[:], sig)
|
||||
|
||||
if !ffi.HashVerify(&s, digests, pubkeys) {
|
||||
if !new(Signature).VerifyCompressed(sig, a.Payload()[:], msg, []byte(DST)) {
|
||||
return fmt.Errorf("bls signature failed to verify")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user