github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/bbs/bbs_signer_factory.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 "fmt" 11 12 "github.com/google/tink/go/core/cryptofmt" 13 "github.com/google/tink/go/core/primitiveset" 14 "github.com/google/tink/go/core/registry" 15 "github.com/google/tink/go/keyset" 16 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 17 18 bbsapi "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/bbs/api" 19 ) 20 21 // NewSigner returns a BBS Signer primitive from the given keyset handle. 22 func NewSigner(h *keyset.Handle) (bbsapi.Signer, error) { 23 return NewSignerWithKeyManager(h, nil) 24 } 25 26 // NewSignerWithKeyManager returns a BBS Signer primitive from the given keyset handle and custom key manager. 27 func NewSignerWithKeyManager(h *keyset.Handle, km registry.KeyManager) (bbsapi.Signer, error) { 28 ps, err := h.PrimitivesWithKeyManager(km) 29 if err != nil { 30 return nil, fmt.Errorf("bbs_sign_factory: cannot obtain primitive set: %w", err) 31 } 32 33 return newWrappedSigner(ps) 34 } 35 36 // wrappedSigner is a BBS Signer implementation that uses the underlying primitive set for bbs signing. 37 type wrappedSigner struct { 38 ps *primitiveset.PrimitiveSet 39 } 40 41 // newWrappedSigner constructor creates a new wrappedSigner and checks primitives in ps are all of BBS Signer type. 42 func newWrappedSigner(ps *primitiveset.PrimitiveSet) (*wrappedSigner, error) { 43 if _, ok := (ps.Primary.Primitive).(bbsapi.Signer); !ok { 44 return nil, fmt.Errorf("bbs_signer_factory: not a BBS Signer primitive") 45 } 46 47 for _, primitives := range ps.Entries { 48 for _, p := range primitives { 49 if _, ok := (p.Primitive).(bbsapi.Signer); !ok { 50 return nil, fmt.Errorf("bbs_signer_factory: not a BBS Signer primitive") 51 } 52 } 53 } 54 55 ret := new(wrappedSigner) 56 ret.ps = ps 57 58 return ret, nil 59 } 60 61 // Sign signs the given messages and returns the signature concatenated with the identifier of the primary primitive. 62 func (ws *wrappedSigner) Sign(messages [][]byte) ([]byte, error) { 63 primary := ws.ps.Primary 64 65 signer, ok := (primary.Primitive).(bbsapi.Signer) 66 if !ok { 67 return nil, fmt.Errorf("bbs_signer_factory: not a BBS Signer primitive") 68 } 69 70 var dataToSign [][]byte 71 if primary.PrefixType == tinkpb.OutputPrefixType_LEGACY { 72 dataToSign = append(dataToSign, messages...) 73 dataToSign = append(dataToSign, []byte{cryptofmt.LegacyStartByte}) 74 } else { 75 dataToSign = append(dataToSign, messages...) 76 } 77 78 signature, err := signer.Sign(dataToSign) 79 if err != nil { 80 return nil, err 81 } 82 83 ret := make([]byte, 0, len(primary.Prefix)+len(signature)) 84 ret = append(ret, primary.Prefix...) 85 ret = append(ret, signature...) 86 87 return ret, nil 88 }