package key import ( "golang.org/x/crypto/sha3" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" ) func GenerateKey(typ types.KeyType) (*Key, error) { ctyp := ActSigType(typ) if ctyp == crypto.SigTypeUnknown { return nil, xerrors.Errorf("unknown sig type: %s", typ) } pk, err := sigs.Generate(ctyp) if err != nil { return nil, err } ki := types.KeyInfo{ Type: typ, PrivateKey: pk, } return NewKey(ki) } type Key struct { types.KeyInfo PublicKey []byte Address address.Address } func NewKey(keyinfo types.KeyInfo) (*Key, error) { k := &Key{ KeyInfo: keyinfo, } var err error k.PublicKey, err = sigs.ToPublic(ActSigType(k.Type), k.PrivateKey) if err != nil { return nil, err } switch k.Type { case types.KTSecp256k1: k.Address, err = address.NewSecp256k1Address(k.PublicKey) if err != nil { return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err) } case types.KTDelegated: // Assume eth for now hasher := sha3.NewLegacyKeccak256() pubk := k.PublicKey // if we get an uncompressed public key (that's what we get from the library, // but putting this check here for defensiveness), strip the prefix if pubk[0] == 0x04 { pubk = pubk[1:] } hasher.Write(pubk) k.Address, err = address.NewDelegatedAddress(builtin.EthereumAddressManagerActorID, hasher.Sum(nil)[12:]) if err != nil { return nil, xerrors.Errorf("converting Delegated to address: %w", err) } case types.KTBLS: k.Address, err = address.NewBLSAddress(k.PublicKey) if err != nil { return nil, xerrors.Errorf("converting BLS to address: %w", err) } default: return nil, xerrors.Errorf("unsupported key type: %s", k.Type) } return k, nil } func ActSigType(typ types.KeyType) crypto.SigType { switch typ { case types.KTBLS: return crypto.SigTypeBLS case types.KTSecp256k1: return crypto.SigTypeSecp256k1 case types.KTDelegated: return crypto.SigTypeDelegated default: return crypto.SigTypeUnknown } }