diff --git a/CHANGELOG.md b/CHANGELOG.md index ee84575e..3a5abb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ Description of the upcoming release here. ### Added -- [#1436](https://github.com/FuelLabs/fuel-core/pull/1436): Add a github action to continuously test beta-4 +- [#1436](https://github.com/FuelLabs/fuel-core/pull/1436): Add a github action to continuously test beta-4. +- [#1430](https://github.com/FuelLabs/fuel-core/pull/1430): Add "sanity" benchmarks for crypto opcodes. - [#1432](https://github.com/FuelLabs/fuel-core/pull/1432): Add a new `--api-request-timeout` argument to control TTL for GraphQL requests. - [#1419](https://github.com/FuelLabs/fuel-core/pull/1419): Add additional "sanity" benchmarks for arithmetic op code instructions. - [#1411](https://github.com/FuelLabs/fuel-core/pull/1411): Added WASM and `no_std` compatibility. diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 384563ab..e2de497e 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -1,4 +1,7 @@ -use block_target_gas_set::alu::run_alu; +use block_target_gas_set::{ + alu::run_alu, + crypto::run_crypto, +}; use criterion::{ criterion_group, criterion_main, @@ -170,89 +173,10 @@ fn block_target_gas(c: &mut Criterion) { vec![], ); - let message = fuel_core_types::fuel_crypto::Message::new(b"foo"); - let ecr1_secret = p256::ecdsa::SigningKey::random(&mut rand::thread_rng()); - let ecr1_signature = secp256r1::sign_prehashed(&ecr1_secret, &message) - .expect("Failed to sign with secp256r1"); - - run( - "Script with ecr1 opcode and infinite loop", - &mut group, - [ - op::gtf_args(0x20, 0x00, GTFArgs::ScriptData), - op::addi( - 0x21, - 0x20, - ecr1_signature.as_ref().len().try_into().unwrap(), - ), - op::addi(0x22, 0x21, message.as_ref().len().try_into().unwrap()), - op::movi(0x10, PublicKey::LEN.try_into().unwrap()), - op::aloc(0x10), - op::move_(0x11, RegId::HP), - op::ecr1(0x11, 0x20, 0x21), - op::jmpb(RegId::ZERO, 0), - ] - .to_vec(), - ecr1_signature - .as_ref() - .iter() - .chain(message.as_ref()) - .copied() - .collect(), - ); - - let ed19_keypair = - ed25519_dalek::Keypair::generate(&mut ed25519_dalek_old_rand::rngs::OsRng {}); - let ed19_signature = ed19_keypair.sign(&*message); - - run( - "Script with ed19 opcode and infinite loop", - &mut group, - [ - op::gtf_args(0x20, 0x00, GTFArgs::ScriptData), - op::addi( - 0x21, - 0x20, - ed19_keypair.public.as_ref().len().try_into().unwrap(), - ), - op::addi( - 0x22, - 0x21, - ed19_signature.as_ref().len().try_into().unwrap(), - ), - op::addi(0x22, 0x21, message.as_ref().len().try_into().unwrap()), - op::movi(0x10, ed25519_dalek::PUBLIC_KEY_LENGTH.try_into().unwrap()), - op::aloc(0x10), - op::move_(0x11, RegId::HP), - op::ed19(0x20, 0x21, 0x22), - op::jmpb(RegId::ZERO, 0), - ] - .to_vec(), - ed19_keypair - .public - .as_ref() - .iter() - .chain(ed19_signature.as_ref()) - .chain(message.as_ref()) - .copied() - .collect(), - ); - - // The test is supper long because we don't use `DependentCost` for k256 opcode - // run( - // "Script with k256 opcode and infinite loop", - // &mut group, - // [ - // op::movi(0x10, 1 << 18 - 1), - // op::aloc(0x10), - // op::k256(RegId::HP, RegId::ZERO, 0x10), - // op::jmpb(RegId::ZERO, 0), - // ] - // .to_vec(), - // ); - run_alu(&mut group); + run_crypto(&mut group); + group.finish(); } diff --git a/benches/benches/block_target_gas_set/crypto.rs b/benches/benches/block_target_gas_set/crypto.rs new file mode 100644 index 00000000..c94598e0 --- /dev/null +++ b/benches/benches/block_target_gas_set/crypto.rs @@ -0,0 +1,171 @@ +use crate::{ + utils::generate_linear_costs, + *, +}; +use rand::{ + rngs::StdRng, + SeedableRng, +}; + +// ECK1: Secp251k1 signature recovery +// ECR1: Secp256r1 signature recovery +// ED19: edDSA curve25519 verification +// K256: keccak-256 +// S256: SHA-2-256 +pub fn run_crypto(group: &mut BenchmarkGroup) { + let rng = &mut StdRng::seed_from_u64(2322u64); + + let message = Message::new(b"foo"); + + let eck1_secret = SecretKey::random(rng); + let eck1_signature = Signature::sign(&eck1_secret, &message); + run( + "crypto/eck1 opcode valid", + group, + [ + op::gtf_args(0x20, 0x00, GTFArgs::ScriptData), + op::addi( + 0x21, + 0x20, + eck1_signature.as_ref().len().try_into().unwrap(), + ), + op::movi(0x10, PublicKey::LEN.try_into().unwrap()), + op::aloc(0x10), + op::eck1(RegId::HP, 0x20, 0x21), + op::jmpb(RegId::ZERO, 0), + ] + .to_vec(), + eck1_signature + .iter() + .chain(message.iter()) + .copied() + .collect(), + ); + + let wrong_message = Message::new(b"bar"); + + run( + "crypto/eck1 opcode invalid", + group, + [ + op::gtf_args(0x20, 0x00, GTFArgs::ScriptData), + op::addi( + 0x21, + 0x20, + eck1_signature.as_ref().len().try_into().unwrap(), + ), + op::movi(0x10, PublicKey::LEN.try_into().unwrap()), + op::aloc(0x10), + op::eck1(RegId::HP, 0x20, 0x21), + op::jmpb(RegId::ZERO, 0), + ] + .to_vec(), + eck1_signature + .iter() + .chain(wrong_message.iter()) + .copied() + .collect(), + ); + + let message = fuel_core_types::fuel_crypto::Message::new(b"foo"); + let ecr1_secret = p256::ecdsa::SigningKey::random(&mut rand::thread_rng()); + let ecr1_signature = secp256r1::sign_prehashed(&ecr1_secret, &message) + .expect("Failed to sign with secp256r1"); + + run( + "crypto/ecr1 opcode", + group, + [ + op::gtf_args(0x20, 0x00, GTFArgs::ScriptData), + op::addi( + 0x21, + 0x20, + ecr1_signature.as_ref().len().try_into().unwrap(), + ), + op::movi(0x10, PublicKey::LEN.try_into().unwrap()), + op::aloc(0x10), + op::move_(0x11, RegId::HP), + op::ecr1(0x11, 0x20, 0x21), + op::jmpb(RegId::ZERO, 0), + ] + .to_vec(), + ecr1_signature + .as_ref() + .iter() + .chain(message.as_ref()) + .copied() + .collect(), + ); + + let message = fuel_core_types::fuel_crypto::Message::new(b"foo"); + let ed19_keypair = + ed25519_dalek::Keypair::generate(&mut ed25519_dalek_old_rand::rngs::OsRng {}); + let ed19_signature = ed19_keypair.sign(&*message); + + run( + "crypto/ed19 opcode", + group, + [ + op::gtf_args(0x20, 0x00, GTFArgs::ScriptData), + op::addi( + 0x21, + 0x20, + ed19_keypair.public.as_ref().len().try_into().unwrap(), + ), + op::addi( + 0x22, + 0x21, + ed19_signature.as_ref().len().try_into().unwrap(), + ), + op::addi(0x22, 0x21, message.as_ref().len().try_into().unwrap()), + op::movi(0x10, ed25519_dalek::PUBLIC_KEY_LENGTH.try_into().unwrap()), + op::aloc(0x10), + op::move_(0x11, RegId::HP), + op::ed19(0x20, 0x21, 0x22), + op::jmpb(RegId::ZERO, 0), + ] + .to_vec(), + ed19_keypair + .public + .as_ref() + .iter() + .chain(ed19_signature.as_ref()) + .chain(message.as_ref()) + .copied() + .collect(), + ); + + for i in generate_linear_costs() { + let id = format!("crypto/s256 opcode {:?}", i); + run( + &id, + group, + [ + op::movi(0x11, 32), + op::aloc(0x11), + op::movi(0x10, i), + op::s256(RegId::HP, RegId::ZERO, 0x10), + op::jmpb(RegId::ZERO, 0), + ] + .to_vec(), + vec![], + ) + } + + for i in generate_linear_costs() { + let id = format!("crypto/k256 opcode {:?}", i); + run( + &id, + group, + [ + op::movi(0x11, 32), + op::aloc(0x11), + op::movi(0x10, i), + op::k256(RegId::HP, RegId::ZERO, 0x10), + op::jmpb(RegId::ZERO, 0), + ] + .to_vec(), + vec![], + ) + } +} diff --git a/benches/benches/block_target_gas_set/mod.rs b/benches/benches/block_target_gas_set/mod.rs index 0040cfb0..cae18be4 100644 --- a/benches/benches/block_target_gas_set/mod.rs +++ b/benches/benches/block_target_gas_set/mod.rs @@ -1 +1,3 @@ pub mod alu; + +pub mod crypto; diff --git a/benches/benches/utils.rs b/benches/benches/utils.rs index 7353dd19..3ebc5321 100644 --- a/benches/benches/utils.rs +++ b/benches/benches/utils.rs @@ -1,3 +1,4 @@ +use core::iter::successors; use ethnum::U256; use fuel_core_types::fuel_asm::{ op, @@ -25,3 +26,14 @@ pub fn make_u128(reg: u8, v: u128) -> Vec { pub fn make_u256(reg: u8, v: U256) -> Vec { aloc_bytearray(reg, v.to_be_bytes()) } + +pub fn generate_linear_costs() -> Vec { + let mut linear = vec![1, 10, 100, 1000, 10_000]; + let mut l = successors(Some(100_000.0f64), |n| Some(n / 1.5)) + .take(5) + .map(|f| f as u32) + .collect::>(); + l.sort_unstable(); + linear.extend(l); + linear +} diff --git a/benches/benches/vm_set/crypto.rs b/benches/benches/vm_set/crypto.rs index 96618fee..19c59a61 100644 --- a/benches/benches/vm_set/crypto.rs +++ b/benches/benches/vm_set/crypto.rs @@ -73,7 +73,7 @@ pub fn run(c: &mut Criterion) { ), ); - let linear = super::generate_linear_costs(); + let linear = super::utils::generate_linear_costs(); let mut bench_k256 = c.benchmark_group("k256"); for i in &linear { diff --git a/benches/benches/vm_set/mem.rs b/benches/benches/vm_set/mem.rs index a545c3c4..0b4c6b71 100644 --- a/benches/benches/vm_set/mem.rs +++ b/benches/benches/vm_set/mem.rs @@ -1,5 +1,6 @@ use super::run_group_ref; +use crate::utils::generate_linear_costs; use criterion::{ Criterion, Throughput, @@ -53,7 +54,7 @@ pub fn run(c: &mut Criterion) { ]), ); - let linear = super::generate_linear_costs(); + let linear = generate_linear_costs(); run_group_ref( &mut c.benchmark_group("cfei"), diff --git a/benches/benches/vm_set/mod.rs b/benches/benches/vm_set/mod.rs index a0bd339f..71753e8c 100644 --- a/benches/benches/vm_set/mod.rs +++ b/benches/benches/vm_set/mod.rs @@ -7,15 +7,3 @@ pub mod mem; pub use super::run_group_ref; use super::utils; -use core::iter::successors; - -fn generate_linear_costs() -> Vec { - let mut linear = vec![1, 10, 100, 1000, 10_000]; - let mut l = successors(Some(100_000.0f64), |n| Some(n / 1.5)) - .take(5) - .map(|f| f as u32) - .collect::>(); - l.sort_unstable(); - linear.extend(l); - linear -}