github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/bbs/bbs_signer_key_manager.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package bbs 8 9 import ( 10 "crypto/rand" 11 "errors" 12 "fmt" 13 14 "github.com/google/tink/go/keyset" 15 commonpb "github.com/google/tink/go/proto/common_go_proto" 16 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 17 "github.com/google/tink/go/subtle" 18 "github.com/trustbloc/bbs-signature-go/bbs12381g2pub" 19 "google.golang.org/protobuf/proto" 20 21 bbssubtle "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/bbs/subtle" 22 bbspb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/bbs_go_proto" 23 ) 24 25 const ( 26 bbsSignerKeyVersion = 0 27 bbsSignerKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.BBSPrivateKey" 28 ) 29 30 // common errors. 31 var ( 32 errInvalidBBSSignerKey = errors.New("bbs_signer_key_manager: invalid key") 33 errInvalidBBSSignerKeyFormat = errors.New("bbs_signer_key_manager: invalid key format") 34 ) 35 36 // bbsSignerKeyManager is an implementation of KeyManager interface for BBS signatures/proofs. 37 // It generates new BBSPrivateKeys and produces new instances of BBSSign subtle. 38 type bbsSignerKeyManager struct{} 39 40 // newBBSSignerKeyManager creates a new bbsSignerKeyManager. 41 func newBBSSignerKeyManager() *bbsSignerKeyManager { 42 return new(bbsSignerKeyManager) 43 } 44 45 // Primitive creates an BBS Signer subtle for the given serialized BBSPrivateKey proto. 46 func (km *bbsSignerKeyManager) Primitive(serializedKey []byte) (interface{}, error) { 47 if len(serializedKey) == 0 { 48 return nil, errInvalidBBSSignerKey 49 } 50 51 key := new(bbspb.BBSPrivateKey) 52 53 err := proto.Unmarshal(serializedKey, key) 54 if err != nil { 55 return nil, fmt.Errorf(errInvalidBBSSignerKey.Error()+": invalid proto: %w", err) 56 } 57 58 err = km.validateKey(key) 59 if err != nil { 60 return nil, fmt.Errorf(errInvalidBBSSignerKey.Error()+": %w", err) 61 } 62 63 return bbssubtle.NewBLS12381G2Signer(key.KeyValue), nil 64 } 65 66 // NewKey creates a new key according to the specification of BBSPrivateKey format. 67 func (km *bbsSignerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { 68 if len(serializedKeyFormat) == 0 { 69 return nil, errInvalidBBSSignerKeyFormat 70 } 71 72 keyFormat := new(bbspb.BBSKeyFormat) 73 74 err := proto.Unmarshal(serializedKeyFormat, keyFormat) 75 if err != nil { 76 return nil, fmt.Errorf(errInvalidBBSSignerKeyFormat.Error()+": invalid proto: %w", err) 77 } 78 79 err = validateKeyFormat(keyFormat) 80 if err != nil { 81 return nil, fmt.Errorf(errInvalidBBSSignerKeyFormat.Error()+": %w", err) 82 } 83 84 var ( 85 pubKey *bbs12381g2pub.PublicKey 86 privKey *bbs12381g2pub.PrivateKey 87 ) 88 89 // Since bbs+ in aries-framework-go only supports BLS12-381 curve on G2, we create keys of this curve and 90 // group only. BBS+ keys with other curves/group field can be added later if needed. 91 if keyFormat.Params.Group == bbspb.GroupField_G2 && keyFormat.Params.Curve == bbspb.BBSCurveType_BLS12_381 { 92 seed := make([]byte, 32) 93 94 _, err = rand.Read(seed) 95 if err != nil { 96 return nil, err 97 } 98 99 hFunc := subtle.GetHashFunc(keyFormat.Params.HashType.String()) 100 101 pubKey, privKey, err = bbs12381g2pub.GenerateKeyPair(hFunc, seed) 102 if err != nil { 103 return nil, err 104 } 105 } else { 106 return nil, errInvalidBBSSignerKeyFormat 107 } 108 109 pubKeyBytes, err := pubKey.Marshal() 110 if err != nil { 111 return nil, err 112 } 113 114 privKeyBytes, err := privKey.Marshal() 115 if err != nil { 116 return nil, err 117 } 118 119 return &bbspb.BBSPrivateKey{ 120 Version: bbsSignerKeyVersion, 121 KeyValue: privKeyBytes, 122 PublicKey: &bbspb.BBSPublicKey{ 123 Version: bbsSignerKeyVersion, 124 Params: keyFormat.Params, 125 KeyValue: pubKeyBytes, 126 }, 127 }, nil 128 } 129 130 // NewKeyData creates a new KeyData according to the specification of ECDHESPrivateKey Format. 131 // It should be used solely by the key management API. 132 func (km *bbsSignerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { 133 key, err := km.NewKey(serializedKeyFormat) 134 if err != nil { 135 return nil, err 136 } 137 138 serializedKey, err := proto.Marshal(key) 139 if err != nil { 140 return nil, fmt.Errorf("bbs_signer_key_manager: Proto.Marshal failed: %w", err) 141 } 142 143 return &tinkpb.KeyData{ 144 TypeUrl: bbsSignerKeyTypeURL, 145 Value: serializedKey, 146 KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE, 147 }, nil 148 } 149 150 // PublicKeyData returns the enclosed public key data of serializedPrivKey. 151 func (km *bbsSignerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) { 152 privKey := new(bbspb.BBSPrivateKey) 153 154 err := proto.Unmarshal(serializedPrivKey, privKey) 155 if err != nil { 156 return nil, errInvalidBBSSignerKey 157 } 158 159 serializedPubKey, err := proto.Marshal(privKey.PublicKey) 160 if err != nil { 161 return nil, errInvalidBBSSignerKey 162 } 163 164 return &tinkpb.KeyData{ 165 TypeUrl: bbsVerifierKeyTypeURL, 166 Value: serializedPubKey, 167 KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC, 168 }, nil 169 } 170 171 // DoesSupport indicates if this key manager supports the given key type. 172 func (km *bbsSignerKeyManager) DoesSupport(typeURL string) bool { 173 return typeURL == bbsSignerKeyTypeURL 174 } 175 176 // TypeURL returns the key type of keys managed by this key manager. 177 func (km *bbsSignerKeyManager) TypeURL() string { 178 return bbsSignerKeyTypeURL 179 } 180 181 // validateKey validates the given ECDHPrivateKey and returns the KW curve. 182 func (km *bbsSignerKeyManager) validateKey(key *bbspb.BBSPrivateKey) error { 183 err := keyset.ValidateKeyVersion(key.Version, bbsSignerKeyVersion) 184 if err != nil { 185 return fmt.Errorf("bbs_signer_key_manager: invalid key: %w", err) 186 } 187 188 return validateKeyParams(key.PublicKey.Params) 189 } 190 191 // validateKeyFormat validates the given BBS curve and Group field. 192 func validateKeyFormat(format *bbspb.BBSKeyFormat) error { 193 return validateKeyParams(format.Params) 194 } 195 196 func validateKeyParams(params *bbspb.BBSParams) error { 197 switch params.Curve { 198 case bbspb.BBSCurveType_BLS12_381: 199 default: 200 return fmt.Errorf("bad curve '%s'", params.Curve) 201 } 202 203 switch params.Group { 204 case bbspb.GroupField_G1, bbspb.GroupField_G2: 205 default: 206 return fmt.Errorf("bad group field '%s'", params.Group) 207 } 208 209 switch params.HashType { 210 case commonpb.HashType_SHA256, commonpb.HashType_SHA384, commonpb.HashType_SHA512: 211 default: 212 return fmt.Errorf("unsupported hash type '%s'", params.HashType) 213 } 214 215 return nil 216 }