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  }