diff --git a/.gitmodules b/.gitmodules index 127386beb24..cdee35ce393 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/chain/gen/mining.go b/chain/gen/mining.go index cca4b61699a..5de0fec0ed0 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -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) { @@ -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 } diff --git a/chain/sync.go b/chain/sync.go index 906841f5210..9c1b2480644 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -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. @@ -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" ) @@ -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") } diff --git a/extern/blst b/extern/blst deleted file mode 160000 index 1cbb16ed958..00000000000 --- a/extern/blst +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1cbb16ed9580dcd3e9593b71221fcf2a048faaef diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 1d9cb3e8ff5..0c50dfbaa64 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 1d9cb3e8ff53f51f9318fc57e5d00bc79bdc0128 +Subproject commit 0c50dfbaa64c6187d65e63e19aea751a981ac931 diff --git a/go.mod b/go.mod index 0810d7e7e08..2a276eddb8d 100644 --- a/go.mod +++ b/go.mod @@ -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 @@ -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 diff --git a/lib/sigs/bls/init.go b/lib/sigs/bls/init.go index 42633eee88a..9bc69c3a460 100644 --- a/lib/sigs/bls/init.go +++ b/lib/sigs/bls/init.go @@ -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{} @@ -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 }