package bls import ( "fmt" "github.com/herumi/bls-eth-go-binary/bls" "github.com/meshplus/bitxhub-kit/crypto" "github.com/meshplus/bitxhub-kit/crypto/asym" "github.com/meshplus/bitxhub-kit/crypto/asym/ecdsa" "github.com/meshplus/bitxhub-kit/types" ) func init() { if err := bls.Init(bls.BLS12_381); err != nil { panic(err) } if err := bls.SetETHmode(bls.EthModeDraft07); err != nil { panic(err) } asym.RegisterCrypto1( BlsEth, "BlsEth", GenerateKeyPair, Verify, UnmarshalPrivateKey, ) } // Verify TODO fix bug func Verify(opt crypto.KeyType, sig, digest []byte, from types.Address) (bool, error) { if len(sig) == 0 { return false, fmt.Errorf("empty sig data") } if opt != BlsEth { return false, fmt.Errorf("not supported %d", opt) } return true, nil } func UnmarshalPrivateKey(data []byte, opt crypto.KeyType) (crypto.PrivateKey, error) { if len(data) == 0 { return nil, fmt.Errorf("empty private key data") } if opt != BlsEth { return nil, fmt.Errorf("not supported %d", opt) } pk := &PrivateKey{ curve: BlsEth, SecretKey: &bls.SecretKey{}, } err := pk.Deserialize(data) if err != nil { return nil, err } return pk, nil } type Sign = bls.Sign var HashAndMapToSignature = bls.HashAndMapToSignature const BlsEth crypto.KeyType = 9 func GenerateKeyPair(opt crypto.KeyType) (crypto.PrivateKey, error) { var sec bls.SecretKey sec.SetByCSPRNG() return &PrivateKey{ curve: BlsEth, SecretKey: &sec, }, nil } type PrivateKey struct { curve crypto.KeyType *bls.SecretKey } func (p *PrivateKey) Bytes() ([]byte, error) { return p.Serialize(), nil } func (p *PrivateKey) Type() crypto.KeyType { return p.curve } func (p *PrivateKey) Sign(digest []byte) ([]byte, error) { return []byte(p.SecretKey.SignHash(digest).SerializeToHexStr()), nil } func (p *PrivateKey) PublicKey() crypto.PublicKey { return &PublicKey{ curve: p.curve, PublicKey: p.GetPublicKey(), } } type PublicKey struct { curve crypto.KeyType *bls.PublicKey } func (p *PublicKey) Bytes() ([]byte, error) { return p.Serialize(), nil } func (p *PublicKey) Type() crypto.KeyType { return p.curve } func (p *PublicKey) Address() (*types.Address, error) { data := p.Serialize() ret := ecdsa.Keccak256(data[1:]) return types.NewAddress(ret[12:]), nil } func (p *PublicKey) Verify(digest []byte, sig []byte) (bool, error) { var sign bls.Sign err := sign.DeserializeHexStr(string(sig)) if err != nil { return false, err } return sign.VerifyHash(p.PublicKey, digest), nil } func IsSign(aggSign *bls.Sign, aggDataSign *bls.Sign, selfKey *bls.PublicKey) bool { return bls.VerifyPairing(aggSign, aggDataSign, selfKey) }