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 }