github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/environment/crypto_library.go (about)

     1  package environment
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/cadence/runtime"
     7  
     8  	"github.com/onflow/flow-go/fvm/crypto"
     9  	"github.com/onflow/flow-go/fvm/storage/state"
    10  	"github.com/onflow/flow-go/fvm/tracing"
    11  	"github.com/onflow/flow-go/module/trace"
    12  )
    13  
    14  type CryptoLibrary interface {
    15  	Hash(
    16  		data []byte,
    17  		tag string,
    18  		hashAlgorithm runtime.HashAlgorithm,
    19  	) (
    20  		[]byte,
    21  		error,
    22  	)
    23  
    24  	VerifySignature(
    25  		signature []byte,
    26  		tag string,
    27  		signedData []byte,
    28  		publicKey []byte,
    29  		signatureAlgorithm runtime.SignatureAlgorithm,
    30  		hashAlgorithm runtime.HashAlgorithm,
    31  	) (
    32  		bool,
    33  		error,
    34  	)
    35  
    36  	ValidatePublicKey(pk *runtime.PublicKey) error
    37  
    38  	BLSVerifyPOP(
    39  		pk *runtime.PublicKey,
    40  		sig []byte,
    41  	) (
    42  		bool,
    43  		error,
    44  	)
    45  
    46  	BLSAggregateSignatures(sigs [][]byte) ([]byte, error)
    47  
    48  	BLSAggregatePublicKeys(
    49  		keys []*runtime.PublicKey,
    50  	) (
    51  		*runtime.PublicKey,
    52  		error,
    53  	)
    54  }
    55  
    56  type ParseRestrictedCryptoLibrary struct {
    57  	txnState state.NestedTransactionPreparer
    58  	impl     CryptoLibrary
    59  }
    60  
    61  func NewParseRestrictedCryptoLibrary(
    62  	txnState state.NestedTransactionPreparer,
    63  	impl CryptoLibrary,
    64  ) CryptoLibrary {
    65  	return ParseRestrictedCryptoLibrary{
    66  		txnState: txnState,
    67  		impl:     impl,
    68  	}
    69  }
    70  
    71  func (lib ParseRestrictedCryptoLibrary) Hash(
    72  	data []byte,
    73  	tag string,
    74  	hashAlgorithm runtime.HashAlgorithm,
    75  ) (
    76  	[]byte,
    77  	error,
    78  ) {
    79  	return parseRestrict3Arg1Ret(
    80  		lib.txnState,
    81  		trace.FVMEnvHash,
    82  		lib.impl.Hash,
    83  		data,
    84  		tag,
    85  		hashAlgorithm)
    86  }
    87  
    88  func (lib ParseRestrictedCryptoLibrary) VerifySignature(
    89  	signature []byte,
    90  	tag string,
    91  	signedData []byte,
    92  	publicKey []byte,
    93  	signatureAlgorithm runtime.SignatureAlgorithm,
    94  	hashAlgorithm runtime.HashAlgorithm,
    95  ) (
    96  	bool,
    97  	error,
    98  ) {
    99  	return parseRestrict6Arg1Ret(
   100  		lib.txnState,
   101  		trace.FVMEnvVerifySignature,
   102  		lib.impl.VerifySignature,
   103  		signature,
   104  		tag,
   105  		signedData,
   106  		publicKey,
   107  		signatureAlgorithm,
   108  		hashAlgorithm)
   109  }
   110  
   111  func (lib ParseRestrictedCryptoLibrary) ValidatePublicKey(
   112  	pk *runtime.PublicKey,
   113  ) error {
   114  	return parseRestrict1Arg(
   115  		lib.txnState,
   116  		trace.FVMEnvValidatePublicKey,
   117  		lib.impl.ValidatePublicKey,
   118  		pk)
   119  }
   120  
   121  func (lib ParseRestrictedCryptoLibrary) BLSVerifyPOP(
   122  	pk *runtime.PublicKey,
   123  	sig []byte,
   124  ) (
   125  	bool,
   126  	error,
   127  ) {
   128  	return parseRestrict2Arg1Ret(
   129  		lib.txnState,
   130  		trace.FVMEnvBLSVerifyPOP,
   131  		lib.impl.BLSVerifyPOP,
   132  		pk,
   133  		sig)
   134  }
   135  
   136  func (lib ParseRestrictedCryptoLibrary) BLSAggregateSignatures(
   137  	sigs [][]byte,
   138  ) (
   139  	[]byte,
   140  	error,
   141  ) {
   142  	return parseRestrict1Arg1Ret(
   143  		lib.txnState,
   144  		trace.FVMEnvBLSAggregateSignatures,
   145  		lib.impl.BLSAggregateSignatures,
   146  		sigs)
   147  }
   148  
   149  func (lib ParseRestrictedCryptoLibrary) BLSAggregatePublicKeys(
   150  	keys []*runtime.PublicKey,
   151  ) (
   152  	*runtime.PublicKey,
   153  	error,
   154  ) {
   155  	return parseRestrict1Arg1Ret(
   156  		lib.txnState,
   157  		trace.FVMEnvBLSAggregatePublicKeys,
   158  		lib.impl.BLSAggregatePublicKeys,
   159  		keys)
   160  }
   161  
   162  type cryptoLibrary struct {
   163  	tracer tracing.TracerSpan
   164  	meter  Meter
   165  }
   166  
   167  func NewCryptoLibrary(tracer tracing.TracerSpan, meter Meter) CryptoLibrary {
   168  	return &cryptoLibrary{
   169  		tracer: tracer,
   170  		meter:  meter,
   171  	}
   172  }
   173  
   174  func (lib *cryptoLibrary) Hash(
   175  	data []byte,
   176  	tag string,
   177  	hashAlgorithm runtime.HashAlgorithm,
   178  ) (
   179  	[]byte,
   180  	error,
   181  ) {
   182  	defer lib.tracer.StartChildSpan(trace.FVMEnvHash).End()
   183  
   184  	err := lib.meter.MeterComputation(ComputationKindHash, 1)
   185  	if err != nil {
   186  		return nil, fmt.Errorf("hash failed: %w", err)
   187  	}
   188  
   189  	hashAlgo := crypto.RuntimeToCryptoHashingAlgorithm(hashAlgorithm)
   190  	return crypto.HashWithTag(hashAlgo, tag, data)
   191  }
   192  
   193  func (lib *cryptoLibrary) VerifySignature(
   194  	signature []byte,
   195  	tag string,
   196  	signedData []byte,
   197  	publicKey []byte,
   198  	signatureAlgorithm runtime.SignatureAlgorithm,
   199  	hashAlgorithm runtime.HashAlgorithm,
   200  ) (
   201  	bool,
   202  	error,
   203  ) {
   204  	defer lib.tracer.StartChildSpan(trace.FVMEnvVerifySignature).End()
   205  
   206  	err := lib.meter.MeterComputation(ComputationKindVerifySignature, 1)
   207  	if err != nil {
   208  		return false, fmt.Errorf("verify signature failed: %w", err)
   209  	}
   210  
   211  	valid, err := crypto.VerifySignatureFromRuntime(
   212  		signature,
   213  		tag,
   214  		signedData,
   215  		publicKey,
   216  		signatureAlgorithm,
   217  		hashAlgorithm,
   218  	)
   219  
   220  	if err != nil {
   221  		return false, fmt.Errorf("verify signature failed: %w", err)
   222  	}
   223  
   224  	return valid, nil
   225  }
   226  
   227  func (lib *cryptoLibrary) ValidatePublicKey(pk *runtime.PublicKey) error {
   228  	defer lib.tracer.StartChildSpan(trace.FVMEnvValidatePublicKey).End()
   229  
   230  	err := lib.meter.MeterComputation(ComputationKindValidatePublicKey, 1)
   231  	if err != nil {
   232  		return fmt.Errorf("validate public key failed: %w", err)
   233  	}
   234  
   235  	return crypto.ValidatePublicKey(pk.SignAlgo, pk.PublicKey)
   236  }
   237  
   238  func (lib *cryptoLibrary) BLSVerifyPOP(
   239  	pk *runtime.PublicKey,
   240  	sig []byte,
   241  ) (
   242  	bool,
   243  	error,
   244  ) {
   245  	defer lib.tracer.StartChildSpan(trace.FVMEnvBLSVerifyPOP).End()
   246  
   247  	err := lib.meter.MeterComputation(ComputationKindBLSVerifyPOP, 1)
   248  	if err != nil {
   249  		return false, fmt.Errorf("BLSVerifyPOP failed: %w", err)
   250  	}
   251  
   252  	return crypto.VerifyPOP(pk, sig)
   253  }
   254  
   255  func (lib *cryptoLibrary) BLSAggregateSignatures(
   256  	sigs [][]byte,
   257  ) (
   258  	[]byte,
   259  	error,
   260  ) {
   261  	defer lib.tracer.StartChildSpan(trace.FVMEnvBLSAggregateSignatures).End()
   262  
   263  	err := lib.meter.MeterComputation(ComputationKindBLSAggregateSignatures, 1)
   264  	if err != nil {
   265  		return nil, fmt.Errorf("BLSAggregateSignatures failed: %w", err)
   266  	}
   267  
   268  	return crypto.AggregateSignatures(sigs)
   269  }
   270  
   271  func (lib *cryptoLibrary) BLSAggregatePublicKeys(
   272  	keys []*runtime.PublicKey,
   273  ) (
   274  	*runtime.PublicKey,
   275  	error,
   276  ) {
   277  	defer lib.tracer.StartChildSpan(trace.FVMEnvBLSAggregatePublicKeys).End()
   278  
   279  	err := lib.meter.MeterComputation(ComputationKindBLSAggregatePublicKeys, 1)
   280  	if err != nil {
   281  		return nil, fmt.Errorf("BLSAggregatePublicKeys failed: %w", err)
   282  	}
   283  
   284  	return crypto.AggregatePublicKeys(keys)
   285  }