Skip to content

Commit 58b2353

Browse files
committed
Update gas cost of secp256 and ed25519
1 parent 7a6da55 commit 58b2353

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

packages/vm/src/environment.rs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ pub struct GasConfig {
4242
/// ed25519 signature verification cost
4343
pub ed25519_verify_cost: u64,
4444
/// ed25519 batch signature verification cost
45-
/// This is charged per signature.
46-
pub ed25519_batch_verify_cost: u64,
45+
pub ed25519_batch_verify_cost: LinearGasCost,
4746
/// ed25519 batch signature verification cost (single public key)
48-
/// This is charged per signature.
49-
pub ed25519_batch_verify_one_pubkey_cost: u64,
47+
pub ed25519_batch_verify_one_pubkey_cost: LinearGasCost,
5048
/// bls12-381 aggregate cost per point (g1)
5149
pub bls12_381_aggregate_g1_per_point: u64,
5250
/// bls12-381 aggregate cost per point (g2)
@@ -67,20 +65,26 @@ impl Default for GasConfig {
6765
// Target is 10^12 per second (see GAS.md), i.e. 10^6 gas per µ second.
6866
const GAS_PER_US: u64 = 1_000_000;
6967
Self {
70-
// ~119 us in crypto benchmarks
71-
secp256k1_verify_cost: 119 * GAS_PER_US,
72-
// ~233 us in crypto benchmarks
73-
secp256k1_recover_pubkey_cost: 233 * GAS_PER_US,
74-
// ~374 us in crypto benchmarks
75-
secp256r1_verify_cost: 374 * GAS_PER_US,
76-
// ~834 us in crypto benchmarks
77-
secp256r1_recover_pubkey_cost: 834 * GAS_PER_US,
78-
// ~63 us in crypto benchmarks
79-
ed25519_verify_cost: 63 * GAS_PER_US,
80-
// Gas cost factors, relative to ed25519_verify cost
81-
// From https://docs.rs/ed25519-zebra/2.2.0/ed25519_zebra/batch/index.html
82-
ed25519_batch_verify_cost: 63 * GAS_PER_US / 2,
83-
ed25519_batch_verify_one_pubkey_cost: 63 * GAS_PER_US / 4,
68+
// ~96 us in crypto benchmarks
69+
secp256k1_verify_cost: 96 * GAS_PER_US,
70+
// ~194 us in crypto benchmarks
71+
secp256k1_recover_pubkey_cost: 194 * GAS_PER_US,
72+
// ~279 us in crypto benchmarks
73+
secp256r1_verify_cost: 279 * GAS_PER_US,
74+
// ~592 us in crypto benchmarks
75+
secp256r1_recover_pubkey_cost: 592 * GAS_PER_US,
76+
// ~35 us in crypto benchmarks
77+
ed25519_verify_cost: 35 * GAS_PER_US,
78+
// Calculated based on the benchmark results for `ed25519_batch_verify_{x}`.
79+
ed25519_batch_verify_cost: LinearGasCost {
80+
base: 24 * GAS_PER_US,
81+
per_item: 21 * GAS_PER_US,
82+
},
83+
// Calculated based on the benchmark results for `ed25519_batch_verify_one_pubkey_{x}`.
84+
ed25519_batch_verify_one_pubkey_cost: LinearGasCost {
85+
base: 36 * GAS_PER_US,
86+
per_item: 10 * GAS_PER_US,
87+
},
8488
// just assume the production machines have more than 4 cores, so we can half that
8589
bls12_381_aggregate_g1_per_point: 16 * GAS_PER_US / 2,
8690
bls12_381_aggregate_g2_per_point: 33 * GAS_PER_US / 2,
@@ -93,6 +97,25 @@ impl Default for GasConfig {
9397
}
9498
}
9599

100+
/// Linear gas cost model where the cost is linear in the number of items.
101+
///
102+
/// To calculate it, you sample the cost for a few different amounts of items and fit a line to it.
103+
/// Let `b` be that line of best fit. Then `base = b(0)` is the y-intercept and
104+
/// `per_item = b(1) - b(0)` the slope.
105+
#[derive(Clone, PartialEq, Eq, Debug)]
106+
pub struct LinearGasCost {
107+
/// This is a flat part of the cost, charged once per batch.
108+
base: u64,
109+
/// This is the cost per item in the batch.
110+
per_item: u64,
111+
}
112+
113+
impl LinearGasCost {
114+
pub fn total_cost(&self, items: u64) -> u64 {
115+
self.base + self.per_item * items
116+
}
117+
}
118+
96119
/** context data **/
97120

98121
#[derive(Clone, PartialEq, Eq, Debug, Default)]

packages/vm/src/imports.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -728,14 +728,14 @@ pub fn do_ed25519_batch_verify<
728728
let signatures = decode_sections(&signatures);
729729
let public_keys = decode_sections(&public_keys);
730730

731-
let gas_cost_per_sig = if public_keys.len() == 1 {
732-
data.gas_config.ed25519_batch_verify_one_pubkey_cost
731+
let gas_cost = if public_keys.len() == 1 {
732+
&data.gas_config.ed25519_batch_verify_one_pubkey_cost
733733
} else {
734-
data.gas_config.ed25519_batch_verify_cost
734+
&data.gas_config.ed25519_batch_verify_cost
735735
};
736736
let gas_info = GasInfo::with_cost(max(
737737
// charge for each signature
738-
gas_cost_per_sig * (signatures.len() as u64),
738+
gas_cost.total_cost(signatures.len() as u64),
739739
// but ensure we charge something even if there are no signatures
740740
data.gas_config.ed25519_verify_cost,
741741
));

0 commit comments

Comments
 (0)