Skip to content

Commit

Permalink
Merge pull request #5393 from filecoin-project/feat-refactor-bls
Browse files Browse the repository at this point in the history
refactor: switch to filecoin-ffi bls api for bls signatures
  • Loading branch information
magik6k committed Jan 25, 2021
2 parents 519b5e1 + e4f4fa2 commit 2609080
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 42 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,3 @@
[submodule "extern/test-vectors"]
path = extern/test-vectors
url = https://github.com/filecoin-project/test-vectors.git
[submodule "extern/blst"]
path = extern/blst
url = https://github.com/supranational/blst.git
24 changes: 9 additions & 15 deletions chain/gen/mining.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"

ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sigs/bls"
)

func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletAPI, bt *api.BlockTemplate) (*types.FullBlock, error) {
Expand Down Expand Up @@ -140,35 +140,29 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA
}

func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) {
sigsS := make([][]byte, len(sigs))
sigsS := make([]ffi.Signature, len(sigs))
for i := 0; i < len(sigs); i++ {
sigsS[i] = sigs[i].Data
copy(sigsS[i][:], sigs[i].Data[:ffi.SignatureBytes])
}

aggregator := new(bls.AggregateSignature).AggregateCompressed(sigsS)
if aggregator == nil {
aggSig := ffi.Aggregate(sigsS)
if aggSig == nil {
if len(sigs) > 0 {
return nil, xerrors.Errorf("bls.Aggregate returned nil with %d signatures", len(sigs))
}

zeroSig := ffi.CreateZeroSignature()

// Note: for blst this condition should not happen - nil should not
// be returned
return &crypto.Signature{
Type: crypto.SigTypeBLS,
Data: new(bls.Signature).Compress(),
}, nil
}
aggSigAff := aggregator.ToAffine()
if aggSigAff == nil {
return &crypto.Signature{
Type: crypto.SigTypeBLS,
Data: new(bls.Signature).Compress(),
Data: zeroSig[:],
}, nil
}
aggSig := aggSigAff.Compress()
return &crypto.Signature{
Type: crypto.SigTypeBLS,
Data: aggSig,
Data: aggSig[:],
}, nil
}

Expand Down
14 changes: 9 additions & 5 deletions chain/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import (
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
blst "github.com/supranational/blst/bindings/go"

ffi "github.com/filecoin-project/filecoin-ffi"

// named msgarray here to make it clear that these are the types used by
// messages, regardless of specs-actors version.
Expand All @@ -55,7 +56,6 @@ import (
"github.com/filecoin-project/lotus/chain/vm"
bstore "github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/lotus/lib/sigs"
"github.com/filecoin-project/lotus/lib/sigs/bls"
"github.com/filecoin-project/lotus/metrics"
)

Expand Down Expand Up @@ -1182,17 +1182,21 @@ func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig *crypto.Signat
trace.Int64Attribute("msgCount", int64(len(msgs))),
)

msgsS := make([]blst.Message, len(msgs))
msgsS := make([]ffi.Message, len(msgs))
pubksS := make([]ffi.PublicKey, len(msgs))
for i := 0; i < len(msgs); i++ {
msgsS[i] = msgs[i].Bytes()
copy(pubksS[i][:], pubks[i][:ffi.PublicKeyBytes])
}

sigS := new(ffi.Signature)
copy(sigS[:], sig.Data[:ffi.SignatureBytes])

if len(msgs) == 0 {
return nil
}

valid := new(bls.Signature).AggregateVerifyCompressed(sig.Data, pubks,
msgsS, []byte(bls.DST))
valid := ffi.HashVerify(sigS, msgsS, pubksS)
if !valid {
return xerrors.New("bls aggregate signature failed to verify")
}
Expand Down
1 change: 0 additions & 1 deletion extern/blst
Submodule blst deleted from 1cbb16
2 changes: 1 addition & 1 deletion extern/filecoin-ffi
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ require (
github.com/raulk/clock v1.1.0
github.com/raulk/go-watchdog v1.0.1
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
Expand Down Expand Up @@ -157,5 +156,3 @@ replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v
replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi

replace github.com/filecoin-project/test-vectors => ./extern/test-vectors

replace github.com/supranational/blst => ./extern/blst
53 changes: 39 additions & 14 deletions lib/sigs/bls/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"

blst "github.com/supranational/blst/bindings/go"
ffi "github.com/filecoin-project/filecoin-ffi"

"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 SecretKey = ffi.PrivateKey
type PublicKey = ffi.PublicKey
type Signature = ffi.Signature
type AggregateSignature = ffi.Signature

type blsSigner struct{}

Expand All @@ -29,30 +29,55 @@ func (blsSigner) GenPrivate() ([]byte, error) {
return nil, fmt.Errorf("bls signature error generating random data")
}
// Note private keys seem to be serialized little-endian!
pk := blst.KeyGen(ikm[:]).ToLEndian()
return pk, nil
sk := ffi.PrivateKeyGenerateWithSeed(ikm)
return sk[:], nil
}

func (blsSigner) ToPublic(priv []byte) ([]byte, error) {
pk := new(SecretKey).FromLEndian(priv)
if pk == nil || !pk.Valid() {
if priv == nil || len(priv) != ffi.PrivateKeyBytes {
return nil, fmt.Errorf("bls signature invalid private key")
}
return new(PublicKey).From(pk).Compress(), nil

sk := new(SecretKey)
copy(sk[:], priv[:ffi.PrivateKeyBytes])

pubkey := ffi.PrivateKeyPublicKey(*sk)

return pubkey[:], nil
}

func (blsSigner) Sign(p []byte, msg []byte) ([]byte, error) {
pk := new(SecretKey).FromLEndian(p)
if pk == nil || !pk.Valid() {
if p == nil || len(p) != ffi.PrivateKeyBytes {
return nil, fmt.Errorf("bls signature invalid private key")
}
return new(Signature).Sign(pk, msg, []byte(DST)).Compress(), nil

sk := new(SecretKey)
copy(sk[:], p[:ffi.PrivateKeyBytes])

sig := ffi.PrivateKeySign(*sk, msg)

return sig[:], nil
}

func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error {
if !new(Signature).VerifyCompressed(sig, a.Payload()[:], msg, []byte(DST)) {
payload := a.Payload()
if sig == nil || len(sig) != ffi.SignatureBytes || len(payload) != ffi.PublicKeyBytes {
return fmt.Errorf("bls signature failed to verify")
}

pk := new(PublicKey)
copy(pk[:], payload[:ffi.PublicKeyBytes])

sigS := new(Signature)
copy(sigS[:], sig[:ffi.SignatureBytes])

msgs := [1]ffi.Message{msg}
pks := [1]PublicKey{*pk}

if !ffi.HashVerify(sigS, msgs[:], pks[:]) {
return fmt.Errorf("bls signature failed to verify")
}

return nil
}

Expand Down

0 comments on commit 2609080

Please sign in to comment.