|
1 | 1 | //! Import implementations
|
2 | 2 |
|
| 3 | +use std::cmp::max; |
3 | 4 | use std::convert::TryInto;
|
4 | 5 |
|
5 | 6 | use cosmwasm_crypto::{
|
@@ -27,10 +28,17 @@ use crate::sections::encode_sections;
|
27 | 28 | use crate::serde::to_vec;
|
28 | 29 | use crate::GasInfo;
|
29 | 30 |
|
30 |
| -const GAS_COST_SECP256K1_VERIFY_SIGNATURE: u64 = 100; |
31 |
| -const GAS_COST_SECP256K1_RECOVER_PUBKEY_SIGNATURE: u64 = 100; |
32 |
| -const GAS_COST_VERIFY_ED25519_SIGNATURE: u64 = 100; |
33 |
| -const GAS_COST_BATCH_VERIFY_ED25519_SIGNATURE: u64 = GAS_COST_VERIFY_ED25519_SIGNATURE / 3; |
| 31 | +// 1000 Cosmos SDK * 100 CosmWasm factor (~154 us in crypto benchmarks) |
| 32 | +const GAS_COST_SECP256K1_VERIFY: u64 = 100000; |
| 33 | + |
| 34 | +// Gas costs relative to secp256k1_verify cost |
| 35 | +const GAS_COST_SECP256K1_RECOVER_PUBKEY: u64 = 105195; // 100_000 * 162 us / 154 us |
| 36 | +const GAS_COST_ED25519_VERIFY: u64 = 40909; // 100_000 * 63 us / 154 us |
| 37 | + |
| 38 | +// Gas costs relative to ed25519_verify cost |
| 39 | +// From https://docs.rs/ed25519-zebra/2.2.0/ed25519_zebra/batch/index.html |
| 40 | +const GAS_COST_ED25519_BATCH_VERIFY: u64 = GAS_COST_ED25519_VERIFY / 2; |
| 41 | +const GAS_COST_ED25519_BATCH_VERIFY_ONE_PUBKEY: u64 = GAS_COST_ED25519_VERIFY / 4; |
34 | 42 |
|
35 | 43 | /// A kibi (kilo binary)
|
36 | 44 | const KI: usize = 1024;
|
@@ -296,7 +304,7 @@ fn do_secp256k1_verify<A: BackendApi, S: Storage, Q: Querier>(
|
296 | 304 | let pubkey = read_region(&env.memory(), pubkey_ptr, ECDSA_PUBKEY_MAX_LEN)?;
|
297 | 305 |
|
298 | 306 | let result = secp256k1_verify(&hash, &signature, &pubkey);
|
299 |
| - let gas_info = GasInfo::with_cost(GAS_COST_SECP256K1_VERIFY_SIGNATURE); |
| 307 | + let gas_info = GasInfo::with_cost(GAS_COST_SECP256K1_VERIFY); |
300 | 308 | process_gas_info::<A, S, Q>(env, gas_info)?;
|
301 | 309 | Ok(result.map_or_else(
|
302 | 310 | |err| match err {
|
@@ -327,7 +335,7 @@ fn do_secp256k1_recover_pubkey<A: BackendApi, S: Storage, Q: Querier>(
|
327 | 335 | };
|
328 | 336 |
|
329 | 337 | let result = secp256k1_recover_pubkey(&hash, &signature, recover_param);
|
330 |
| - let gas_info = GasInfo::with_cost(GAS_COST_SECP256K1_RECOVER_PUBKEY_SIGNATURE); |
| 338 | + let gas_info = GasInfo::with_cost(GAS_COST_SECP256K1_RECOVER_PUBKEY); |
331 | 339 | process_gas_info::<A, S, Q>(env, gas_info)?;
|
332 | 340 | match result {
|
333 | 341 | Ok(pubkey) => {
|
@@ -358,7 +366,7 @@ fn do_ed25519_verify<A: BackendApi, S: Storage, Q: Querier>(
|
358 | 366 | let pubkey = read_region(&env.memory(), pubkey_ptr, EDDSA_PUBKEY_LEN)?;
|
359 | 367 |
|
360 | 368 | let result = ed25519_verify(&message, &signature, &pubkey);
|
361 |
| - let gas_info = GasInfo::with_cost(GAS_COST_VERIFY_ED25519_SIGNATURE); |
| 369 | + let gas_info = GasInfo::with_cost(GAS_COST_ED25519_VERIFY); |
362 | 370 | process_gas_info::<A, S, Q>(env, gas_info)?;
|
363 | 371 | Ok(result.map_or_else(
|
364 | 372 | |err| match err {
|
@@ -402,8 +410,12 @@ fn do_ed25519_batch_verify<A: BackendApi, S: Storage, Q: Querier>(
|
402 | 410 | let public_keys = decode_sections(&public_keys);
|
403 | 411 |
|
404 | 412 | let result = ed25519_batch_verify(&messages, &signatures, &public_keys);
|
405 |
| - let gas_info = |
406 |
| - GasInfo::with_cost(GAS_COST_BATCH_VERIFY_ED25519_SIGNATURE * signatures.len() as u64); |
| 413 | + let gas_cost = if public_keys.len() == 1 { |
| 414 | + GAS_COST_ED25519_BATCH_VERIFY_ONE_PUBKEY |
| 415 | + } else { |
| 416 | + GAS_COST_ED25519_BATCH_VERIFY |
| 417 | + } * signatures.len() as u64; |
| 418 | + let gas_info = GasInfo::with_cost(max(gas_cost, GAS_COST_ED25519_VERIFY)); |
407 | 419 | process_gas_info::<A, S, Q>(env, gas_info)?;
|
408 | 420 | Ok(result.map_or_else(|err| err.code(), |valid| (!valid).into()))
|
409 | 421 | }
|
|
0 commit comments