From 4101d540bd6eb34becc1f13281a9278ba6c98c24 Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Fri, 12 Feb 2021 11:03:45 +0000 Subject: [PATCH 001/134] feat: Extend the Math API with EVM precompiles. --- Cargo.lock | 2 + core/primitives-core/src/config.rs | 30 +++++++++ .../res/test_contract_ts.wasm | Bin runtime/near-vm-logic/Cargo.toml | 2 + runtime/near-vm-logic/src/logic.rs | 44 ++++++++++++ runtime/near-vm-logic/tests/test_miscs.rs | 63 ++++++++++++++++++ runtime/near-vm-runner/src/imports.rs | 2 + runtime/runtime-params-estimator/src/cases.rs | 4 ++ 8 files changed, 147 insertions(+) mode change 100755 => 100644 runtime/near-test-contracts/res/test_contract_ts.wasm diff --git a/Cargo.lock b/Cargo.lock index 203decf3c51..d8ed39a6dec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3602,6 +3602,7 @@ name = "near-vm-logic" version = "3.0.0" dependencies = [ "base64 0.13.0", + "blake2", "borsh", "bs58", "byteorder", @@ -3609,6 +3610,7 @@ dependencies = [ "near-primitives-core", "near-runtime-utils", "near-vm-errors", + "ripemd160", "serde", "serde_json", "sha2 0.9.3", diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 58136b1d244..ac395ddcc75 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -223,6 +223,16 @@ pub struct ExtCostsConfig { /// Cost of getting sha256 per byte pub keccak512_byte: Gas, + /// Cost of getting ripemd160 base + pub ripemd160_base: Gas, + /// Cost of getting ripemd160 per byte + pub ripemd160_byte: Gas, + + /// Cost of getting blake2b base + pub blake2b_base: Gas, + /// Cost of getting blake2b per byte + pub blake2b_byte: Gas, + /// Cost for calling logging. pub log_base: Gas, /// Cost for logging per byte @@ -353,6 +363,10 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, + ripemd160_base: SAFETY_MULTIPLIER * 1513656750, // TODO + ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO + blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO + blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, storage_write_base: SAFETY_MULTIPLIER * 21398912000, @@ -423,6 +437,10 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, + ripemd160_base: 0, + ripemd160_byte: 0, + blake2b_base: 0, + blake2b_byte: 0, log_base: 0, log_byte: 0, storage_write_base: 0, @@ -494,6 +512,10 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, + ripemd160_base, + ripemd160_byte, + blake2b_base, + blake2b_byte, log_base, log_byte, storage_write_base, @@ -618,6 +640,10 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, + ripemd160_base => config.ripemd160_base, + ripemd160_byte => config.ripemd160_byte, + blake2b_base => config.blake2b_base, + blake2b_byte => config.blake2b_byte, log_base => config.log_base, log_byte => config.log_byte, storage_write_base => config.storage_write_base, @@ -692,6 +718,10 @@ impl ExtCosts { "keccak256_byte", "keccak512_base", "keccak512_byte", + "ripemd160_base", + "ripemd160_byte", + "blake2b_base", + "blake2b_byte", "log_base", "log_byte", "storage_write_base", diff --git a/runtime/near-test-contracts/res/test_contract_ts.wasm b/runtime/near-test-contracts/res/test_contract_ts.wasm old mode 100755 new mode 100644 diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index f504b28ef8f..0832e05100b 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,9 +14,11 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" +blake2 = "0.9.1" borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" +ripemd160 = "0.9.0" serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" sha3 = ">=0.8,<0.10" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index d80b64719c8..2bc3e9a57ae 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -951,6 +951,50 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } + /// Hashes the given value using RIPEMD-160 and returns it into `register_id`. + /// + /// # Errors + /// + /// If `value_len + value_ptr` points outside the memory or the registers use more memory than + /// the limit with `MemoryAccessViolation`. + /// + /// # Cost + /// + /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_byte * num_bytes` + pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { + self.gas_counter.pay_base(ripemd160_base)?; + let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; + self.gas_counter.pay_per_byte(ripemd160_byte, value.len() as u64)?; + + use ripemd160::Digest; + + let value_hash = ripemd160::Ripemd160::digest(&value); + self.internal_write_register(register_id, value_hash.as_slice().to_vec()) + } + + /// Hashes the given value using BLAKE2b and returns it into `register_id`. + /// + /// # Errors + /// + /// If `value_len + value_ptr` points outside the memory or the registers use more memory than + /// the limit with `MemoryAccessViolation`. + /// + /// # Cost + /// + /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` + pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { + self.gas_counter.pay_base(blake2b_base)?; + let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; + self.gas_counter.pay_per_byte(blake2b_byte, value.len() as u64)?; + + use blake2::{Blake2b, Digest}; + + let mut hasher = Blake2b::new(); + hasher.update(&value); + let value_hash = hasher.finalize(); + self.internal_write_register(register_id, value_hash.as_slice().to_vec()) + } + /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. /// /// # Errors diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 0ce9fb87caf..515f7fdf8b9 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -530,6 +530,69 @@ fn test_keccak512() { }); } +#[test] +fn test_ripemd160() { + let mut logic_builder = VMLogicBuilder::default(); + let mut logic = logic_builder.build(get_context(vec![], false)); + let data = b"tesdsst"; + + logic.ripemd160(data.len() as _, data.as_ptr() as _, 0).unwrap(); + let res = &vec![0u8; 20]; + logic.read_register(0, res.as_ptr() as _).expect("OK"); + assert_eq!( + res, + &[21, 102, 156, 115, 232, 3, 58, 215, 35, 84, 129, 30, 143, 86, 212, 104, 70, 97, 14, 225,] + ); + let len = data.len() as u64; + assert_costs(map! { + ExtCosts::base: 1, + ExtCosts::read_memory_base: 1, + ExtCosts::read_memory_byte: len, + ExtCosts::write_memory_base: 1, + ExtCosts::write_memory_byte: 20, + ExtCosts::read_register_base: 1, + ExtCosts::read_register_byte: 20, + ExtCosts::write_register_base: 1, + ExtCosts::write_register_byte: 20, + ExtCosts::ripemd160_base: 1, + ExtCosts::ripemd160_byte: len, + }); +} + +#[test] +fn test_blake2b() { + let mut logic_builder = VMLogicBuilder::default(); + let mut logic = logic_builder.build(get_context(vec![], false)); + let data = b"tesdsst"; + + logic.blake2b(data.len() as _, data.as_ptr() as _, 0).unwrap(); + let res = &vec![0u8; 64]; + logic.read_register(0, res.as_ptr() as _).expect("OK"); + assert_eq!( + res, + &[ + 144, 12, 165, 192, 98, 246, 37, 228, 134, 61, 43, 212, 111, 32, 204, 204, 186, 212, 47, + 44, 209, 53, 167, 80, 195, 200, 226, 84, 34, 162, 249, 135, 172, 3, 90, 122, 205, 96, + 211, 100, 188, 18, 134, 125, 111, 130, 31, 143, 25, 108, 194, 209, 205, 73, 169, 10, + 132, 222, 75, 219, 103, 234, 67, 180 + ] + ); + let len = data.len() as u64; + assert_costs(map! { + ExtCosts::base: 1, + ExtCosts::read_memory_base: 1, + ExtCosts::read_memory_byte: len, + ExtCosts::write_memory_base: 1, + ExtCosts::write_memory_byte: 64, + ExtCosts::read_register_base: 1, + ExtCosts::read_register_byte: 64, + ExtCosts::write_register_base: 1, + ExtCosts::write_register_byte: 64, + ExtCosts::blake2b_base: 1, + ExtCosts::blake2b_byte: len, + }); +} + #[test] fn test_hash256_register() { let mut logic_builder = VMLogicBuilder::default(); diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 3325e402d4d..d1781a47f08 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -221,6 +221,8 @@ wrapped_imports! { sha256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # // ##################### diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index e82f6aab5ec..2d5f4de465a 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -760,6 +760,10 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), + ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), + ripemd160_byte: measured_to_gas(metric, &measured, ripemd160_byte), + blake2b_base: measured_to_gas(metric, &measured, blake2b_base), + blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), storage_write_base: measured_to_gas(metric, &measured, storage_write_base), From f1129da459d72fab043b05d6932e6f49760492f3 Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Wed, 17 Feb 2021 06:12:22 +0000 Subject: [PATCH 002/134] feat: Add Math API stubs for ECRecover. (#3921) --- core/primitives-core/src/config.rs | 15 +++++++++++++++ runtime/near-vm-logic/src/logic.rs | 15 +++++++++++++++ runtime/near-vm-logic/tests/test_miscs.rs | 5 +++++ runtime/near-vm-runner/src/imports.rs | 1 + runtime/runtime-params-estimator/src/cases.rs | 2 ++ 5 files changed, 38 insertions(+) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index ac395ddcc75..15093abf918 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -233,6 +233,11 @@ pub struct ExtCostsConfig { /// Cost of getting blake2b per byte pub blake2b_byte: Gas, + /// Cost of getting ecrecover base + pub ecrecover_base: Gas, + /// Cost of getting ecrecover per byte + pub ecrecover_byte: Gas, + /// Cost for calling logging. pub log_base: Gas, /// Cost for logging per byte @@ -367,6 +372,8 @@ impl Default for ExtCostsConfig { ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO + ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO + ecrecover_byte: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, storage_write_base: SAFETY_MULTIPLIER * 21398912000, @@ -441,6 +448,8 @@ impl ExtCostsConfig { ripemd160_byte: 0, blake2b_base: 0, blake2b_byte: 0, + ecrecover_base: 0, + ecrecover_byte: 0, log_base: 0, log_byte: 0, storage_write_base: 0, @@ -516,6 +525,8 @@ pub enum ExtCosts { ripemd160_byte, blake2b_base, blake2b_byte, + ecrecover_base, + ecrecover_byte, log_base, log_byte, storage_write_base, @@ -644,6 +655,8 @@ impl ExtCosts { ripemd160_byte => config.ripemd160_byte, blake2b_base => config.blake2b_base, blake2b_byte => config.blake2b_byte, + ecrecover_base => config.ecrecover_base, + ecrecover_byte => config.ecrecover_byte, log_base => config.log_base, log_byte => config.log_byte, storage_write_base => config.storage_write_base, @@ -722,6 +735,8 @@ impl ExtCosts { "ripemd160_byte", "blake2b_base", "blake2b_byte", + "ecrecover_base", + "ecrecover_byte", "log_base", "log_byte", "storage_write_base", diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 2bc3e9a57ae..d1e09640f62 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -995,6 +995,21 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } + /// TODO + /// + /// # Errors + /// + /// TODO + /// + /// # Cost + /// + /// TODO + pub fn ecrecover(&mut self, hash_ptr: u64, v: u8, r_ptr: u64, s_ptr: u64, register_id: u64) -> Result<()> { + self.gas_counter.pay_base(ecrecover_base)?; + + Ok(()) // TODO + } + /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. /// /// # Errors diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 515f7fdf8b9..2856dff20fd 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -593,6 +593,11 @@ fn test_blake2b() { }); } +#[test] +fn test_ecrecover() { + // TODO +} + #[test] fn test_hash256_register() { let mut logic_builder = VMLogicBuilder::default(); diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index d1781a47f08..5c2d650829f 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -223,6 +223,7 @@ wrapped_imports! { keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + ecrecover<[hash_ptr: u64, v: u8, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # // ##################### diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 2d5f4de465a..26c365160c3 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -764,6 +764,8 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts ripemd160_byte: measured_to_gas(metric, &measured, ripemd160_byte), blake2b_base: measured_to_gas(metric, &measured, blake2b_base), blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), + ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), + ecrecover_byte: measured_to_gas(metric, &measured, ecrecover_byte), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), storage_write_base: measured_to_gas(metric, &measured, storage_write_base), From 55291eea262c269cfa3a9fb5d5ffb644ff7c66ac Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Wed, 17 Feb 2021 10:31:55 +0000 Subject: [PATCH 003/134] test: Add RIPEMD-160 and BLAKE2b to the params estimator. --- runtime/runtime-params-estimator/README.md | 2 +- runtime/runtime-params-estimator/src/cases.rs | 13 +++++ .../src/ext_costs_generator.rs | 6 +++ .../test-contract/src/lib.rs | 48 +++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/runtime/runtime-params-estimator/README.md b/runtime/runtime-params-estimator/README.md index 87f5deeaea3..40165784b93 100644 --- a/runtime/runtime-params-estimator/README.md +++ b/runtime/runtime-params-estimator/README.md @@ -13,6 +13,6 @@ Use this tool to measure the running time of elementary runtime operations that cargo run --release --package runtime-params-estimator --features required --bin runtime-params-estimator -- --home /tmp/data --accounts-num 20000 --iters 1 --warmup-iters 1 --metric time ``` - With the given parameters above estimator will run relatively fast. We will be using different parameters to do the actual parameter estimation. Also note that the defualt metric is `icount`, instruction count, but requires using qemu to emulate the processor. So this example provides a way to get a quick way to test out the estimator based on time, but the instructions in [`emu-cost/README.md`](./emu-cost/README.md) should be followed to get the real data. + With the given parameters above estimator will run relatively fast. We will be using different parameters to do the actual parameter estimation. Also note that the default metric is `icount`, instruction count, but requires using QEMU to emulate the processor. So this example provides a way to get a quick way to test out the estimator based on time, but the instructions in [`emu-cost/README.md`](./emu-cost/README.md) should be followed to get the real data. Note, if you use the plotting functionality you would need to install [gnuplot](http://gnuplot.info/) to see the graphs. diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 26c365160c3..6b5d83a5d78 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -198,6 +198,19 @@ pub enum Metric { keccak256_10kib_10k, keccak512_10b_10k, keccak512_10kib_10k, + #[cfg(feature = "protocol_feature_evm")] + ripemd160_10b_10k, + #[cfg(feature = "protocol_feature_evm")] + ripemd160_10kib_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2b_10b_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2b_10kib_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_10b_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_10kib_10k, + #[cfg(feature = "protocol_feature_evm")] #[cfg(feature = "protocol_feature_alt_bn128")] alt_bn128_g1_multiexp_1_1k, #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index e3e353c237f..81e554422ba 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,6 +65,12 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); + self.extract(ripemd160_10b_10k, ripemd160_base); + self.extract(ripemd160_10kib_10k, ripemd160_byte); + + self.extract(blake2b_10b_10k, blake2b_base); + self.extract(blake2b_10kib_10k, blake2b_byte); + #[cfg(feature = "protocol_feature_alt_bn128")] { self.extract(alt_bn128_g1_multiexp_1_1k, alt_bn128_g1_multiexp_base); diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index a2bda684413..f274443c3a7 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -47,6 +47,8 @@ extern "C" { fn sha256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); + fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); + fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # // ##################### @@ -424,6 +426,52 @@ pub unsafe fn keccak512_10kib_10k() { } } +// Function to measure `ripemd160_base` and `ripemd160_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `ripemd160` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute ripemd160 on 10b 10k times. +#[no_mangle] +pub unsafe fn ripemd160_10b_10k() { + let buffer = [65u8; 10]; + for _ in 0..10_000 { + ripemd160(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); + } +} +// Function to measure `ripemd160_base` and `ripemd160_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `ripemd160` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute ripemd160 on 10kib 10k times. +#[no_mangle] +pub unsafe fn ripemd160_10kib_10k() { + let buffer = [65u8; 10240]; + for _ in 0..10_000 { + ripemd160(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); + } +} + +// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `blake2b` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute blake2b on 10b 10k times. +#[no_mangle] +pub unsafe fn blake2b_10b_10k() { + let buffer = [65u8; 10]; + for _ in 0..10_000 { + blake2b(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); + } +} +// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `blake2b` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute blake2b on 10kib 10k times. +#[no_mangle] +pub unsafe fn blake2b_10kib_10k() { + let buffer = [65u8; 10240]; + for _ in 0..10_000 { + blake2b(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); + } +} + // Function to measure `alt_bn128_g1_multiexp_base` and `alt_bn128_g1_multiexp_sublinear`. Also measures `base`, `write_register_base`, // and `write_register_byte`. However `g1_multiexp` computation is more expensive than register writing // so we are okay overcharging it. From e4aedd6de1a68d7274ed0075d5f58733be84f71b Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Wed, 17 Feb 2021 10:34:21 +0000 Subject: [PATCH 004/134] fix: Improve error output from the params estimator. Co-authored-by: Aleksey Kladov --- runtime/runtime-params-estimator/src/cases.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 6b5d83a5d78..2120cf995e1 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -691,7 +691,7 @@ fn measured_to_gas( ) -> u64 { match measured.get(&cost) { Some(value) => ratio_to_gas(gas_metric, *value), - None => panic!("cost {} not found", cost as u32), + None => panic!("cost {:?} not found", cost), } } From 4b145d18e7c52917c36bb5f576476b2145259b66 Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Thu, 18 Feb 2021 14:06:27 +0000 Subject: [PATCH 005/134] test: Add ECRecover stubs to the params estimator. --- core/primitives-core/src/config.rs | 9 +-------- runtime/runtime-params-estimator/src/cases.rs | 2 +- .../src/ext_costs_generator.rs | 2 ++ .../test-contract/src/lib.rs | 12 ++++++++++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 15093abf918..8b193a25d9b 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -233,10 +233,8 @@ pub struct ExtCostsConfig { /// Cost of getting blake2b per byte pub blake2b_byte: Gas, - /// Cost of getting ecrecover base + /// Cost of calling ecrecover pub ecrecover_base: Gas, - /// Cost of getting ecrecover per byte - pub ecrecover_byte: Gas, /// Cost for calling logging. pub log_base: Gas, @@ -373,7 +371,6 @@ impl Default for ExtCostsConfig { blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO - ecrecover_byte: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, storage_write_base: SAFETY_MULTIPLIER * 21398912000, @@ -449,7 +446,6 @@ impl ExtCostsConfig { blake2b_base: 0, blake2b_byte: 0, ecrecover_base: 0, - ecrecover_byte: 0, log_base: 0, log_byte: 0, storage_write_base: 0, @@ -526,7 +522,6 @@ pub enum ExtCosts { blake2b_base, blake2b_byte, ecrecover_base, - ecrecover_byte, log_base, log_byte, storage_write_base, @@ -656,7 +651,6 @@ impl ExtCosts { blake2b_base => config.blake2b_base, blake2b_byte => config.blake2b_byte, ecrecover_base => config.ecrecover_base, - ecrecover_byte => config.ecrecover_byte, log_base => config.log_base, log_byte => config.log_byte, storage_write_base => config.storage_write_base, @@ -736,7 +730,6 @@ impl ExtCosts { "blake2b_base", "blake2b_byte", "ecrecover_base", - "ecrecover_byte", "log_base", "log_byte", "storage_write_base", diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 2120cf995e1..e5e84b10da6 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -211,6 +211,7 @@ pub enum Metric { #[cfg(feature = "protocol_feature_evm")] blake2b_f_10kib_10k, #[cfg(feature = "protocol_feature_evm")] + ecrecover_10k, #[cfg(feature = "protocol_feature_alt_bn128")] alt_bn128_g1_multiexp_1_1k, #[cfg(feature = "protocol_feature_alt_bn128")] @@ -778,7 +779,6 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts blake2b_base: measured_to_gas(metric, &measured, blake2b_base), blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), - ecrecover_byte: measured_to_gas(metric, &measured, ecrecover_byte), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), storage_write_base: measured_to_gas(metric, &measured, storage_write_base), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 81e554422ba..b4db9d0ab48 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -71,6 +71,8 @@ impl ExtCostsGenerator { self.extract(blake2b_10b_10k, blake2b_base); self.extract(blake2b_10kib_10k, blake2b_byte); + self.extract(ecrecover_10k, ecrecover_base); + #[cfg(feature = "protocol_feature_alt_bn128")] { self.extract(alt_bn128_g1_multiexp_1_1k, alt_bn128_g1_multiexp_base); diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index f274443c3a7..2153ec84a4d 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -49,6 +49,7 @@ extern "C" { fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); + fn ecrecover(hash_ptr: u64, v: u8, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # // ##################### @@ -472,6 +473,17 @@ pub unsafe fn blake2b_10kib_10k() { } } +// Function to measure `ecrecover_base`. Also measures `base`, `write_register_base`, and +// `write_register_byte`. However `ecrecover` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute ecrecover 10k times. +#[no_mangle] +pub unsafe fn ecrecover_10k() { + for _ in 0..10_000 { + // TODO + } +} + // Function to measure `alt_bn128_g1_multiexp_base` and `alt_bn128_g1_multiexp_sublinear`. Also measures `base`, `write_register_base`, // and `write_register_byte`. However `g1_multiexp` computation is more expensive than register writing // so we are okay overcharging it. From f8461f712738cf6f663a2b0bec00056d33d17134 Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Thu, 18 Feb 2021 14:09:22 +0000 Subject: [PATCH 006/134] fix: Widen ecrecover() parameter type to pass CI checks. --- runtime/near-vm-logic/src/logic.rs | 2 +- runtime/near-vm-runner/src/imports.rs | 2 +- runtime/runtime-params-estimator/test-contract/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index d1e09640f62..3e3d06f9417 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1004,7 +1004,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// TODO - pub fn ecrecover(&mut self, hash_ptr: u64, v: u8, r_ptr: u64, s_ptr: u64, register_id: u64) -> Result<()> { + pub fn ecrecover(&mut self, hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(ecrecover_base)?; Ok(()) // TODO diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 5c2d650829f..b50462a88f7 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -223,7 +223,7 @@ wrapped_imports! { keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ecrecover<[hash_ptr: u64, v: u8, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, + ecrecover<[hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # // ##################### diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 2153ec84a4d..cf565449f15 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -49,7 +49,7 @@ extern "C" { fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); - fn ecrecover(hash_ptr: u64, v: u8, r_ptr: u64, s_ptr: u64, register_id: u64); + fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # // ##################### From becf0036ea71cb3d04228d0f96e04726b24cda6f Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Thu, 18 Feb 2021 22:11:07 +0000 Subject: [PATCH 007/134] feat(chain): Bump the protocol version. --- core/primitives/src/version.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index bd5cd28c8fc..1a7cee8f237 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -52,6 +52,9 @@ pub const SHARD_CHUNK_HEADER_UPGRADE_VERSION: ProtocolVersion = 41; /// Updates the way receipt ID is constructed to use current block hash instead of last block hash pub const CREATE_RECEIPT_ID_SWITCH_TO_CURRENT_BLOCK_VERSION: ProtocolVersion = 42; +/// See [#3954: Extend the Math API with EVM precompiles](https://github.com/near/nearcore/pull/3954) +pub const MATH_API_FOR_EVM_ISTANBUL_PROTOCOL_VERSION: ProtocolVersion = 43; + pub struct ProtocolVersionRange { lower: ProtocolVersion, upper: Option, From 4950ad3405cbf13242129858f1e2f8316f2555dd Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Fri, 19 Feb 2021 02:57:54 +0000 Subject: [PATCH 008/134] feat(runtime): Implement ECRecover in the Math API. (#3921) --- chain/jsonrpc/res/rpc_errors_schema.json | 5 +++ runtime/near-vm-errors/src/lib.rs | 3 ++ runtime/near-vm-logic/Cargo.toml | 2 + runtime/near-vm-logic/src/logic.rs | 40 ++++++++++++++++++- runtime/near-vm-logic/tests/test_miscs.rs | 34 ++++++++++++++-- .../test-contract/src/lib.rs | 5 ++- 6 files changed, 83 insertions(+), 6 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index e5ac6cec66e..c7dc48937b3 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -76,6 +76,11 @@ "method_name": "" } }, + "InvalidECDSASignature": { + "name": "InvalidECDSASignature", + "subtypes": [], + "props": {} + }, "Deserialization": { "name": "Deserialization", "subtypes": [], diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 9311eb01030..4498a8a6d2b 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -206,6 +206,8 @@ pub enum HostError { ContractSizeExceeded { size: u64, limit: u64 }, /// The host function was deprecated. Deprecated { method_name: String }, + /// Invalid ECDSA signature. + InvalidECDSASignature, /// Deserialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg: String }, @@ -494,6 +496,7 @@ impl std::fmt::Display for HostError { ReturnedValueLengthExceeded { length, limit } => write!(f, "The length of a returned value {} exceeds the limit {}", length, limit), ContractSizeExceeded { size, limit } => write!(f, "The size of a contract code in DeployContract action {} exceeds the limit {}", size, limit), Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), + InvalidECDSASignature => write!(f, "Invalid ECDSA signature"), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 0832e05100b..2af5f6530cc 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -18,6 +18,7 @@ blake2 = "0.9.1" borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" +libsecp256k1 = "0.3.5" ripemd160 = "0.9.0" serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" @@ -31,6 +32,7 @@ near-runtime-utils = { path = "../near-runtime-utils", version = "3.0.0" } bn = { package = "zeropool-bn", version = "0.5.9", features = [], optional = true } [dev-dependencies] +hex-literal = "0.2" serde_json = {version= "1", features= ["preserve_order"]} [features] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 3e3d06f9417..c184cf1e8bd 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1004,10 +1004,46 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// TODO - pub fn ecrecover(&mut self, hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64) -> Result<()> { + pub fn ecrecover( + &mut self, + hash_ptr: u64, + v: u32, + r_ptr: u64, + s_ptr: u64, + register_id: u64, + ) -> Result<()> { self.gas_counter.pay_base(ecrecover_base)?; + if v != 27 && v != 28 { + return Err(HostError::InvalidECDSASignature.into()); + } + let hash = self.memory_get_vec(hash_ptr, 32)?; + let v = (v & 0xFF) as u8; + let r = self.memory_get_vec(r_ptr, 32)?; + let s = self.memory_get_vec(s_ptr, 32)?; + + let hash = secp256k1::Message::parse_slice(hash.as_slice()).unwrap(); + + let mut signature = [0u8; 64]; + signature[0..32].copy_from_slice(r.as_slice()); + signature[32..64].copy_from_slice(s.as_slice()); + let signature = secp256k1::Signature::parse(&signature); + + let recovery_id = match secp256k1::RecoveryId::parse_rpc(v) { + Err(_) => return Err(HostError::InvalidECDSASignature.into()), + Ok(rid) => rid, + }; + + let public_key = match secp256k1::recover(&hash, &signature, &recovery_id) { + Err(_) => return Err(HostError::InvalidECDSASignature.into()), + Ok(pk) => pk, + }; + + use sha3::Digest; + let result = sha3::Keccak256::digest(&public_key.serialize()[1..]); + let mut address = [0u8; 20]; + address.copy_from_slice(&result[12..]); - Ok(()) // TODO + self.internal_write_register(register_id, address.to_vec()) } /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 2856dff20fd..faf3bdc7f2e 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -1,5 +1,6 @@ use fixtures::get_context; use helpers::*; +use hex_literal::hex; use near_vm_errors::HostError; use near_vm_logic::ExtCosts; use vm_logic_builder::VMLogicBuilder; @@ -534,8 +535,8 @@ fn test_keccak512() { fn test_ripemd160() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); - let data = b"tesdsst"; + let data = b"tesdsst"; logic.ripemd160(data.len() as _, data.as_ptr() as _, 0).unwrap(); let res = &vec![0u8; 20]; logic.read_register(0, res.as_ptr() as _).expect("OK"); @@ -563,8 +564,8 @@ fn test_ripemd160() { fn test_blake2b() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); - let data = b"tesdsst"; + let data = b"tesdsst"; logic.blake2b(data.len() as _, data.as_ptr() as _, 0).unwrap(); let res = &vec![0u8; 64]; logic.read_register(0, res.as_ptr() as _).expect("OK"); @@ -595,7 +596,34 @@ fn test_blake2b() { #[test] fn test_ecrecover() { - // TODO + let mut logic_builder = VMLogicBuilder::default(); + let mut logic = logic_builder.build(get_context(vec![], false)); + + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/cryptography/ECDSA.test.js + use sha3::Digest; + let hash = sha3::Keccak256::digest(b"OpenZeppelin"); + let signature = hex!("5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be8921b"); + let signer = hex!("2cc1166f6212628A0deEf2B33BEFB2187D35b86c"); + + let (r, s, v) = (&signature[0..32], &signature[32..64], signature[64] as u32); + logic.ecrecover(hash.as_ptr() as _, v, r.as_ptr() as _, s.as_ptr() as _, 0).unwrap(); + + let result = &vec![0u8; 20]; + logic.read_register(0, result.as_ptr() as _).expect("OK"); + + assert_eq!(result.to_vec(), signer); + assert_costs(map! { + ExtCosts::base: 1, + ExtCosts::read_memory_base: 3, + ExtCosts::read_memory_byte: 96, + ExtCosts::write_memory_base: 1, + ExtCosts::write_memory_byte: 20, + ExtCosts::read_register_base: 1, + ExtCosts::read_register_byte: 20, + ExtCosts::write_register_base: 1, + ExtCosts::write_register_byte: 20, + ExtCosts::ecrecover_base: 1, + }); } #[test] diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index cf565449f15..135c7ff3745 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -479,8 +479,11 @@ pub unsafe fn blake2b_10kib_10k() { // Compute ecrecover 10k times. #[no_mangle] pub unsafe fn ecrecover_10k() { + let hash = [0u8; 32]; + let signature = [0u8; 65]; + let (r, s, v) = (&signature[0..32], &signature[32..64], 27); for _ in 0..10_000 { - // TODO + ecrecover(hash.as_ptr() as _, v, r.as_ptr() as _, s.as_ptr() as _, 0); } } From a5bbe0babb48251e0651f54e219f9bc30f0e812c Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Fri, 19 Feb 2021 03:14:21 +0000 Subject: [PATCH 009/134] docs: Document the ecrecover() function. --- runtime/near-vm-logic/src/logic.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index c184cf1e8bd..e084bba0c0c 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -995,15 +995,18 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } - /// TODO + /// Recovers an ECDSA signer address and returns it into `register_id`. /// /// # Errors /// - /// TODO + /// * If `hash_ptr`, `r_ptr`, or `s_ptr` point outside the memory or the registers use more + /// memory than the limit, then returns `MemoryAccessViolation`. + /// * If `v` is invalid (not 27 or 28), then returns `InvalidECDSASignature`. + /// * If the ECDSA recovery fails for any reason, then returns `InvalidECDSASignature`. /// /// # Cost /// - /// TODO + /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` pub fn ecrecover( &mut self, hash_ptr: u64, From 2f881939873935931f9c9d07c303b5e440eae9d6 Mon Sep 17 00:00:00 2001 From: Arto Bendiken Date: Fri, 19 Feb 2021 03:28:27 +0000 Subject: [PATCH 010/134] fix(chain): Guard protocol upgrade behind EVM feature. --- core/primitives/src/version.rs | 3 --- runtime/near-vm-runner/src/imports.rs | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index 1a7cee8f237..bd5cd28c8fc 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -52,9 +52,6 @@ pub const SHARD_CHUNK_HEADER_UPGRADE_VERSION: ProtocolVersion = 41; /// Updates the way receipt ID is constructed to use current block hash instead of last block hash pub const CREATE_RECEIPT_ID_SWITCH_TO_CURRENT_BLOCK_VERSION: ProtocolVersion = 42; -/// See [#3954: Extend the Math API with EVM precompiles](https://github.com/near/nearcore/pull/3954) -pub const MATH_API_FOR_EVM_ISTANBUL_PROTOCOL_VERSION: ProtocolVersion = 43; - pub struct ProtocolVersionRange { lower: ProtocolVersion, upper: Option, diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index b50462a88f7..5144088dbed 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -221,9 +221,9 @@ wrapped_imports! { sha256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ecrecover<[hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # // ##################### From e97e6c66cfcf29844b51dd7de41f138ae6dba4b0 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 10 Mar 2021 11:20:50 +0700 Subject: [PATCH 011/134] add crypto feature gates --- core/primitives-core/Cargo.toml | 6 +++++ core/primitives-core/src/config.rs | 25 +++++++++++++++++ runtime/near-vm-logic/Cargo.toml | 6 ++--- runtime/near-vm-logic/src/logic.rs | 3 +++ runtime/near-vm-logic/tests/test_miscs.rs | 3 +++ runtime/near-vm-runner/Cargo.toml | 9 ++++++- runtime/runtime-params-estimator/Cargo.toml | 9 ++++++- runtime/runtime-params-estimator/src/cases.rs | 27 +++++++++++++++++++ .../src/ext_costs_generator.rs | 5 ++++ .../test-contract/src/lib.rs | 8 ++++++ 10 files changed, 96 insertions(+), 5 deletions(-) diff --git a/core/primitives-core/Cargo.toml b/core/primitives-core/Cargo.toml index 8f18572d4d7..ff09d4753cc 100644 --- a/core/primitives-core/Cargo.toml +++ b/core/primitives-core/Cargo.toml @@ -24,7 +24,13 @@ lazy_static = "1.4" [features] default = [] +protocol_feature_evm = [] protocol_feature_add_account_versions = [] protocol_feature_evm = [] protocol_feature_alt_bn128 = [] protocol_feature_tx_size_limit = [] + +# cryptography extras +ripemd160 = [] +blake2b = [] +ecrecover = [] diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 8b193a25d9b..13a33fc3920 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -224,16 +224,21 @@ pub struct ExtCostsConfig { pub keccak512_byte: Gas, /// Cost of getting ripemd160 base + #[cfg(feature = "ripemd160")] pub ripemd160_base: Gas, /// Cost of getting ripemd160 per byte + #[cfg(feature = "ripemd160")] pub ripemd160_byte: Gas, /// Cost of getting blake2b base + #[cfg(feature = "blake2b")] pub blake2b_base: Gas, /// Cost of getting blake2b per byte + #[cfg(feature = "blake2b")] pub blake2b_byte: Gas, /// Cost of calling ecrecover + #[cfg(feature = "ecrecover")] pub ecrecover_base: Gas, /// Cost for calling logging. @@ -366,10 +371,15 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, + #[cfg(feature = "ripemd160")] ripemd160_base: SAFETY_MULTIPLIER * 1513656750, // TODO + #[cfg(feature = "ripemd160")] ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO + #[cfg(feature = "blake2b")] blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO + #[cfg(feature = "blake2b")] blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO + #[cfg(feature = "ecrecover")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -441,10 +451,15 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, + #[cfg(feature = "ripemd160")] ripemd160_base: 0, + #[cfg(feature = "ripemd160")] ripemd160_byte: 0, + #[cfg(feature = "blake2b")] blake2b_base: 0, + #[cfg(feature = "blake2b")] blake2b_byte: 0, + #[cfg(feature = "ecrecover")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -517,10 +532,15 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, + #[cfg(feature = "ripemd160")] ripemd160_base, + #[cfg(feature = "ripemd160")] ripemd160_byte, + #[cfg(feature = "blake2b")] blake2b_base, + #[cfg(feature = "blake2b")] blake2b_byte, + #[cfg(feature = "ecrecover")] ecrecover_base, log_base, log_byte, @@ -646,10 +666,15 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, + #[cfg(feature = "ripemd160")] ripemd160_base => config.ripemd160_base, + #[cfg(feature = "ripemd160")] ripemd160_byte => config.ripemd160_byte, + #[cfg(feature = "blake2b")] blake2b_base => config.blake2b_base, + #[cfg(feature = "blake2b")] blake2b_byte => config.blake2b_byte, + #[cfg(feature = "ecrecover")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 2af5f6530cc..a17a9e4d39a 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,12 +14,12 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = "0.9.1" +blake2 = { version = "0.9.1", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" -libsecp256k1 = "0.3.5" -ripemd160 = "0.9.0" +libsecp256k1 = { version = "0.3.5", optional = true } +ripemd160 = { version = "0.9.0", optional = true } serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" sha3 = ">=0.8,<0.10" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index e084bba0c0c..1c8e31a533d 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -961,6 +961,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_byte * num_bytes` + #[cfg(feature = "ripemd160")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -982,6 +983,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` + #[cfg(feature = "blake2b")] pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(blake2b_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -1007,6 +1009,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` + #[cfg(feature = "ecrecover")] pub fn ecrecover( &mut self, hash_ptr: u64, diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index faf3bdc7f2e..448f50f9ee2 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -532,6 +532,7 @@ fn test_keccak512() { } #[test] +#[cfg(feature = "ripemd160")] fn test_ripemd160() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -561,6 +562,7 @@ fn test_ripemd160() { } #[test] +#[cfg(feature = "blake2b")] fn test_blake2b() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -595,6 +597,7 @@ fn test_blake2b() { } #[test] +#[cfg(feature = "ecrecover")] fn test_ecrecover() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index 64bac7e6c94..580364a1576 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -56,7 +56,14 @@ wasmer1_default = [] lightbeam = ["wasmtime/lightbeam"] no_cpu_compatibility_checks = [] -protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm"] +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm", "crypto_extras"] +evm_crypto_extras = ["crypto_extras"] +crypto_extras = ["ripemd160", "blake2b", "ecrecover"] + +# cryptography extras +ripemd160 = [] +blake2b = [] +ecrecover = [] no_cache = [] diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index e899ff5569d..1a5f9ffec92 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -69,4 +69,11 @@ protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "near-chain-configs/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-primitives/protocol_feature_evm", - "testlib/protocol_feature_evm"] + "testlib/protocol_feature_evm", + "crypto_extras"] +crypto_extras = ["ripemd160", "blake2b", "ecrecover"] + +# cryptography extras +ripemd160 = [] +blake2b = [] +ecrecover = [] diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index e5e84b10da6..ceb9246cae6 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -621,6 +621,28 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon data_receipt_100kib_1000 => data_receipt_100kib_1000 }; + v.append(&mut ripemd_v); + } + + #[cfg(feature = "blake2b")] + { + let mut blake2b_v = calls_helper! { + blake2b_10b_10k => blake2b_10b_10k, + blake2b_10kib_10k => blake2b_10kib_10k + }; + + v.append(&mut blake2b_v); + } + + #[cfg(feature = "ecrecover")] + { + let mut ecrecover_v = calls_helper! { + ecrecover_10k => ecrecover_10k + }; + + v.append(&mut ecrecover_v); + } + // Measure the speed of all extern function calls. for (metric, method_name) in v { testbed = measure_function( @@ -774,10 +796,15 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), + #[cfg(feature = "ripemd160")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), + #[cfg(feature = "ripemd160")] ripemd160_byte: measured_to_gas(metric, &measured, ripemd160_byte), + #[cfg(feature = "blake2b")] blake2b_base: measured_to_gas(metric, &measured, blake2b_base), + #[cfg(feature = "blake2b")] blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), + #[cfg(feature = "ecrecover")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index b4db9d0ab48..1bbdfa0ddfc 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,12 +65,17 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); + #[cfg(ripemod160)] self.extract(ripemd160_10b_10k, ripemd160_base); + #[cfg(ripemod160)] self.extract(ripemd160_10kib_10k, ripemd160_byte); + #[cfg(feature = "blake2b")] self.extract(blake2b_10b_10k, blake2b_base); + #[cfg(feature = "blake2b")] self.extract(blake2b_10kib_10k, blake2b_byte); + #[cfg(feature = "ecrecover")] self.extract(ecrecover_10k, ecrecover_base); #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 135c7ff3745..766247527ad 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -47,8 +47,11 @@ extern "C" { fn sha256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); + #[cfg(feature = "ripemd160")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); + #[cfg(feature = "blake2b")] fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); + #[cfg(feature = "ecrecover")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # @@ -432,6 +435,7 @@ pub unsafe fn keccak512_10kib_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10b 10k times. #[no_mangle] +#[cfg(feature = "ripemd160")] pub unsafe fn ripemd160_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -443,6 +447,7 @@ pub unsafe fn ripemd160_10b_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10kib 10k times. #[no_mangle] +#[cfg(feature = "ripemd160")] pub unsafe fn ripemd160_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -455,6 +460,7 @@ pub unsafe fn ripemd160_10kib_10k() { // so we are okay overcharging it. // Compute blake2b on 10b 10k times. #[no_mangle] +#[cfg(feature = "blake2b")] pub unsafe fn blake2b_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -466,6 +472,7 @@ pub unsafe fn blake2b_10b_10k() { // so we are okay overcharging it. // Compute blake2b on 10kib 10k times. #[no_mangle] +#[cfg(feature = "blake2b")] pub unsafe fn blake2b_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -478,6 +485,7 @@ pub unsafe fn blake2b_10kib_10k() { // so we are okay overcharging it. // Compute ecrecover 10k times. #[no_mangle] +#[cfg(feature = "ecrecover")] pub unsafe fn ecrecover_10k() { let hash = [0u8; 32]; let signature = [0u8; 65]; From acb144005fc6ad16536d1e700813c3534b75fc7f Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 11 Mar 2021 12:28:14 +0700 Subject: [PATCH 012/134] fix nightly compile --- runtime/near-vm-runner/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index 580364a1576..38d338ba0f3 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -57,7 +57,6 @@ wasmer1_default = [] lightbeam = ["wasmtime/lightbeam"] no_cpu_compatibility_checks = [] protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm", "crypto_extras"] -evm_crypto_extras = ["crypto_extras"] crypto_extras = ["ripemd160", "blake2b", "ecrecover"] # cryptography extras From 773d81843136bd3eeb0d255c9ec9f1b37a21fc29 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 11 Mar 2021 12:43:10 +0700 Subject: [PATCH 013/134] cargo fmt --- core/primitives-core/src/config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 13a33fc3920..70d44bc2b91 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -374,11 +374,11 @@ impl Default for ExtCostsConfig { #[cfg(feature = "ripemd160")] ripemd160_base: SAFETY_MULTIPLIER * 1513656750, // TODO #[cfg(feature = "ripemd160")] - ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO + ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO #[cfg(feature = "blake2b")] - blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO + blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO #[cfg(feature = "blake2b")] - blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO + blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO #[cfg(feature = "ecrecover")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, From bdc04950777e2dcd77b17a3ac1f7db7c65e94d62 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 11 Mar 2021 12:51:58 +0700 Subject: [PATCH 014/134] fix two ripemd160 missing feature gates --- runtime/runtime-params-estimator/src/ext_costs_generator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 1bbdfa0ddfc..8d452a2fb54 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,9 +65,9 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); - #[cfg(ripemod160)] + #[cfg(feature = "ripemd160")] self.extract(ripemd160_10b_10k, ripemd160_base); - #[cfg(ripemod160)] + #[cfg(feature = "ripemd160")] self.extract(ripemd160_10kib_10k, ripemd160_byte); #[cfg(feature = "blake2b")] From b55fa0f043be589525c1ad2c60535b62d3abc353 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 12 Mar 2021 12:08:30 +0700 Subject: [PATCH 015/134] rename crypto_extras feature to protocol_feature equivalents --- core/primitives-core/Cargo.toml | 6 +-- core/primitives-core/src/config.rs | 50 +++++++++---------- runtime/near-vm-logic/src/logic.rs | 7 +-- runtime/near-vm-logic/tests/test_miscs.rs | 6 +-- runtime/near-vm-runner/Cargo.toml | 11 ++-- runtime/runtime-params-estimator/Cargo.toml | 11 ++-- runtime/runtime-params-estimator/src/cases.rs | 14 +++--- .../src/ext_costs_generator.rs | 10 ++-- .../test-contract/src/lib.rs | 16 +++--- 9 files changed, 65 insertions(+), 66 deletions(-) diff --git a/core/primitives-core/Cargo.toml b/core/primitives-core/Cargo.toml index ff09d4753cc..a1dc94b1243 100644 --- a/core/primitives-core/Cargo.toml +++ b/core/primitives-core/Cargo.toml @@ -31,6 +31,6 @@ protocol_feature_alt_bn128 = [] protocol_feature_tx_size_limit = [] # cryptography extras -ripemd160 = [] -blake2b = [] -ecrecover = [] +protocol_feature_ripemd160 = [] +protocol_feature_blake2b = [] +protocol_feature_ecrecover = [] diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 70d44bc2b91..72a6bb68210 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -224,21 +224,21 @@ pub struct ExtCostsConfig { pub keccak512_byte: Gas, /// Cost of getting ripemd160 base - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] pub ripemd160_base: Gas, /// Cost of getting ripemd160 per byte - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] pub ripemd160_byte: Gas, /// Cost of getting blake2b base - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] pub blake2b_base: Gas, /// Cost of getting blake2b per byte - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] pub blake2b_byte: Gas, /// Cost of calling ecrecover - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] pub ecrecover_base: Gas, /// Cost for calling logging. @@ -371,15 +371,15 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_base: SAFETY_MULTIPLIER * 1513656750, // TODO - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -451,15 +451,15 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_base: 0, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_byte: 0, - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_base: 0, - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_byte: 0, - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -532,15 +532,15 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_base, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_byte, - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_base, - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_byte, - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] ecrecover_base, log_base, log_byte, @@ -666,15 +666,15 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_base => config.ripemd160_base, - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_byte => config.ripemd160_byte, - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_base => config.blake2b_base, - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_byte => config.blake2b_byte, - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 1c8e31a533d..8832ec7bd40 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -4,6 +4,7 @@ use crate::gas_counter::GasCounter; use crate::types::{PromiseIndex, PromiseResult, ReceiptIndex, ReturnData}; use crate::utils::split_method_names; use crate::ValuePtr; +use blake2::crypto_mac::Mac; use byteorder::ByteOrder; use near_primitives::checked_feature; use near_primitives::version::is_implicit_account_creation_enabled; @@ -961,7 +962,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_byte * num_bytes` - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -983,7 +984,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(blake2b_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -1009,7 +1010,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] pub fn ecrecover( &mut self, hash_ptr: u64, diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 448f50f9ee2..9a7ff29784a 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -532,7 +532,7 @@ fn test_keccak512() { } #[test] -#[cfg(feature = "ripemd160")] +#[cfg(feature = "protocol_feature_ripemd160")] fn test_ripemd160() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -562,7 +562,7 @@ fn test_ripemd160() { } #[test] -#[cfg(feature = "blake2b")] +#[cfg(feature = "protocol_feature_blake2b")] fn test_blake2b() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -597,7 +597,7 @@ fn test_blake2b() { } #[test] -#[cfg(feature = "ecrecover")] +#[cfg(feature = "protocol_feature_ecrecover")] fn test_ecrecover() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index 38d338ba0f3..0797ef949f7 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -56,13 +56,12 @@ wasmer1_default = [] lightbeam = ["wasmtime/lightbeam"] no_cpu_compatibility_checks = [] -protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm", "crypto_extras"] -crypto_extras = ["ripemd160", "blake2b", "ecrecover"] - +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm", "protocol_feature_crypto_extras"] +protocol_feature_crypto_extras = ["protocol_feature_ripemd160", "protocol_feature_blake2b", "protocol_feature_ecrecover"] # cryptography extras -ripemd160 = [] -blake2b = [] -ecrecover = [] +protocol_feature_ripemd160 = [] +protocol_feature_blake2b = [] +protocol_feature_ecrecover = [] no_cache = [] diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index 1a5f9ffec92..0f8e6e0a7e0 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -70,10 +70,9 @@ protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-primitives/protocol_feature_evm", "testlib/protocol_feature_evm", - "crypto_extras"] -crypto_extras = ["ripemd160", "blake2b", "ecrecover"] - + "protocol_feature_crypto_extras"] +protocol_feature_crypto_extras = ["protocol_feature_ripemd160", "protocol_feature_blake2b", "protocol_feature_ecrecover"] # cryptography extras -ripemd160 = [] -blake2b = [] -ecrecover = [] +protocol_feature_ripemd160 = [] +protocol_feature_blake2b = [] +protocol_feature_ecrecover = [] diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index ceb9246cae6..673ddbf14bc 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -624,7 +624,7 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon v.append(&mut ripemd_v); } - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] { let mut blake2b_v = calls_helper! { blake2b_10b_10k => blake2b_10b_10k, @@ -634,7 +634,7 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon v.append(&mut blake2b_v); } - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] { let mut ecrecover_v = calls_helper! { ecrecover_10k => ecrecover_10k @@ -796,15 +796,15 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] ripemd160_byte: measured_to_gas(metric, &measured, ripemd160_byte), - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_base: measured_to_gas(metric, &measured, blake2b_base), - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 8d452a2fb54..9a56c200281 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,17 +65,17 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] self.extract(ripemd160_10b_10k, ripemd160_base); - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] self.extract(ripemd160_10kib_10k, ripemd160_byte); - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] self.extract(blake2b_10b_10k, blake2b_base); - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] self.extract(blake2b_10kib_10k, blake2b_byte); - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] self.extract(ecrecover_10k, ecrecover_base); #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 766247527ad..ee9bdf282b1 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -47,11 +47,11 @@ extern "C" { fn sha256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "ripemd160")] + #[cfg(feature = "protocol_feature_ripemd160")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "blake2b")] + #[cfg(feature = "protocol_feature_blake2b")] fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "ecrecover")] + #[cfg(feature = "protocol_feature_ecrecover")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # @@ -435,7 +435,7 @@ pub unsafe fn keccak512_10kib_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10b 10k times. #[no_mangle] -#[cfg(feature = "ripemd160")] +#[cfg(feature = "protocol_feature_ripemd160")] pub unsafe fn ripemd160_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -447,7 +447,7 @@ pub unsafe fn ripemd160_10b_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10kib 10k times. #[no_mangle] -#[cfg(feature = "ripemd160")] +#[cfg(feature = "protocol_feature_ripemd160")] pub unsafe fn ripemd160_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -460,7 +460,7 @@ pub unsafe fn ripemd160_10kib_10k() { // so we are okay overcharging it. // Compute blake2b on 10b 10k times. #[no_mangle] -#[cfg(feature = "blake2b")] +#[cfg(feature = "protocol_feature_blake2b")] pub unsafe fn blake2b_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -472,7 +472,7 @@ pub unsafe fn blake2b_10b_10k() { // so we are okay overcharging it. // Compute blake2b on 10kib 10k times. #[no_mangle] -#[cfg(feature = "blake2b")] +#[cfg(feature = "protocol_feature_blake2b")] pub unsafe fn blake2b_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -485,7 +485,7 @@ pub unsafe fn blake2b_10kib_10k() { // so we are okay overcharging it. // Compute ecrecover 10k times. #[no_mangle] -#[cfg(feature = "ecrecover")] +#[cfg(feature = "protocol_feature_ecrecover")] pub unsafe fn ecrecover_10k() { let hash = [0u8; 32]; let signature = [0u8; 65]; From e6c389fcde05a3c61ef732f29a551dce70bb4da4 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 19 Mar 2021 11:37:38 +0700 Subject: [PATCH 016/134] change repo to our git --- Cargo.lock | 3 +-- core/crypto/Cargo.toml | 2 +- runtime/near-vm-logic/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8ed39a6dec..41a2ec40c8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -532,8 +532,7 @@ dependencies = [ [[package]] name = "blake2" version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4" +source = "git+https://github.com/near/near-blake2.git#bc8a58ab1188f6fd4de895920f81137bf710a3be" dependencies = [ "crypto-mac 0.8.0", "digest 0.9.0", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index 924c9089dce..48c400e4509 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = "0.9.1" +blake2 = { git = "https://github.com/near/near-blake2.git" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index a17a9e4d39a..6b02f144e94 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { version = "0.9.1", optional = true } +blake2 = { git = "https://github.com/near/near-blake2.git", version = "0.9.1", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" From fd0022a32efe1cba336babff378f5cadf51a68ff Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 19 Mar 2021 11:45:18 +0700 Subject: [PATCH 017/134] put everything under protocol_feature_evm --- core/primitives-core/Cargo.toml | 5 -- core/primitives-core/src/config.rs | 50 +++++++++---------- runtime/near-vm-logic/src/logic.rs | 6 +-- runtime/near-vm-logic/tests/test_miscs.rs | 6 +-- runtime/near-vm-runner/Cargo.toml | 7 +-- runtime/runtime-params-estimator/Cargo.toml | 8 +-- runtime/runtime-params-estimator/src/cases.rs | 21 +++++--- .../src/ext_costs_generator.rs | 10 ++-- .../test-contract/src/lib.rs | 16 +++--- 9 files changed, 60 insertions(+), 69 deletions(-) diff --git a/core/primitives-core/Cargo.toml b/core/primitives-core/Cargo.toml index a1dc94b1243..4c1880fdc6d 100644 --- a/core/primitives-core/Cargo.toml +++ b/core/primitives-core/Cargo.toml @@ -29,8 +29,3 @@ protocol_feature_add_account_versions = [] protocol_feature_evm = [] protocol_feature_alt_bn128 = [] protocol_feature_tx_size_limit = [] - -# cryptography extras -protocol_feature_ripemd160 = [] -protocol_feature_blake2b = [] -protocol_feature_ecrecover = [] diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 72a6bb68210..c596c68496a 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -224,21 +224,21 @@ pub struct ExtCostsConfig { pub keccak512_byte: Gas, /// Cost of getting ripemd160 base - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] pub ripemd160_base: Gas, /// Cost of getting ripemd160 per byte - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] pub ripemd160_byte: Gas, /// Cost of getting blake2b base - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] pub blake2b_base: Gas, /// Cost of getting blake2b per byte - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] pub blake2b_byte: Gas, /// Cost of calling ecrecover - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] pub ecrecover_base: Gas, /// Cost for calling logging. @@ -371,15 +371,15 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_base: SAFETY_MULTIPLIER * 1513656750, // TODO - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -451,15 +451,15 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_base: 0, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_byte: 0, - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_base: 0, - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_byte: 0, - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -532,15 +532,15 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_base, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_byte, - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_base, - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_byte, - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] ecrecover_base, log_base, log_byte, @@ -666,15 +666,15 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_base => config.ripemd160_base, - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_byte => config.ripemd160_byte, - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_base => config.blake2b_base, - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_byte => config.blake2b_byte, - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 8832ec7bd40..7466948916e 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -962,7 +962,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_byte * num_bytes` - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -984,7 +984,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(blake2b_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -1010,7 +1010,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] pub fn ecrecover( &mut self, hash_ptr: u64, diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 9a7ff29784a..b2b0688f360 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -532,7 +532,7 @@ fn test_keccak512() { } #[test] -#[cfg(feature = "protocol_feature_ripemd160")] +#[cfg(feature = "protocol_feature_evm")] fn test_ripemd160() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -562,7 +562,7 @@ fn test_ripemd160() { } #[test] -#[cfg(feature = "protocol_feature_blake2b")] +#[cfg(feature = "protocol_feature_evm")] fn test_blake2b() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -597,7 +597,7 @@ fn test_blake2b() { } #[test] -#[cfg(feature = "protocol_feature_ecrecover")] +#[cfg(feature = "protocol_feature_evm")] fn test_ecrecover() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index 0797ef949f7..64bac7e6c94 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -56,12 +56,7 @@ wasmer1_default = [] lightbeam = ["wasmtime/lightbeam"] no_cpu_compatibility_checks = [] -protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm", "protocol_feature_crypto_extras"] -protocol_feature_crypto_extras = ["protocol_feature_ripemd160", "protocol_feature_blake2b", "protocol_feature_ecrecover"] -# cryptography extras -protocol_feature_ripemd160 = [] -protocol_feature_blake2b = [] -protocol_feature_ecrecover = [] +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-evm-runner/protocol_feature_evm"] no_cache = [] diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index 0f8e6e0a7e0..e899ff5569d 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -69,10 +69,4 @@ protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "near-chain-configs/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-primitives/protocol_feature_evm", - "testlib/protocol_feature_evm", - "protocol_feature_crypto_extras"] -protocol_feature_crypto_extras = ["protocol_feature_ripemd160", "protocol_feature_blake2b", "protocol_feature_ecrecover"] -# cryptography extras -protocol_feature_ripemd160 = [] -protocol_feature_blake2b = [] -protocol_feature_ecrecover = [] + "testlib/protocol_feature_evm"] diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 673ddbf14bc..00e7a6f5f21 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -621,10 +621,17 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon data_receipt_100kib_1000 => data_receipt_100kib_1000 }; + #[cfg(feature = "protocol_feature_evm")] + { + let mut ripemd_v = calls_helper! { + ripemd160_10b_10k => ripemd160_10b_10k, + ripemd160_10kib_10k => ripemd160_10kib_10k + }; + v.append(&mut ripemd_v); } - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] { let mut blake2b_v = calls_helper! { blake2b_10b_10k => blake2b_10b_10k, @@ -634,7 +641,7 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon v.append(&mut blake2b_v); } - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] { let mut ecrecover_v = calls_helper! { ecrecover_10k => ecrecover_10k @@ -796,15 +803,15 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] ripemd160_byte: measured_to_gas(metric, &measured, ripemd160_byte), - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_base: measured_to_gas(metric, &measured, blake2b_base), - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 9a56c200281..5ee8d213ad5 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,17 +65,17 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] self.extract(ripemd160_10b_10k, ripemd160_base); - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] self.extract(ripemd160_10kib_10k, ripemd160_byte); - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] self.extract(blake2b_10b_10k, blake2b_base); - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] self.extract(blake2b_10kib_10k, blake2b_byte); - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] self.extract(ecrecover_10k, ecrecover_base); #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index ee9bdf282b1..27741b69365 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -47,11 +47,11 @@ extern "C" { fn sha256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "protocol_feature_ripemd160")] + #[cfg(feature = "protocol_feature_evm")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "protocol_feature_blake2b")] + #[cfg(feature = "protocol_feature_evm")] fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "protocol_feature_ecrecover")] + #[cfg(feature = "protocol_feature_evm")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # @@ -435,7 +435,7 @@ pub unsafe fn keccak512_10kib_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10b 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_ripemd160")] +#[cfg(feature = "protocol_feature_evm")] pub unsafe fn ripemd160_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -447,7 +447,7 @@ pub unsafe fn ripemd160_10b_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10kib 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_ripemd160")] +#[cfg(feature = "protocol_feature_evm")] pub unsafe fn ripemd160_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -460,7 +460,7 @@ pub unsafe fn ripemd160_10kib_10k() { // so we are okay overcharging it. // Compute blake2b on 10b 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_blake2b")] +#[cfg(feature = "protocol_feature_evm")] pub unsafe fn blake2b_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -472,7 +472,7 @@ pub unsafe fn blake2b_10b_10k() { // so we are okay overcharging it. // Compute blake2b on 10kib 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_blake2b")] +#[cfg(feature = "protocol_feature_evm")] pub unsafe fn blake2b_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -485,7 +485,7 @@ pub unsafe fn blake2b_10kib_10k() { // so we are okay overcharging it. // Compute ecrecover 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_ecrecover")] +#[cfg(feature = "protocol_feature_evm")] pub unsafe fn ecrecover_10k() { let hash = [0u8; 32]; let signature = [0u8; 65]; From c1d77f082c65c51daefbc0784f21d4b95da9f399 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 19 Mar 2021 14:00:38 +0700 Subject: [PATCH 018/134] point to alternative blake2 branch temporarily --- Cargo.lock | 14 ++++++++++++-- runtime/near-vm-logic/Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41a2ec40c8a..9719f90071c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -529,6 +529,16 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.9.1" +source = "git+https://github.com/near/near-blake2.git?branch=f-standard-out#a930c335a3b04814c37ef2a33b4a0f26ae6e047b" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + [[package]] name = "blake2" version = "0.9.1" @@ -3143,7 +3153,7 @@ name = "near-crypto" version = "0.1.0" dependencies = [ "arrayref", - "blake2", + "blake2 0.9.1 (git+https://github.com/near/near-blake2.git)", "borsh", "bs58", "c2-chacha", @@ -3601,7 +3611,7 @@ name = "near-vm-logic" version = "3.0.0" dependencies = [ "base64 0.13.0", - "blake2", + "blake2 0.9.1 (git+https://github.com/near/near-blake2.git?branch=f-standard-out)", "borsh", "bs58", "byteorder", diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 6b02f144e94..7003917f398 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { git = "https://github.com/near/near-blake2.git", version = "0.9.1", optional = true } +blake2 = { git = "https://github.com/near/near-blake2.git", branch = "f-standard-out", version = "0.9.1", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" From f7ec5b18c8c30866aefaaeff438fbad35aadff2b Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 19 Mar 2021 14:00:52 +0700 Subject: [PATCH 019/134] Add blake2b f function --- runtime/near-vm-logic/src/logic.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 7466948916e..88265169d99 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -23,6 +23,7 @@ use near_vm_errors::{HostError, VMLogicError}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::mem::size_of; +use std::convert::TryFrom; pub type Result = ::std::result::Result; @@ -998,6 +999,25 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } + #[cfg(feature = "protocol_feature_evm")] + pub fn blake2b_f(&mut self, rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64) -> Result<()> { + use blake2; + + let rounds = self.memory_get_u32(rounds_ptr)?; + for _ in 0..rounds { + self.gas_counter.pay_base(blake2b_f_base)?; + } + let h = <[u64; 8]>::try_from(self.memory_get_vec_u64(h_ptr, 8)?)?; + let m = <[u64; 16]>::try_from(self.memory_get_vec_u64(m_ptr, 16)?)?; + let t = <[u64; 2]>::try_from(self.memory_get_vec_u64(t_ptr, 2)?)?; + let f: bool = self.memory_get_u8(f_ptr)? != 0; + + let value = blake2::blake2b_f(rounds, h, m, t, f); + self.internal_write_register(register_id, value.as_slice().to_vec()); + + Ok(()) + } + /// Recovers an ECDSA signer address and returns it into `register_id`. /// /// # Errors From 598b0c537cc21e9018bd703c1015dd622c13384f Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 23 Mar 2021 12:12:11 +0700 Subject: [PATCH 020/134] add blake2b_f to config --- core/primitives-core/src/config.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index c596c68496a..1823d1e4d24 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -236,6 +236,12 @@ pub struct ExtCostsConfig { /// Cost of getting blake2b per byte #[cfg(feature = "protocol_feature_evm")] pub blake2b_byte: Gas, + /// Cost of calculating blake2b F compression base + #[cfg(feature = "protocol_feature_evm")] + pub blake2b_f_base: Gas, + /// Cost of getting blake2b F compression per byte + #[cfg(feature = "protocol_feature_evm")] + pub blake2b_f_byte: Gas, /// Cost of calling ecrecover #[cfg(feature = "protocol_feature_evm")] @@ -380,6 +386,10 @@ impl Default for ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO #[cfg(feature = "protocol_feature_evm")] + blake2b_f_base: SAFETY_MULTIPLIER * 1513656750, // TODO + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_byte: SAFETY_MULTIPLIER * 8039117, // TODO + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -460,6 +470,10 @@ impl ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_byte: 0, #[cfg(feature = "protocol_feature_evm")] + blake2b_f_base: 0, + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_byte: 0, + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -541,6 +555,10 @@ pub enum ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_byte, #[cfg(feature = "protocol_feature_evm")] + blake2b_f_base, + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_byte, + #[cfg(feature = "protocol_feature_evm")] ecrecover_base, log_base, log_byte, From 16a32c8cf30ee0b187123a307818663c7ea33ab9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 23 Mar 2021 13:15:33 +0700 Subject: [PATCH 021/134] post rebase fixes --- runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/logic.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 7003917f398..3c891886433 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -37,7 +37,7 @@ serde_json = {version= "1", features= ["preserve_order"]} [features] default = [] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "blake2"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 88265169d99..b54b13e3d9c 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -4,7 +4,6 @@ use crate::gas_counter::GasCounter; use crate::types::{PromiseIndex, PromiseResult, ReceiptIndex, ReturnData}; use crate::utils::split_method_names; use crate::ValuePtr; -use blake2::crypto_mac::Mac; use byteorder::ByteOrder; use near_primitives::checked_feature; use near_primitives::version::is_implicit_account_creation_enabled; @@ -23,7 +22,6 @@ use near_vm_errors::{HostError, VMLogicError}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::mem::size_of; -use std::convert::TryFrom; pub type Result = ::std::result::Result; @@ -987,12 +985,12 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` #[cfg(feature = "protocol_feature_evm")] pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { + use blake2::{Blake2b, Digest, crypto_mac::Mac}; + self.gas_counter.pay_base(blake2b_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; self.gas_counter.pay_per_byte(blake2b_byte, value.len() as u64)?; - use blake2::{Blake2b, Digest}; - let mut hasher = Blake2b::new(); hasher.update(&value); let value_hash = hasher.finalize(); From e2b5e5992efb71750f8ea3f13fc9c1d9fc7e7d8c Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 23 Mar 2021 14:13:33 +0700 Subject: [PATCH 022/134] wrap all ext_costs in evm feature --- .../src/ext_costs_generator.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 5ee8d213ad5..f2f84992fe8 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -66,17 +66,17 @@ impl ExtCostsGenerator { self.extract(keccak512_10kib_10k, keccak512_byte); #[cfg(feature = "protocol_feature_evm")] - self.extract(ripemd160_10b_10k, ripemd160_base); - #[cfg(feature = "protocol_feature_evm")] - self.extract(ripemd160_10kib_10k, ripemd160_byte); + { + self.extract(ripemd160_10b_10k, ripemd160_base); + self.extract(ripemd160_10kib_10k, ripemd160_byte); - #[cfg(feature = "protocol_feature_evm")] - self.extract(blake2b_10b_10k, blake2b_base); - #[cfg(feature = "protocol_feature_evm")] - self.extract(blake2b_10kib_10k, blake2b_byte); + self.extract(blake2b_10b_10k, blake2b_base); + self.extract(blake2b_10kib_10k, blake2b_byte); + self.extract(blake2b_f_10b_10k, blake2b_f_base); + self.extract(blake2b_f_10kib_10k, blake2b_f_byte); - #[cfg(feature = "protocol_feature_evm")] - self.extract(ecrecover_10k, ecrecover_base); + self.extract(ecrecover_10k, ecrecover_base); + } #[cfg(feature = "protocol_feature_alt_bn128")] { From ca3e329c69ddb25f1c864bb3d0bd1322ad4ae953 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 23 Mar 2021 14:14:17 +0700 Subject: [PATCH 023/134] add blake_2b_f to runtime estimator --- .../test-contract/src/lib.rs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 27741b69365..b2b87970613 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -52,6 +52,8 @@ extern "C" { #[cfg(feature = "protocol_feature_evm")] fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); #[cfg(feature = "protocol_feature_evm")] + fn blake2b_f(rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64); + #[cfg(feature = "protocol_feature_evm")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # @@ -480,6 +482,49 @@ pub unsafe fn blake2b_10kib_10k() { } } +/// Function to measure the `blake2b_f_base` and `blake2b_byte`. Also measures `base`, +/// `write_register_base`, and `write_register_byte`. This is done at cost per +/// round. +#[no_mangle] +#[cfg(feature = "protocol_feature_evm")] +pub unsafe fn blake2b_f_1r_10k() { + let rounds: u32 = 1; + let hash: [u64; 8] = [ + 0x6a09e667f2bdc948, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, + ]; + let m: [u64; 16] = [ + 0x0000000000636261, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]; + let t: [u64; 2] = [3, 0]; + let f = true; + + for _ in 0..10_000 { + blake2b_f(rounds.as_ptr(), hash.as_ptr() as u64, m.as_ptr() as u64, t.as_ptr() as u64, f.as_ptr() as u64, 0); + } +} + // Function to measure `ecrecover_base`. Also measures `base`, `write_register_base`, and // `write_register_byte`. However `ecrecover` computation is more expensive than register writing // so we are okay overcharging it. From 188b9b82d99eadf5162600e25e18c0bd463594ae Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 23 Mar 2021 14:14:25 +0700 Subject: [PATCH 024/134] cargo fmt --- runtime/near-vm-logic/src/logic.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index b54b13e3d9c..72f662b12c3 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -985,7 +985,7 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` #[cfg(feature = "protocol_feature_evm")] pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { - use blake2::{Blake2b, Digest, crypto_mac::Mac}; + use blake2::{crypto_mac::Mac, Blake2b, Digest}; self.gas_counter.pay_base(blake2b_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -998,7 +998,15 @@ impl<'a> VMLogic<'a> { } #[cfg(feature = "protocol_feature_evm")] - pub fn blake2b_f(&mut self, rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64) -> Result<()> { + pub fn blake2b_f( + &mut self, + rounds_ptr: u64, + h_ptr: u64, + m_ptr: u64, + t_ptr: u64, + f_ptr: u64, + register_id: u64, + ) -> Result<()> { use blake2; let rounds = self.memory_get_u32(rounds_ptr)?; From b0236f540f6bf8048dd8f36ba8c5a51072826a4b Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 13:34:41 +0700 Subject: [PATCH 025/134] add new hash algos to feature --- runtime/near-vm-logic/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 3c891886433..246e09ef172 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -37,7 +37,7 @@ serde_json = {version= "1", features= ["preserve_order"]} [features] default = [] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "blake2"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "blake2", "ripemd160", "libsecp256k1"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] From 8945af79e6d6f514e552febbdd216f8ae3ad5e7a Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 13:35:33 +0700 Subject: [PATCH 026/134] add vm-logic test for blake2b_f --- core/primitives-core/src/config.rs | 4 ++ runtime/near-vm-logic/src/logic.rs | 17 ++--- runtime/near-vm-logic/tests/test_miscs.rs | 78 ++++++++++++++++++++++- 3 files changed, 90 insertions(+), 9 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 1823d1e4d24..bdfec2c950e 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -693,6 +693,10 @@ impl ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_byte => config.blake2b_byte, #[cfg(feature = "protocol_feature_evm")] + blake2b_f_base => config.blake2b_f_base, + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_byte => config.blake2b_f_byte, + #[cfg(feature = "protocol_feature_evm")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 72f662b12c3..985fcdd48f7 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -985,7 +985,7 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` #[cfg(feature = "protocol_feature_evm")] pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { - use blake2::{crypto_mac::Mac, Blake2b, Digest}; + use blake2::{Blake2b, Digest}; self.gas_counter.pay_base(blake2b_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; @@ -1007,21 +1007,22 @@ impl<'a> VMLogic<'a> { f_ptr: u64, register_id: u64, ) -> Result<()> { - use blake2; + use std::convert::TryFrom; let rounds = self.memory_get_u32(rounds_ptr)?; for _ in 0..rounds { self.gas_counter.pay_base(blake2b_f_base)?; } - let h = <[u64; 8]>::try_from(self.memory_get_vec_u64(h_ptr, 8)?)?; - let m = <[u64; 16]>::try_from(self.memory_get_vec_u64(m_ptr, 16)?)?; - let t = <[u64; 2]>::try_from(self.memory_get_vec_u64(t_ptr, 2)?)?; + let h = + <[u64; 8]>::try_from(self.memory_get_vec_u64(h_ptr, 8)?).expect("vec bytes conversion"); + let m = <[u64; 16]>::try_from(self.memory_get_vec_u64(m_ptr, 16)?) + .expect("vec bytes conversion"); + let t = + <[u64; 2]>::try_from(self.memory_get_vec_u64(t_ptr, 2)?).expect("vec bytes conversion"); let f: bool = self.memory_get_u8(f_ptr)? != 0; let value = blake2::blake2b_f(rounds, h, m, t, f); - self.internal_write_register(register_id, value.as_slice().to_vec()); - - Ok(()) + self.internal_write_register(register_id, value.as_slice().to_vec()) } /// Recovers an ECDSA signer address and returns it into `register_id`. diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index b2b0688f360..b5062a584dc 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -1,6 +1,5 @@ use fixtures::get_context; use helpers::*; -use hex_literal::hex; use near_vm_errors::HostError; use near_vm_logic::ExtCosts; use vm_logic_builder::VMLogicBuilder; @@ -596,9 +595,86 @@ fn test_blake2b() { }); } +#[test] +#[cfg(feature = "protocol_feature_evm")] +fn test_blake2b_f() { + let mut logic_builder = VMLogicBuilder::default(); + let mut logic = logic_builder.build(get_context(vec![], false)); + + let rounds: [u8; 4] = 1_u32.to_le_bytes(); + let h: [u64; 8] = [ + 0x6a09e667f2bdc948, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, + ]; + let m: [u64; 16] = [ + 0x0000000000636261, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]; + let t: [u64; 2] = [3, 0]; + let f_bool: [u8; 1] = 1_u8.to_le_bytes(); + logic + .blake2b_f( + rounds.as_ptr() as u64, + h.as_ptr() as u64, + m.as_ptr() as u64, + t.as_ptr() as u64, + f_bool.as_ptr() as u64, + 0, + ) + .unwrap(); + + let res = &vec![0u8; 64]; + logic.read_register(0, res.as_ptr() as _).expect("OK"); + assert_eq!( + res, + &[ + 0xB6, 0x3A, 0x38, 0x0C, 0xB2, 0x89, 0x7D, 0x52, 0x19, 0x94, 0xA8, 0x52, 0x34, 0xEE, + 0x2C, 0x18, 0x1B, 0x5F, 0x84, 0x4D, 0x2C, 0x62, 0x4C, 0x00, 0x26, 0x77, 0xE9, 0x70, + 0x34, 0x49, 0xD2, 0xFB, 0xA5, 0x51, 0xB3, 0xA8, 0x33, 0x3B, 0xCD, 0xF5, 0xF2, 0xF7, + 0xE0, 0x89, 0x93, 0xD5, 0x39, 0x23, 0xDE, 0x3D, 0x64, 0xFC, 0xC6, 0x8C, 0x03, 0x4E, + 0x71, 0x7B, 0x92, 0x93, 0xFE, 0xD7, 0xA4, 0x21 + ], + ); + + assert_costs(map! { + ExtCosts::base: 1, + ExtCosts::blake2b_f_base: 1, + ExtCosts::read_register_base: 1, + ExtCosts::read_register_byte: 64, + ExtCosts::write_register_base: 1, + ExtCosts::write_register_byte: 64, + ExtCosts::read_memory_base: 5, + ExtCosts::read_memory_byte: 4 + 64 + 128 + 8 + 8 + 1, // 213 per EIP-152 + ExtCosts::write_memory_base: 1, + ExtCosts::write_memory_byte: 64, + }); +} + #[test] #[cfg(feature = "protocol_feature_evm")] fn test_ecrecover() { + use hex_literal::hex; + let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); From 78ec8615e6caef693def6b0c841ce257cf285f09 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 14:29:55 +0700 Subject: [PATCH 027/134] fix derive formatting --- chain/rosetta-rpc/src/models.rs | 4 +--- core/primitives/src/types.rs | 12 +++--------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/chain/rosetta-rpc/src/models.rs b/chain/rosetta-rpc/src/models.rs index 7b3cf198d1c..851b423944b 100644 --- a/chain/rosetta-rpc/src/models.rs +++ b/chain/rosetta-rpc/src/models.rs @@ -935,9 +935,7 @@ pub(crate) struct SubNetworkIdentifier { /// The timestamp of the block in milliseconds since the Unix Epoch. The /// timestamp is stored in milliseconds because some blockchains produce blocks /// more often than once a second. -#[derive( - Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, Apiv2Schema, -)] +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, Apiv2Schema)] pub(crate) struct Timestamp(i64); /// Transactions contain an array of Operations that are attributable to the diff --git a/core/primitives/src/types.rs b/core/primitives/src/types.rs index 7da4e91d8cb..638c0855419 100644 --- a/core/primitives/src/types.rs +++ b/core/primitives/src/types.rs @@ -53,9 +53,7 @@ pub struct AccountInfo { /// /// NOTE: Currently, this type is only used in the view_client and RPC to be able to transparently /// pretty-serialize the bytes arrays as base64-encoded strings (see `serialize.rs`). -#[derive( - Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize, -)] +#[derive(Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize)] #[as_ref(forward)] pub struct StoreKey(Vec); @@ -63,9 +61,7 @@ pub struct StoreKey(Vec); /// /// NOTE: Currently, this type is only used in the view_client and RPC to be able to transparently /// pretty-serialize the bytes arrays as base64-encoded strings (see `serialize.rs`). -#[derive( - Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize, -)] +#[derive(Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize)] #[as_ref(forward)] pub struct StoreValue(Vec); @@ -74,9 +70,7 @@ pub struct StoreValue(Vec); /// NOTE: The main reason for this to exist (except the type-safety) is that the value is /// transparently serialized and deserialized as a base64-encoded string when serde is used /// (serde_json). -#[derive( - Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize, -)] +#[derive(Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize)] #[as_ref(forward)] pub struct FunctionArgs(Vec); From 075e6beeb724293fb1c71a2920114556b8b1380c Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 14:36:35 +0700 Subject: [PATCH 028/134] use same blake2 library --- Cargo.lock | 14 ++------------ core/crypto/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9719f90071c..d1d4d56b873 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -539,16 +539,6 @@ dependencies = [ "opaque-debug 0.3.0", ] -[[package]] -name = "blake2" -version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git#bc8a58ab1188f6fd4de895920f81137bf710a3be" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "blake2b_simd" version = "0.5.11" @@ -3153,7 +3143,7 @@ name = "near-crypto" version = "0.1.0" dependencies = [ "arrayref", - "blake2 0.9.1 (git+https://github.com/near/near-blake2.git)", + "blake2", "borsh", "bs58", "c2-chacha", @@ -3611,7 +3601,7 @@ name = "near-vm-logic" version = "3.0.0" dependencies = [ "base64 0.13.0", - "blake2 0.9.1 (git+https://github.com/near/near-blake2.git?branch=f-standard-out)", + "blake2", "borsh", "bs58", "byteorder", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index 48c400e4509..bfffe1842d8 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { git = "https://github.com/near/near-blake2.git" } +blake2 = { git = "https://github.com/near/near-blake2.git", branch = "f-standard-out", version = "0.9.1" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" From d53a580dcb241e7fa491da53b46b43328a93c7f8 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 14:45:09 +0700 Subject: [PATCH 029/134] change blake F tests to test 1 round --- runtime/runtime-params-estimator/src/cases.rs | 4 +--- runtime/runtime-params-estimator/src/ext_costs_generator.rs | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 00e7a6f5f21..56e52ea0931 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -207,9 +207,7 @@ pub enum Metric { #[cfg(feature = "protocol_feature_evm")] blake2b_10kib_10k, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_10b_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2b_f_10kib_10k, + blake2b_f_1r_10k, #[cfg(feature = "protocol_feature_evm")] ecrecover_10k, #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index f2f84992fe8..76ff47f13f7 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -72,8 +72,7 @@ impl ExtCostsGenerator { self.extract(blake2b_10b_10k, blake2b_base); self.extract(blake2b_10kib_10k, blake2b_byte); - self.extract(blake2b_f_10b_10k, blake2b_f_base); - self.extract(blake2b_f_10kib_10k, blake2b_f_byte); + self.extract(blake2b_f_1r_10k, blake2b_f_base); self.extract(ecrecover_10k, ecrecover_base); } From 8da8c495200b6305718507e13c186382062e54a4 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 14:45:25 +0700 Subject: [PATCH 030/134] fix blake f test --- runtime/runtime-params-estimator/src/cases.rs | 2 +- runtime/runtime-params-estimator/test-contract/src/lib.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 56e52ea0931..467f9052364 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -565,7 +565,7 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon config.block_sizes = vec![2]; // When adding new functions do not forget to rebuild the test contract by running `test-contract/build.sh`. - let v = calls_helper! { + let mut v = calls_helper! { cpu_ram_soak_test => cpu_ram_soak_test, base_1M => base_1M, read_memory_10b_10k => read_memory_10b_10k, diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index b2b87970613..213aaf76b36 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -488,8 +488,8 @@ pub unsafe fn blake2b_10kib_10k() { #[no_mangle] #[cfg(feature = "protocol_feature_evm")] pub unsafe fn blake2b_f_1r_10k() { - let rounds: u32 = 1; - let hash: [u64; 8] = [ + let rounds: [u8; 4] = 1_u32.to_le_bytes(); + let h: [u64; 8] = [ 0x6a09e667f2bdc948, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, @@ -518,10 +518,10 @@ pub unsafe fn blake2b_f_1r_10k() { 0x0000000000000000, ]; let t: [u64; 2] = [3, 0]; - let f = true; + let f: [u8; 1] = 1_u8.to_le_bytes(); for _ in 0..10_000 { - blake2b_f(rounds.as_ptr(), hash.as_ptr() as u64, m.as_ptr() as u64, t.as_ptr() as u64, f.as_ptr() as u64, 0); + blake2b_f(rounds.as_ptr() as u64, h.as_ptr() as u64, m.as_ptr() as u64, t.as_ptr() as u64, f.as_ptr() as u64, 0); } } From 9f3358c9343b7c75b561ac44f0e9a3a2395c1643 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 24 Mar 2021 15:27:18 +0700 Subject: [PATCH 031/134] cleanup calls_helper --- runtime/runtime-params-estimator/src/cases.rs | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 467f9052364..9f6ec189b9d 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -565,7 +565,7 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon config.block_sizes = vec![2]; // When adding new functions do not forget to rebuild the test contract by running `test-contract/build.sh`. - let mut v = calls_helper! { + let v = calls_helper! { cpu_ram_soak_test => cpu_ram_soak_test, base_1M => base_1M, read_memory_10b_10k => read_memory_10b_10k, @@ -590,6 +590,12 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon keccak256_10kib_10k => keccak256_10kib_10k, keccak512_10b_10k => keccak512_10b_10k, keccak512_10kib_10k => keccak512_10kib_10k, + #["protocol_feature_evm"] ripemd160_10b_10k => ripemd160_10b_10k, + #["protocol_feature_evm"] ripemd160_10kib_10k => ripemd160_10kib_10k, + #["protocol_feature_evm"] blake2b_10b_10k => blake2b_10b_10k, + #["protocol_feature_evm"] blake2b_10kib_10k => blake2b_10kib_10k, + #["protocol_feature_evm"] blake2b_f_1r_10k => blake2b_f_1r_10k, + #["protocol_feature_evm"] ecrecover_10k => ecrecover_10k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_1_1k => alt_bn128_g1_multiexp_1_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_10_1k => alt_bn128_g1_multiexp_10_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_sum_1_1k => alt_bn128_g1_sum_1_1k, @@ -619,35 +625,6 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon data_receipt_100kib_1000 => data_receipt_100kib_1000 }; - #[cfg(feature = "protocol_feature_evm")] - { - let mut ripemd_v = calls_helper! { - ripemd160_10b_10k => ripemd160_10b_10k, - ripemd160_10kib_10k => ripemd160_10kib_10k - }; - - v.append(&mut ripemd_v); - } - - #[cfg(feature = "protocol_feature_evm")] - { - let mut blake2b_v = calls_helper! { - blake2b_10b_10k => blake2b_10b_10k, - blake2b_10kib_10k => blake2b_10kib_10k - }; - - v.append(&mut blake2b_v); - } - - #[cfg(feature = "protocol_feature_evm")] - { - let mut ecrecover_v = calls_helper! { - ecrecover_10k => ecrecover_10k - }; - - v.append(&mut ecrecover_v); - } - // Measure the speed of all extern function calls. for (metric, method_name) in v { testbed = measure_function( From 5ac0d32f6d13f3f2c676e84b8c15dde96c3e943e Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 25 Mar 2021 11:34:30 +0700 Subject: [PATCH 032/134] add missing feature gated fields from ExtCostsConfig --- runtime/runtime-params-estimator/src/cases.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 9f6ec189b9d..df93d40585d 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -787,6 +787,10 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts #[cfg(feature = "protocol_feature_evm")] blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), #[cfg(feature = "protocol_feature_evm")] + blake2b_f_base: measured_to_gas(metric, &measured, blake2b_f_base), + #[cfg(feature = "protocol_feature_evm")] + blake2b_f_byte: measured_to_gas(metric, &measured, blake2b_f_byte), + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), From 1c9ba9185758e9dc7a6a97f04f996da7bb98a773 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 26 Mar 2021 11:55:49 +0700 Subject: [PATCH 033/134] add blake2b_f compression docs --- runtime/near-vm-logic/src/logic.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 985fcdd48f7..87f57de3c9b 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -997,6 +997,17 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } + /// The compression function of the blake2 algorithm. + /// + /// Takes as an argument the state vector "h", message block vector "m" (the + /// last block is padded with zeros to full block size, if required), 2w-bit + /// offset counter "t", and final block indicator flag "f". Local vector + /// v[0..15] is used in processing. F returns a new state vector. The number + /// of rounds, "r", is 12 for BLAKE2b and 10 for BLAKE2s. Rounds are + /// numbered from 0 to r - 1. + /// + /// # Cost + /// base + write_register_base + write_register_byte * 64 + blake2b_f_base #[cfg(feature = "protocol_feature_evm")] pub fn blake2b_f( &mut self, From 687202551b9f3ef6fec2766d1683fc8f73a46421 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 26 Mar 2021 11:56:13 +0700 Subject: [PATCH 034/134] remove unused `blake2b_f_byte` as sizes are fixed --- core/primitives-core/src/config.rs | 11 ----------- runtime/runtime-params-estimator/src/cases.rs | 2 -- 2 files changed, 13 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index bdfec2c950e..e825ab5cfd8 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -239,9 +239,6 @@ pub struct ExtCostsConfig { /// Cost of calculating blake2b F compression base #[cfg(feature = "protocol_feature_evm")] pub blake2b_f_base: Gas, - /// Cost of getting blake2b F compression per byte - #[cfg(feature = "protocol_feature_evm")] - pub blake2b_f_byte: Gas, /// Cost of calling ecrecover #[cfg(feature = "protocol_feature_evm")] @@ -388,8 +385,6 @@ impl Default for ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_f_base: SAFETY_MULTIPLIER * 1513656750, // TODO #[cfg(feature = "protocol_feature_evm")] - blake2b_f_byte: SAFETY_MULTIPLIER * 8039117, // TODO - #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -472,8 +467,6 @@ impl ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_f_base: 0, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_byte: 0, - #[cfg(feature = "protocol_feature_evm")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -557,8 +550,6 @@ pub enum ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_f_base, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_byte, - #[cfg(feature = "protocol_feature_evm")] ecrecover_base, log_base, log_byte, @@ -695,8 +686,6 @@ impl ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_f_base => config.blake2b_f_base, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_byte => config.blake2b_f_byte, - #[cfg(feature = "protocol_feature_evm")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index df93d40585d..c0ff51e2783 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -789,8 +789,6 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts #[cfg(feature = "protocol_feature_evm")] blake2b_f_base: measured_to_gas(metric, &measured, blake2b_f_base), #[cfg(feature = "protocol_feature_evm")] - blake2b_f_byte: measured_to_gas(metric, &measured, blake2b_f_byte), - #[cfg(feature = "protocol_feature_evm")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), From 6704cade618f9469d7259133886f6d7be0b02a37 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 26 Mar 2021 11:59:31 +0700 Subject: [PATCH 035/134] add missing blake2b_f to imports --- runtime/near-vm-runner/src/imports.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 5144088dbed..d5132c96501 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -223,6 +223,7 @@ wrapped_imports! { keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2b_f<[rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # From 36bbc375ce32400c97be9c87565e0811ebd6d2bf Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 26 Mar 2021 17:30:44 +0700 Subject: [PATCH 036/134] runtime estimator mod docs --- runtime/runtime-params-estimator/src/lib.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/runtime/runtime-params-estimator/src/lib.rs b/runtime/runtime-params-estimator/src/lib.rs index e72fde2f613..0c816cb58d0 100644 --- a/runtime/runtime-params-estimator/src/lib.rs +++ b/runtime/runtime-params-estimator/src/lib.rs @@ -1,19 +1,20 @@ -// Lists all cases that we want to measure. +/// Lists all cases that we want to measure. pub mod cases; -// Generates runtime fees from the measurements. +/// Generates runtime fees from the measurements. pub mod runtime_fees_generator; -// Generates external costs from the measurements. +/// Generates external costs from the measurements. pub mod ext_costs_generator; -// Runs a VM (Default: Wasmer) on the given contract and measures the time it takes to do a single operation. #[cfg(feature = "protocol_feature_evm")] +/// Generates the runtime fees for the EVM. pub mod evm_estimator; +/// Runs a VM (Default: Wasmer) on the given contract and measures the time it takes to do a single operation. pub mod vm_estimator; -// Collects and processes stats. Prints them on display, plots them, writes them into a file. +/// Collects and processes stats. Prints them on display, plots them, writes them into a file. pub mod stats; -// Encapsulates the runtime so that it can be run separately from the rest of the node. +/// Encapsulates the runtime so that it can be run separately from the rest of the node. pub mod testbed; -// Prepares transactions and feeds them to the testbed in batches. Performs the warm up, takes care -// of nonces. +/// Prepares transactions and feeds them to the testbed in batches. Performs the warm up, takes care +/// of nonces. pub mod testbed_runners; use std::path::Path; From e971fe3fe56e006329d5aaa7b8a16a11590d682c Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 19 May 2021 12:27:08 +0700 Subject: [PATCH 037/134] Add near-blake2 lib to near-crypto --- core/crypto/Cargo.toml | 2 +- core/crypto/blake2/CHANGELOG.md | 62 +++ core/crypto/blake2/Cargo.lock | 106 ++++ core/crypto/blake2/Cargo.toml | 30 ++ core/crypto/blake2/LICENSE-APACHE | 201 ++++++++ core/crypto/blake2/LICENSE-MIT | 26 + core/crypto/blake2/README.md | 57 +++ core/crypto/blake2/benches/blake2b.rs | 4 + core/crypto/blake2/benches/blake2s.rs | 4 + core/crypto/blake2/examples/blake2b_sum.rs | 47 ++ core/crypto/blake2/examples/blake2s_sum.rs | 47 ++ core/crypto/blake2/src/as_bytes.rs | 44 ++ core/crypto/blake2/src/blake2.rs | 453 ++++++++++++++++++ core/crypto/blake2/src/blake2b.rs | 18 + core/crypto/blake2/src/blake2s.rs | 18 + core/crypto/blake2/src/consts.rs | 47 ++ core/crypto/blake2/src/lib.rs | 111 +++++ core/crypto/blake2/src/simd.rs | 152 ++++++ core/crypto/blake2/src/simd/simd_opt.rs | 51 ++ core/crypto/blake2/src/simd/simd_opt/u32x4.rs | 67 +++ core/crypto/blake2/src/simd/simd_opt/u64x4.rs | 140 ++++++ core/crypto/blake2/src/simd/simdint.rs | 22 + core/crypto/blake2/src/simd/simdop.rs | 103 ++++ core/crypto/blake2/src/simd/simdty.rs | 77 +++ core/crypto/blake2/tests/compression.rs | 76 +++ .../blake2/tests/data/blake2b/fixed.blb | Bin 0 -> 182 bytes core/crypto/blake2/tests/data/blake2b/mac.blb | Bin 0 -> 66318 bytes .../blake2/tests/data/blake2b/variable.blb | Bin 0 -> 53 bytes core/crypto/blake2/tests/data/blake2s/mac.blb | Bin 0 -> 49870 bytes .../blake2/tests/data/blake2s/variable.blb | 1 + core/crypto/blake2/tests/lib.rs | 18 + core/crypto/blake2/tests/mac.rs | 6 + core/crypto/blake2/tests/persona.rs | 23 + 33 files changed, 2012 insertions(+), 1 deletion(-) create mode 100644 core/crypto/blake2/CHANGELOG.md create mode 100644 core/crypto/blake2/Cargo.lock create mode 100644 core/crypto/blake2/Cargo.toml create mode 100644 core/crypto/blake2/LICENSE-APACHE create mode 100644 core/crypto/blake2/LICENSE-MIT create mode 100644 core/crypto/blake2/README.md create mode 100644 core/crypto/blake2/benches/blake2b.rs create mode 100644 core/crypto/blake2/benches/blake2s.rs create mode 100644 core/crypto/blake2/examples/blake2b_sum.rs create mode 100644 core/crypto/blake2/examples/blake2s_sum.rs create mode 100644 core/crypto/blake2/src/as_bytes.rs create mode 100644 core/crypto/blake2/src/blake2.rs create mode 100644 core/crypto/blake2/src/blake2b.rs create mode 100644 core/crypto/blake2/src/blake2s.rs create mode 100644 core/crypto/blake2/src/consts.rs create mode 100644 core/crypto/blake2/src/lib.rs create mode 100644 core/crypto/blake2/src/simd.rs create mode 100644 core/crypto/blake2/src/simd/simd_opt.rs create mode 100644 core/crypto/blake2/src/simd/simd_opt/u32x4.rs create mode 100644 core/crypto/blake2/src/simd/simd_opt/u64x4.rs create mode 100644 core/crypto/blake2/src/simd/simdint.rs create mode 100644 core/crypto/blake2/src/simd/simdop.rs create mode 100644 core/crypto/blake2/src/simd/simdty.rs create mode 100644 core/crypto/blake2/tests/compression.rs create mode 100644 core/crypto/blake2/tests/data/blake2b/fixed.blb create mode 100644 core/crypto/blake2/tests/data/blake2b/mac.blb create mode 100644 core/crypto/blake2/tests/data/blake2b/variable.blb create mode 100644 core/crypto/blake2/tests/data/blake2s/mac.blb create mode 100644 core/crypto/blake2/tests/data/blake2s/variable.blb create mode 100644 core/crypto/blake2/tests/lib.rs create mode 100644 core/crypto/blake2/tests/mac.rs create mode 100644 core/crypto/blake2/tests/persona.rs diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index bfffe1842d8..31be2938d38 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { git = "https://github.com/near/near-blake2.git", branch = "f-standard-out", version = "0.9.1" } +blake2 = { package = "near-blake2", path = "./blake2" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/core/crypto/blake2/CHANGELOG.md b/core/crypto/blake2/CHANGELOG.md new file mode 100644 index 00000000000..22ee2af94cd --- /dev/null +++ b/core/crypto/blake2/CHANGELOG.md @@ -0,0 +1,62 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.9.1 (2020-10-26) +### Changed +- Bump `opaque-debug` to v0.3 ([#168]) +- Bump `block-buffer` to v0.9 ([#164]) + +[#168]: https://github.com/RustCrypto/hashes/pull/168 +[#164]: https://github.com/RustCrypto/hashes/pull/164 + +## 0.9.0 (2020-06-10) +### Added +- Support for Persona and Salt ([#78]) + +### Changed +- Update to `digest` v0.9 release; MSRV 1.41+ ([#155]) +- Use new `*Dirty` traits from the `digest` crate ([#153]) +- Bump `crypto-mac` to v0.8 release ([#152]) +- Bump `block-buffer` to v0.8 release ([#151]) +- Rename `*result*` to `finalize` ([#148]) +- Upgrade to Rust 2018 edition ([#119]) + +[#155]: https://github.com/RustCrypto/hashes/pull/155 +[#153]: https://github.com/RustCrypto/hashes/pull/153 +[#152]: https://github.com/RustCrypto/hashes/pull/152 +[#151]: https://github.com/RustCrypto/hashes/pull/151 +[#148]: https://github.com/RustCrypto/hashes/pull/148 +[#119]: https://github.com/RustCrypto/hashes/pull/133 +[#78]: https://github.com/RustCrypto/hashes/pull/78 + +## 0.8.1 (2019-08-25) + +## 0.8.0 (2018-10-11) + +## 0.7.1 (2018-04-30) + +## 0.7.0 (2017-11-15) + +## 0.6.1 (2017-07-24) + +## 0.6.0 (2017-06-12) + +## 0.5.2 (2017-05-17) + +## 0.5.1 (2017-05-02) + +## 0.5.0 (2017-04-06) + +## 0.4.0 (2017-03-06) + +## 0.3.0 (2016-11-17) + +## 0.2.0 (2016-10-14) + +## 0.1.1 (2016-10-11) + +## 0.1.0 (2016-10-09) diff --git a/core/crypto/blake2/Cargo.lock b/core/crypto/blake2/Cargo.lock new file mode 100644 index 00000000000..77bc64f337f --- /dev/null +++ b/core/crypto/blake2/Cargo.lock @@ -0,0 +1,106 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blake2" +version = "0.9.1" +dependencies = [ + "crypto-mac", + "digest", + "hex-literal", + "opaque-debug", +] + +[[package]] +name = "blobby" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" +dependencies = [ + "byteorder", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "blobby", + "generic-array", + "subtle", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "blobby", + "generic-array", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "hex-literal" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +dependencies = [ + "hex-literal-impl", + "proc-macro-hack", +] + +[[package]] +name = "hex-literal-impl" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" +dependencies = [ + "proc-macro-hack", +] + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "subtle" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" diff --git a/core/crypto/blake2/Cargo.toml b/core/crypto/blake2/Cargo.toml new file mode 100644 index 00000000000..c07f9c328ee --- /dev/null +++ b/core/crypto/blake2/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "near-blake2" +version = "0.9.1" +description = "BLAKE2 hash functions" +authors = [ + "RustCrypto Developers", + "Near Inc ", +] +license = "MIT OR Apache-2.0" +readme = "README.md" +edition = "2018" +keywords = ["crypto", "blake2", "hash", "digest"] +categories = ["cryptography", "no-std"] + +[dependencies] +digest = "0.9" +crypto-mac = "0.8" +opaque-debug = "0.3" + +[dev-dependencies] +digest = { version = "0.9", features = ["dev"] } +crypto-mac = { version = "0.8", features = ["dev"] } +hex-literal = "0.2" + +[features] +default = ["std"] +std = ["digest/std", "crypto-mac/std"] +simd = [] +simd_opt = ["simd"] +simd_asm = ["simd_opt"] diff --git a/core/crypto/blake2/LICENSE-APACHE b/core/crypto/blake2/LICENSE-APACHE new file mode 100644 index 00000000000..78173fa2e75 --- /dev/null +++ b/core/crypto/blake2/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/core/crypto/blake2/LICENSE-MIT b/core/crypto/blake2/LICENSE-MIT new file mode 100644 index 00000000000..872e206f2fe --- /dev/null +++ b/core/crypto/blake2/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2015-2016 The blake2-rfc Developers, Cesar Barros +Copyright (c) 2017 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/core/crypto/blake2/README.md b/core/crypto/blake2/README.md new file mode 100644 index 00000000000..6915156d4a7 --- /dev/null +++ b/core/crypto/blake2/README.md @@ -0,0 +1,57 @@ +# RustCrypto: BLAKE2 + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] + +Pure Rust implementation of the [BLAKE2 hash function][1] family with changes to +the compression function to specify an amount of rounds. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/blake2.svg +[crate-link]: https://crates.io/crates/blake2 +[docs-image]: https://docs.rs/blake2/badge.svg +[docs-link]: https://docs.rs/blake2/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/hashes/workflows/blake2/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/hashes/actions?query=workflow%3Ablake2 + +[//]: # (general links) + +[1]: https://blake2.net/ diff --git a/core/crypto/blake2/benches/blake2b.rs b/core/crypto/blake2/benches/blake2b.rs new file mode 100644 index 00000000000..5c3f4e7e7d3 --- /dev/null +++ b/core/crypto/blake2/benches/blake2b.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(blake2::Blake2b); diff --git a/core/crypto/blake2/benches/blake2s.rs b/core/crypto/blake2/benches/blake2s.rs new file mode 100644 index 00000000000..dba70e921cd --- /dev/null +++ b/core/crypto/blake2/benches/blake2s.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(blake2::Blake2s); diff --git a/core/crypto/blake2/examples/blake2b_sum.rs b/core/crypto/blake2/examples/blake2b_sum.rs new file mode 100644 index 00000000000..01a39e1a072 --- /dev/null +++ b/core/crypto/blake2/examples/blake2b_sum.rs @@ -0,0 +1,47 @@ +use near_blake2::{Blake2b, Digest}; +use std::env; +use std::fs; +use std::io::{self, Read}; + +const BUFFER_SIZE: usize = 1024; + +/// Print digest result as hex string and name pair +fn print_result(sum: &[u8], name: &str) { + for byte in sum { + print!("{:02x}", byte); + } + println!("\t{}", name); +} + +/// Compute digest value for given `Reader` and print it +/// On any error simply return without doing anything +fn process(reader: &mut R, name: &str) { + let mut sh = D::default(); + let mut buffer = [0u8; BUFFER_SIZE]; + loop { + let n = match reader.read(&mut buffer) { + Ok(n) => n, + Err(_) => return, + }; + sh.update(&buffer[..n]); + if n == 0 || n < BUFFER_SIZE { + break; + } + } + print_result(&sh.finalize(), name); +} + +fn main() { + let args = env::args(); + // Process files listed in command line arguments one by one + // If no files provided process input from stdin + if args.len() > 1 { + for path in args.skip(1) { + if let Ok(mut file) = fs::File::open(&path) { + process::(&mut file, &path); + } + } + } else { + process::(&mut io::stdin(), "-"); + } +} diff --git a/core/crypto/blake2/examples/blake2s_sum.rs b/core/crypto/blake2/examples/blake2s_sum.rs new file mode 100644 index 00000000000..c3b7a4898cd --- /dev/null +++ b/core/crypto/blake2/examples/blake2s_sum.rs @@ -0,0 +1,47 @@ +use near_blake2::{Blake2s, Digest}; +use std::env; +use std::fs; +use std::io::{self, Read}; + +const BUFFER_SIZE: usize = 1024; + +/// Print digest result as hex string and name pair +fn print_result(sum: &[u8], name: &str) { + for byte in sum { + print!("{:02x}", byte); + } + println!("\t{}", name); +} + +/// Compute digest value for given `Reader` and print it +/// On any error simply return without doing anything +fn process(reader: &mut R, name: &str) { + let mut sh = D::default(); + let mut buffer = [0u8; BUFFER_SIZE]; + loop { + let n = match reader.read(&mut buffer) { + Ok(n) => n, + Err(_) => return, + }; + sh.update(&buffer[..n]); + if n == 0 || n < BUFFER_SIZE { + break; + } + } + print_result(&sh.finalize(), name); +} + +fn main() { + let args = env::args(); + // Process files listed in command line arguments one by one + // If no files provided process input from stdin + if args.len() > 1 { + for path in args.skip(1) { + if let Ok(mut file) = fs::File::open(&path) { + process::(&mut file, &path); + } + } + } else { + process::(&mut io::stdin(), "-"); + } +} diff --git a/core/crypto/blake2/src/as_bytes.rs b/core/crypto/blake2/src/as_bytes.rs new file mode 100644 index 00000000000..02cca6bbade --- /dev/null +++ b/core/crypto/blake2/src/as_bytes.rs @@ -0,0 +1,44 @@ +// Copyright 2016 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use core::mem; +use core::slice; + +pub unsafe trait Safe {} + +pub trait AsBytes { + fn as_bytes(&self) -> &[u8]; + fn as_mut_bytes(&mut self) -> &mut [u8]; +} + +impl AsBytes for [T] { + #[inline] + fn as_bytes(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * mem::size_of::()) + } + } + + #[inline] + fn as_mut_bytes(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut( + self.as_mut_ptr() as *mut u8, + self.len() * mem::size_of::(), + ) + } + } +} + +unsafe impl Safe for u8 {} +unsafe impl Safe for u16 {} +unsafe impl Safe for u32 {} +unsafe impl Safe for u64 {} +unsafe impl Safe for i8 {} +unsafe impl Safe for i16 {} +unsafe impl Safe for i32 {} +unsafe impl Safe for i64 {} diff --git a/core/crypto/blake2/src/blake2.rs b/core/crypto/blake2/src/blake2.rs new file mode 100644 index 00000000000..d40a89f1868 --- /dev/null +++ b/core/crypto/blake2/src/blake2.rs @@ -0,0 +1,453 @@ +use digest::generic_array::GenericArray; + +macro_rules! blake2_impl { + ( + $state:ident, $fix_state:ident, $word:ident, $vec:ident, $bytes:ident, + $block_size:ident, $R1:expr, $R2:expr, $R3:expr, $R4:expr, $IV:expr, + $vardoc:expr, $doc:expr, + ) => { + use $crate::as_bytes::AsBytes; + use $crate::simd::{$vec, Vector4}; + + use core::{cmp, convert::TryInto, ops::Div}; + use crypto_mac::{InvalidKeyLength, Mac, NewMac}; + use digest::generic_array::typenum::{Unsigned, U4}; + use digest::generic_array::GenericArray; + use digest::InvalidOutputSize; + use digest::{BlockInput, FixedOutputDirty, Reset, Update, VariableOutputDirty}; + + type Output = GenericArray; + + #[derive(Clone)] + #[doc=$vardoc] + pub struct $state { + m: [$word; 16], + h: [$vec; 2], + t: u64, + n: usize, + + h0: [$vec; 2], + m0: [$word; 16], + t0: u64, + } + + #[inline(always)] + fn iv0() -> $vec { + $vec::new($IV[0], $IV[1], $IV[2], $IV[3]) + } + #[inline(always)] + fn iv1() -> $vec { + $vec::new($IV[4], $IV[5], $IV[6], $IV[7]) + } + + #[inline(always)] + fn quarter_round(v: &mut [$vec; 4], rd: u32, rb: u32, m: $vec) { + v[0] = v[0].wrapping_add(v[1]).wrapping_add(m.from_le()); + v[3] = (v[3] ^ v[0]).rotate_right_const(rd); + v[2] = v[2].wrapping_add(v[3]); + v[1] = (v[1] ^ v[2]).rotate_right_const(rb); + } + + #[inline(always)] + fn shuffle(v: &mut [$vec; 4]) { + v[1] = v[1].shuffle_left_1(); + v[2] = v[2].shuffle_left_2(); + v[3] = v[3].shuffle_left_3(); + } + + #[inline(always)] + fn unshuffle(v: &mut [$vec; 4]) { + v[1] = v[1].shuffle_right_1(); + v[2] = v[2].shuffle_right_2(); + v[3] = v[3].shuffle_right_3(); + } + + #[inline(always)] + fn round(v: &mut [$vec; 4], m: &[$word; 16], s: &[usize; 16]) { + quarter_round(v, $R1, $R2, $vec::gather(m, s[0], s[2], s[4], s[6])); + quarter_round(v, $R3, $R4, $vec::gather(m, s[1], s[3], s[5], s[7])); + + shuffle(v); + quarter_round(v, $R1, $R2, $vec::gather(m, s[8], s[10], s[12], s[14])); + quarter_round(v, $R3, $R4, $vec::gather(m, s[9], s[11], s[13], s[15])); + unshuffle(v); + } + + /// The compression function of the blake2 algorithm. + /// + /// Takes as an argument the state vector "h", message block vector "m" + /// (the last block is padded with zeros to full block size, if + /// required), 2w-bit offset counter "t", and final block indicator flag + /// "f". Local vector v[0..15] is used in processing. F returns a new + /// state vector. The number of rounds, "r", is 12 for BLAKE2b and 10 + /// for BLAKE2s. Rounds are numbered from 0 to r - 1. + pub fn f(rounds: u32, h: [$word; 8], m: [$word; 16], t: [$word; 2], f: bool) -> Output { + use $crate::consts::SIGMA; + let mut h: [$vec; 2] = [ + $vec::new(h[0], h[1], h[2], h[3]), + $vec::new(h[4], h[5], h[6], h[7]), + ]; + + let (f0, f1) = if f { (!0, 0) } else { (0, 0) }; + + let (t0, t1) = (t[0], t[1]); + + let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; + + for x in 1..rounds + 1 { + let x = if x > 10 { x - 11 } else { x - 1 }; + round(&mut v, &m, &SIGMA[x as usize]); + } + + h[0] = h[0] ^ (v[0] ^ v[2]); + h[1] = h[1] ^ (v[1] ^ v[3]); + + let buf = [h[0].to_le(), h[1].to_le()]; + let mut out = GenericArray::default(); + copy(buf.as_bytes(), &mut out); + + out + } + + impl $state { + /// Creates a new hashing context with a key. + /// + /// **WARNING!** If you plan to use it for variable output MAC, then + /// make sure to compare codes in constant time! It can be done + /// for example by using `subtle` crate. + pub fn new_keyed(key: &[u8], output_size: usize) -> Self { + Self::with_params(key, &[], &[], output_size) + } + + /// Creates a new hashing context with the full set of sequential-mode parameters. + pub fn with_params( + key: &[u8], + salt: &[u8], + persona: &[u8], + output_size: usize, + ) -> Self { + let kk = key.len(); + assert!(kk <= $bytes::to_usize()); + assert!(output_size <= $bytes::to_usize()); + + // The number of bytes needed to express two words. + let length = $bytes::to_usize() / 4; + assert!(salt.len() <= length); + assert!(persona.len() <= length); + + // Build a parameter block + let mut p = [0 as $word; 8]; + p[0] = 0x0101_0000 ^ ((kk as $word) << 8) ^ (output_size as $word); + + // salt is two words long + if salt.len() < length { + let mut padded_salt = + GenericArray::>::Output>::default(); + for i in 0..salt.len() { + padded_salt[i] = salt[i]; + } + p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap()); + p[5] = $word::from_le_bytes( + padded_salt[length / 2..padded_salt.len()] + .try_into() + .unwrap(), + ); + } else { + p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap()); + p[5] = + $word::from_le_bytes(salt[salt.len() / 2..salt.len()].try_into().unwrap()); + } + + // persona is also two words long + if persona.len() < length { + let mut padded_persona = + GenericArray::>::Output>::default(); + for i in 0..persona.len() { + padded_persona[i] = persona[i]; + } + p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap()); + p[7] = $word::from_le_bytes( + padded_persona[length / 2..padded_persona.len()] + .try_into() + .unwrap(), + ); + } else { + p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap()); + p[7] = $word::from_le_bytes( + persona[length / 2..persona.len()].try_into().unwrap(), + ); + } + + let mut state = Self::with_parameter_block(&p); + + if kk > 0 { + copy(key, state.m.as_mut_bytes()); + state.t = 2 * $bytes::to_u64(); + } + + state.t0 = state.t; + state.m0 = state.m; + state + } + + #[doc(hidden)] + pub fn with_parameter_block(p: &[$word; 8]) -> Self { + let nn = p[0] as u8 as usize; + let kk = (p[0] >> 8) as u8 as usize; + assert!(nn >= 1 && nn <= $bytes::to_usize()); + assert!(kk <= $bytes::to_usize()); + + let h0 = [ + iv0() ^ $vec::new(p[0], p[1], p[2], p[3]), + iv1() ^ $vec::new(p[4], p[5], p[6], p[7]), + ]; + + $state { + m: [0; 16], + h: h0, + t: 0, + n: nn, + + t0: 0, + m0: [0; 16], + h0, + } + } + + /// Updates the hashing context with more data. + fn update(&mut self, data: &[u8]) { + let mut rest = data; + + let block = 2 * $bytes::to_usize(); + + let off = self.t as usize % block; + if off != 0 || self.t == 0 { + let len = cmp::min(block - off, rest.len()); + + let part = &rest[..len]; + rest = &rest[part.len()..]; + + copy(part, &mut self.m.as_mut_bytes()[off..]); + self.t = self + .t + .checked_add(part.len() as u64) + .expect("hash data length overflow"); + } + + while rest.len() >= block { + self.compress(0, 0); + + let part = &rest[..block]; + rest = &rest[part.len()..]; + + copy(part, &mut self.m.as_mut_bytes()); + self.t = self + .t + .checked_add(part.len() as u64) + .expect("hash data length overflow"); + } + + let n = rest.len(); + if n > 0 { + self.compress(0, 0); + + copy(rest, &mut self.m.as_mut_bytes()); + self.t = self + .t + .checked_add(rest.len() as u64) + .expect("hash data length overflow"); + } + } + + #[doc(hidden)] + pub fn finalize_last_node(mut self) -> Output { + self.finalize_with_flag(!0) + } + + fn finalize_with_flag(&mut self, f1: $word) -> Output { + let off = self.t as usize % (2 * $bytes::to_usize()); + if off != 0 { + self.m.as_mut_bytes()[off..].iter_mut().for_each(|b| *b = 0); + } + + self.compress(!0, f1); + + let buf = [self.h[0].to_le(), self.h[1].to_le()]; + + let mut out = GenericArray::default(); + copy(buf.as_bytes(), &mut out); + out + } + + fn compress(&mut self, f0: $word, f1: $word) { + use $crate::consts::SIGMA; + + let m = &self.m; + let h = &mut self.h; + + let t0 = self.t as $word; + let t1 = match $bytes::to_u8() { + 64 => 0, + 32 => (self.t >> 32) as $word, + _ => unreachable!(), + }; + + let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; + + round(&mut v, m, &SIGMA[0]); + round(&mut v, m, &SIGMA[1]); + round(&mut v, m, &SIGMA[2]); + round(&mut v, m, &SIGMA[3]); + round(&mut v, m, &SIGMA[4]); + round(&mut v, m, &SIGMA[5]); + round(&mut v, m, &SIGMA[6]); + round(&mut v, m, &SIGMA[7]); + round(&mut v, m, &SIGMA[8]); + round(&mut v, m, &SIGMA[9]); + + if $bytes::to_u8() == 64 { + round(&mut v, m, &SIGMA[0]); + round(&mut v, m, &SIGMA[1]); + } + + h[0] = h[0] ^ (v[0] ^ v[2]); + h[1] = h[1] ^ (v[1] ^ v[3]); + } + } + + impl Default for $state { + fn default() -> Self { + Self::new_keyed(&[], $bytes::to_usize()) + } + } + + impl BlockInput for $state { + type BlockSize = $block_size; + } + + impl Update for $state { + fn update(&mut self, data: impl AsRef<[u8]>) { + self.update(data.as_ref()); + } + } + + impl VariableOutputDirty for $state { + fn new(output_size: usize) -> Result { + if output_size == 0 || output_size > $bytes::to_usize() { + return Err(InvalidOutputSize); + } + Ok(Self::new_keyed(&[], output_size)) + } + + fn output_size(&self) -> usize { + self.n + } + + fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])) { + let n = self.n; + let res = self.finalize_with_flag(0); + f(&res[..n]); + } + } + + impl Reset for $state { + fn reset(&mut self) { + self.t = self.t0; + self.m = self.m0; + self.h = self.h0; + } + } + + opaque_debug::implement!($state); + digest::impl_write!($state); + + #[derive(Clone)] + #[doc=$doc] + pub struct $fix_state { + state: $state, + } + + impl $fix_state { + /// Creates a new hashing context with the full set of sequential-mode parameters. + pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8]) -> Self { + let state = $state::with_params(key, salt, persona, $bytes::to_usize()); + Self { state } + } + } + + impl Default for $fix_state { + fn default() -> Self { + let state = $state::new_keyed(&[], $bytes::to_usize()); + Self { state } + } + } + + impl BlockInput for $fix_state { + type BlockSize = $block_size; + } + + impl Update for $fix_state { + fn update(&mut self, data: impl AsRef<[u8]>) { + self.state.update(data.as_ref()); + } + } + + impl FixedOutputDirty for $fix_state { + type OutputSize = $bytes; + + fn finalize_into_dirty(&mut self, out: &mut Output) { + out.copy_from_slice(&self.state.finalize_with_flag(0)); + } + } + + impl Reset for $fix_state { + fn reset(&mut self) { + self.state.reset() + } + } + + impl NewMac for $fix_state { + type KeySize = $bytes; + + fn new(key: &GenericArray) -> Self { + let state = $state::new_keyed(key, $bytes::to_usize()); + Self { state } + } + + fn new_varkey(key: &[u8]) -> Result { + if key.len() > $bytes::to_usize() { + Err(InvalidKeyLength) + } else { + let state = $state::new_keyed(key, $bytes::to_usize()); + Ok(Self { state }) + } + } + } + + impl Mac for $fix_state { + type OutputSize = $bytes; + + fn update(&mut self, data: &[u8]) { + self.state.update(data); + } + + fn reset(&mut self) { + ::reset(self) + } + + fn finalize(mut self) -> crypto_mac::Output { + crypto_mac::Output::new(self.state.finalize_with_flag(0)) + } + } + + opaque_debug::implement!($fix_state); + digest::impl_write!($fix_state); + + fn copy(src: &[u8], dst: &mut [u8]) { + assert!(dst.len() >= src.len()); + unsafe { + core::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()); + } + } + }; +} diff --git a/core/crypto/blake2/src/blake2b.rs b/core/crypto/blake2/src/blake2b.rs new file mode 100644 index 00000000000..3afc18d84a5 --- /dev/null +++ b/core/crypto/blake2/src/blake2b.rs @@ -0,0 +1,18 @@ +use crate::consts::BLAKE2B_IV; +use digest::generic_array::typenum::{U128, U64}; + +blake2_impl!( + VarBlake2b, + Blake2b, + u64, + u64x4, + U64, + U128, + 32, + 24, + 16, + 63, + BLAKE2B_IV, + "Blake2b instance with a variable output.", + "Blake2b instance with a fixed output.", +); diff --git a/core/crypto/blake2/src/blake2s.rs b/core/crypto/blake2/src/blake2s.rs new file mode 100644 index 00000000000..5306ed99218 --- /dev/null +++ b/core/crypto/blake2/src/blake2s.rs @@ -0,0 +1,18 @@ +use crate::consts::BLAKE2S_IV; +use digest::generic_array::typenum::{U32, U64}; + +blake2_impl!( + VarBlake2s, + Blake2s, + u32, + u32x4, + U32, + U64, + 16, + 12, + 8, + 7, + BLAKE2S_IV, + "Blake2s instance with a variable output.", + "Blake2s instance with a fixed output.", +); diff --git a/core/crypto/blake2/src/consts.rs b/core/crypto/blake2/src/consts.rs new file mode 100644 index 00000000000..ab76c0e1724 --- /dev/null +++ b/core/crypto/blake2/src/consts.rs @@ -0,0 +1,47 @@ +#![allow(clippy::unreadable_literal)] + +pub static SIGMA: [[usize; 16]; 12] = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], +]; + +pub static BLAKE2B_IV: [u64; 8] = [ + 0x6a09e667f3bcc908, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, +]; + +/* +pub const BLAKE2B_BLOCKBYTES : usize = 128; +pub const BLAKE2B_OUTBYTES : usize = 64; +pub const BLAKE2B_KEYBYTES : usize = 64; +pub const BLAKE2B_SALTBYTES : usize = 16; +pub const BLAKE2B_PERSONALBYTES : usize = 16; +*/ + +pub static BLAKE2S_IV: [u32; 8] = [ + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19, +]; + +/* +pub const BLAKE2S_BLOCKBYTES : usize = 64; +pub const BLAKE2S_OUTBYTES : usize = 32; +pub const BLAKE2S_KEYBYTES : usize = 32; +pub const BLAKE2S_SALTBYTES : usize = 8; +pub const BLAKE2S_PERSONALBYTES : usize = 8; +*/ diff --git a/core/crypto/blake2/src/lib.rs b/core/crypto/blake2/src/lib.rs new file mode 100644 index 00000000000..044f86dd4a1 --- /dev/null +++ b/core/crypto/blake2/src/lib.rs @@ -0,0 +1,111 @@ +//! An implementation of the [BLAKE2][1] hash functions. +//! +//! # Usage +//! +//! `Blake2b` can be used in the following way: +//! +//! ```rust +//! use blake2::{Blake2b, Blake2s, Digest}; +//! use hex_literal::hex; +//! +//! // create a Blake2b object +//! let mut hasher = Blake2b::new(); +//! +//! // write input message +//! hasher.update(b"hello world"); +//! +//! // read hash digest and consume hasher +//! let res = hasher.finalize(); +//! assert_eq!(res[..], hex!(" +//! 021ced8799296ceca557832ab941a50b4a11f83478cf141f51f933f653ab9fbc +//! c05a037cddbed06e309bf334942c4e58cdf1a46e237911ccd7fcf9787cbc7fd0 +//! ")[..]); +//! +//! // same example for `Blake2s`: +//! let mut hasher = Blake2s::new(); +//! hasher.update(b"hello world"); +//! let res = hasher.finalize(); +//! assert_eq!(res[..], hex!(" +//! 9aec6806794561107e594b1f6a8a6b0c92a0cba9acf5e5e93cca06f781813b0b +//! ")[..]); +//! ``` +//! +//! Also see [RustCrypto/hashes](https://github.com/RustCrypto/hashes) readme. +//! +//! ## Variable output size +//! +//! If you need variable sized output you can use `VarBlake2b` and `VarBlake2s` +//! which support variable output sizes through `VariableOutput` trait. `Update` +//! trait has to be imported as well. +//! +//! ```rust +//! use blake2::VarBlake2b; +//! use blake2::digest::{Update, VariableOutput}; +//! +//! let mut hasher = VarBlake2b::new(10).unwrap(); +//! hasher.update(b"my_input"); +//! hasher.finalize_variable(|res| { +//! assert_eq!(res, [44, 197, 92, 132, 228, 22, 146, 78, 100, 0]) +//! }) +//! ``` +//! +//! ## Message Authentication Code (MAC) +//! +//! BLAKE2 can be used as a MAC without any additional constructs: +//! +//! ```rust +//! use blake2::Blake2b; +//! use blake2::crypto_mac::{Mac, NewMac}; +//! +//! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); +//! hasher.update(b"hello world"); +//! +//! // `result` has type `crypto_mac::Output` which is a thin wrapper around +//! // a byte array and provides a constant time equality check +//! let result = hasher.finalize(); +//! // To get underlying array use the `into_bytes` method, but be careful, +//! // since incorrect use of the code value may permit timing attacks which +//! // defeat the security provided by the `crypto_mac::Output` +//! let code_bytes = result.into_bytes(); +//! +//! // To verify the message it's recommended to use `verify` method +//! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); +//! hasher.update(b"hello world"); +//! // `verify` return `Ok(())` if code is correct, `Err(MacError)` otherwise +//! hasher.verify(&code_bytes).unwrap(); +//! ``` +//! +//! # Acknowledgment +//! Based on the [blake2-rfc][2] crate. +//! +//! [1]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 +//! [2]: https://github.com/cesarb/blake2-rfc + +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] +#![warn(missing_docs, rust_2018_idioms)] +#![cfg_attr(feature = "simd", feature(platform_intrinsics, repr_simd))] +#![cfg_attr(feature = "simd_asm", feature(asm))] + +#[cfg(feature = "std")] +extern crate std; + +mod as_bytes; +mod consts; + +mod simd; + +#[macro_use] +mod blake2; + +mod blake2b; +mod blake2s; + +pub use crypto_mac; +pub use digest::{self, Digest}; + +pub use crate::blake2b::{f as blake2b_f, Blake2b, VarBlake2b}; +pub use crate::blake2s::{f as blake2s_f, Blake2s, VarBlake2s}; diff --git a/core/crypto/blake2/src/simd.rs b/core/crypto/blake2/src/simd.rs new file mode 100644 index 00000000000..8f244eaef1c --- /dev/null +++ b/core/crypto/blake2/src/simd.rs @@ -0,0 +1,152 @@ +// Copyright 2015 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +mod simd_opt; +mod simdint; +mod simdop; +mod simdty; + +pub use self::simdty::{u32x4, u64x4}; + +pub trait Vector4: Copy { + fn gather(src: &[T], i0: usize, i1: usize, i2: usize, i3: usize) -> Self; + + // Usually, this should be fixed but to keep it inline with blake2 upstream, + // we will leave it as is for maximum compatibility. + #[allow(clippy::wrong_self_convention)] + fn from_le(self) -> Self; + fn to_le(self) -> Self; + fn to_be(self) -> Self; + + fn wrapping_add(self, rhs: Self) -> Self; + + fn rotate_right_const(self, n: u32) -> Self; + + fn shuffle_left_1(self) -> Self; + fn shuffle_left_2(self) -> Self; + fn shuffle_left_3(self) -> Self; + + #[inline(always)] + fn shuffle_right_1(self) -> Self { + self.shuffle_left_3() + } + #[inline(always)] + fn shuffle_right_2(self) -> Self { + self.shuffle_left_2() + } + #[inline(always)] + fn shuffle_right_3(self) -> Self { + self.shuffle_left_1() + } +} + +macro_rules! impl_vector4 { + ($vec:ident, $word:ident) => { + impl Vector4<$word> for $vec { + #[inline(always)] + fn gather(src: &[$word], i0: usize, i1: usize, i2: usize, i3: usize) -> Self { + $vec::new(src[i0], src[i1], src[i2], src[i3]) + } + + #[cfg(target_endian = "little")] + #[inline(always)] + fn from_le(self) -> Self { + self + } + + #[cfg(not(target_endian = "little"))] + #[inline(always)] + fn from_le(self) -> Self { + $vec::new( + $word::from_le(self.0), + $word::from_le(self.1), + $word::from_le(self.2), + $word::from_le(self.3), + ) + } + + #[cfg(target_endian = "little")] + #[inline(always)] + fn to_le(self) -> Self { + self + } + + #[cfg(not(target_endian = "little"))] + #[inline(always)] + fn to_le(self) -> Self { + $vec::new( + self.0.to_le(), + self.1.to_le(), + self.2.to_le(), + self.3.to_le(), + ) + } + + #[inline(always)] + fn to_be(self) -> Self { + $vec::new( + self.0.to_be(), + self.1.to_be(), + self.2.to_be(), + self.3.to_be(), + ) + } + + #[inline(always)] + fn wrapping_add(self, rhs: Self) -> Self { + self + rhs + } + + #[inline(always)] + fn rotate_right_const(self, n: u32) -> Self { + simd_opt::$vec::rotate_right_const(self, n) + } + + #[cfg(feature = "simd")] + #[inline(always)] + fn shuffle_left_1(self) -> Self { + use crate::simd::simdint::simd_shuffle4; + unsafe { simd_shuffle4(self, self, [1, 2, 3, 0]) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn shuffle_left_1(self) -> Self { + $vec::new(self.1, self.2, self.3, self.0) + } + + #[cfg(feature = "simd")] + #[inline(always)] + fn shuffle_left_2(self) -> Self { + use crate::simd::simdint::simd_shuffle4; + unsafe { simd_shuffle4(self, self, [2, 3, 0, 1]) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn shuffle_left_2(self) -> Self { + $vec::new(self.2, self.3, self.0, self.1) + } + + #[cfg(feature = "simd")] + #[inline(always)] + fn shuffle_left_3(self) -> Self { + use crate::simd::simdint::simd_shuffle4; + unsafe { simd_shuffle4(self, self, [3, 0, 1, 2]) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn shuffle_left_3(self) -> Self { + $vec::new(self.3, self.0, self.1, self.2) + } + } + }; +} + +impl_vector4!(u32x4, u32); +impl_vector4!(u64x4, u64); diff --git a/core/crypto/blake2/src/simd/simd_opt.rs b/core/crypto/blake2/src/simd/simd_opt.rs new file mode 100644 index 00000000000..e143ba4ec80 --- /dev/null +++ b/core/crypto/blake2/src/simd/simd_opt.rs @@ -0,0 +1,51 @@ +// Copyright 2015 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[allow(unused_macros)] +#[cfg(feature = "simd")] +macro_rules! transmute_shuffle { + ($tmp:ident, $shuffle:ident, $vec:expr, $idx:expr) => { + unsafe { + use crate::simd::simdint::$shuffle; + use crate::simd::simdty::$tmp; + use core::mem::transmute; + + let tmp_i: $tmp = transmute($vec); + let tmp_o: $tmp = $shuffle(tmp_i, tmp_i, $idx); + transmute(tmp_o) + } + }; +} + +#[cfg(feature = "simd")] +pub mod u32x4; +#[cfg(feature = "simd")] +pub mod u64x4; + +#[cfg(not(feature = "simd"))] +macro_rules! simd_opt { + ($vec:ident) => { + pub mod $vec { + use crate::simd::simdty::$vec; + + #[inline(always)] + pub fn rotate_right_const(vec: $vec, n: u32) -> $vec { + $vec::new( + vec.0.rotate_right(n), + vec.1.rotate_right(n), + vec.2.rotate_right(n), + vec.3.rotate_right(n), + ) + } + } + }; +} + +#[cfg(not(feature = "simd"))] +simd_opt!(u32x4); +#[cfg(not(feature = "simd"))] +simd_opt!(u64x4); diff --git a/core/crypto/blake2/src/simd/simd_opt/u32x4.rs b/core/crypto/blake2/src/simd/simd_opt/u32x4.rs new file mode 100644 index 00000000000..a3d8e3d6d4a --- /dev/null +++ b/core/crypto/blake2/src/simd/simd_opt/u32x4.rs @@ -0,0 +1,67 @@ +// Copyright 2015 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use crate::simd::simdty::u32x4; + +#[cfg(feature = "simd_opt")] +#[inline(always)] +pub fn rotate_right_const(vec: u32x4, n: u32) -> u32x4 { + match n { + 16 => rotate_right_16(vec), + 8 => rotate_right_8(vec), + _ => rotate_right_any(vec, n), + } +} + +#[cfg(not(feature = "simd_opt"))] +#[inline(always)] +pub fn rotate_right_const(vec: u32x4, n: u32) -> u32x4 { + rotate_right_any(vec, n) +} + +#[inline(always)] +fn rotate_right_any(vec: u32x4, n: u32) -> u32x4 { + let r = n as u32; + let l = 32 - r; + + (vec >> u32x4::new(r, r, r, r)) ^ (vec << u32x4::new(l, l, l, l)) +} + +#[cfg(feature = "simd_opt")] +#[inline(always)] +fn rotate_right_16(vec: u32x4) -> u32x4 { + if cfg!(target_feature = "ssse3") { + // pshufb (SSSE3) / vpshufb (AVX2) + transmute_shuffle!( + u8x16, + simd_shuffle16, + vec, + [2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13] + ) + } else if cfg!(any(target_feature = "sse2", target_feature = "neon")) { + // pshuflw+pshufhw (SSE2) / vrev (NEON) + transmute_shuffle!(u16x8, simd_shuffle8, vec, [1, 0, 3, 2, 5, 4, 7, 6]) + } else { + rotate_right_any(vec, 16) + } +} + +#[cfg(feature = "simd_opt")] +#[inline(always)] +fn rotate_right_8(vec: u32x4) -> u32x4 { + if cfg!(target_feature = "ssse3") { + // pshufb (SSSE3) / vpshufb (AVX2) + transmute_shuffle!( + u8x16, + simd_shuffle16, + vec, + [1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12] + ) + } else { + rotate_right_any(vec, 8) + } +} diff --git a/core/crypto/blake2/src/simd/simd_opt/u64x4.rs b/core/crypto/blake2/src/simd/simd_opt/u64x4.rs new file mode 100644 index 00000000000..0a6972a8771 --- /dev/null +++ b/core/crypto/blake2/src/simd/simd_opt/u64x4.rs @@ -0,0 +1,140 @@ +// Copyright 2015 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use crate::simd::simdty::u64x4; + +#[cfg(feature = "simd_opt")] +#[inline(always)] +pub fn rotate_right_const(vec: u64x4, n: u32) -> u64x4 { + match n { + 32 => rotate_right_32(vec), + 24 => rotate_right_24(vec), + 16 => rotate_right_16(vec), + _ => rotate_right_any(vec, n), + } +} + +#[cfg(not(feature = "simd_opt"))] +#[inline(always)] +pub fn rotate_right_const(vec: u64x4, n: u32) -> u64x4 { + rotate_right_any(vec, n) +} + +#[inline(always)] +fn rotate_right_any(vec: u64x4, n: u32) -> u64x4 { + let r = n as u64; + let l = 64 - r; + + (vec >> u64x4::new(r, r, r, r)) ^ (vec << u64x4::new(l, l, l, l)) +} + +#[cfg(feature = "simd_opt")] +#[inline(always)] +fn rotate_right_32(vec: u64x4) -> u64x4 { + if cfg!(any(target_feature = "sse2", target_feature = "neon")) { + // 2 x pshufd (SSE2) / vpshufd (AVX2) / 2 x vrev (NEON) + transmute_shuffle!(u32x8, simd_shuffle8, vec, [1, 0, 3, 2, 5, 4, 7, 6]) + } else { + rotate_right_any(vec, 32) + } +} + +#[cfg(feature = "simd_opt")] +#[inline(always)] +fn rotate_right_24(vec: u64x4) -> u64x4 { + if cfg!(all( + feature = "simd_asm", + target_feature = "neon", + target_arch = "arm" + )) { + // 4 x vext (NEON) + rotate_right_vext(vec, 3) + } else if cfg!(target_feature = "ssse3") { + // 2 x pshufb (SSSE3) / vpshufb (AVX2) + transmute_shuffle!( + u8x32, + simd_shuffle32, + vec, + [ + 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 19, 20, 21, 22, 23, 16, 17, + 18, 27, 28, 29, 30, 31, 24, 25, 26 + ] + ) + } else { + rotate_right_any(vec, 24) + } +} + +#[cfg(feature = "simd_opt")] +#[inline(always)] +fn rotate_right_16(vec: u64x4) -> u64x4 { + if cfg!(all( + feature = "simd_asm", + target_feature = "neon", + target_arch = "arm" + )) { + // 4 x vext (NEON) + rotate_right_vext(vec, 2) + } else if cfg!(target_feature = "ssse3") { + // 2 x pshufb (SSSE3) / vpshufb (AVX2) + transmute_shuffle!( + u8x32, + simd_shuffle32, + vec, + [ + 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 18, 19, 20, 21, 22, 23, 16, + 17, 26, 27, 28, 29, 30, 31, 24, 25 + ] + ) + } else if cfg!(target_feature = "sse2") { + // 2 x pshuflw+pshufhw (SSE2) + transmute_shuffle!( + u16x16, + simd_shuffle16, + vec, + [1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12] + ) + } else { + rotate_right_any(vec, 16) + } +} + +#[cfg(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm"))] +mod simd_asm_neon_arm { + use crate::simd::simdty::{u64x2, u64x4}; + + #[inline(always)] + fn vext_u64(vec: u64x2, b: u8) -> u64x2 { + unsafe { + let result: u64x2; + asm!("vext.8 ${0:e}, ${1:e}, ${1:e}, $2\nvext.8 ${0:f}, ${1:f}, ${1:f}, $2" + : "=w" (result) + : "w" (vec), "n" (b)); + result + } + } + + #[inline(always)] + pub fn rotate_right_vext(vec: u64x4, b: u8) -> u64x4 { + use crate::simd::simdint::{simd_shuffle2, simd_shuffle4}; + + unsafe { + let tmp0 = vext_u64(simd_shuffle2(vec, vec, [0, 1]), b); + let tmp1 = vext_u64(simd_shuffle2(vec, vec, [2, 3]), b); + simd_shuffle4(tmp0, tmp1, [0, 1, 2, 3]) + } + } +} + +#[cfg(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm"))] +use self::simd_asm_neon_arm::rotate_right_vext; + +#[cfg(feature = "simd_opt")] +#[cfg(not(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm")))] +fn rotate_right_vext(_vec: u64x4, _n: u8) -> u64x4 { + unreachable!() +} diff --git a/core/crypto/blake2/src/simd/simdint.rs b/core/crypto/blake2/src/simd/simdint.rs new file mode 100644 index 00000000000..d876d553820 --- /dev/null +++ b/core/crypto/blake2/src/simd/simdint.rs @@ -0,0 +1,22 @@ +// Copyright 2015 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#![allow(dead_code)] + +#[cfg(feature = "simd")] +extern "platform-intrinsic" { + pub fn simd_add(x: T, y: T) -> T; + pub fn simd_shl(x: T, y: T) -> T; + pub fn simd_shr(x: T, y: T) -> T; + pub fn simd_xor(x: T, y: T) -> T; + + pub fn simd_shuffle2(v: T, w: T, idx: [u32; 2]) -> U; + pub fn simd_shuffle4(v: T, w: T, idx: [u32; 4]) -> U; + pub fn simd_shuffle8(v: T, w: T, idx: [u32; 8]) -> U; + pub fn simd_shuffle16(v: T, w: T, idx: [u32; 16]) -> U; + pub fn simd_shuffle32(v: T, w: T, idx: [u32; 32]) -> U; +} diff --git a/core/crypto/blake2/src/simd/simdop.rs b/core/crypto/blake2/src/simd/simdop.rs new file mode 100644 index 00000000000..891456d9c53 --- /dev/null +++ b/core/crypto/blake2/src/simd/simdop.rs @@ -0,0 +1,103 @@ +// Copyright 2015 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[cfg(feature = "simd")] +use crate::simd::simdint; +use crate::simd::simdty::{u32x4, u64x4}; + +use core::ops::{Add, BitXor, Shl, Shr}; + +macro_rules! impl_ops { + ($vec:ident) => { + impl Add for $vec { + type Output = Self; + + #[cfg(feature = "simd")] + #[inline(always)] + fn add(self, rhs: Self) -> Self::Output { + unsafe { simdint::simd_add(self, rhs) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn add(self, rhs: Self) -> Self::Output { + $vec::new( + self.0.wrapping_add(rhs.0), + self.1.wrapping_add(rhs.1), + self.2.wrapping_add(rhs.2), + self.3.wrapping_add(rhs.3), + ) + } + } + + impl BitXor for $vec { + type Output = Self; + + #[cfg(feature = "simd")] + #[inline(always)] + fn bitxor(self, rhs: Self) -> Self::Output { + unsafe { simdint::simd_xor(self, rhs) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn bitxor(self, rhs: Self) -> Self::Output { + $vec::new( + self.0 ^ rhs.0, + self.1 ^ rhs.1, + self.2 ^ rhs.2, + self.3 ^ rhs.3, + ) + } + } + + impl Shl<$vec> for $vec { + type Output = Self; + + #[cfg(feature = "simd")] + #[inline(always)] + fn shl(self, rhs: Self) -> Self::Output { + unsafe { simdint::simd_shl(self, rhs) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn shl(self, rhs: Self) -> Self::Output { + $vec::new( + self.0 << rhs.0, + self.1 << rhs.1, + self.2 << rhs.2, + self.3 << rhs.3, + ) + } + } + + impl Shr<$vec> for $vec { + type Output = Self; + + #[cfg(feature = "simd")] + #[inline(always)] + fn shr(self, rhs: Self) -> Self::Output { + unsafe { simdint::simd_shr(self, rhs) } + } + + #[cfg(not(feature = "simd"))] + #[inline(always)] + fn shr(self, rhs: Self) -> Self::Output { + $vec::new( + self.0 >> rhs.0, + self.1 >> rhs.1, + self.2 >> rhs.2, + self.3 >> rhs.3, + ) + } + } + }; +} + +impl_ops!(u32x4); +impl_ops!(u64x4); diff --git a/core/crypto/blake2/src/simd/simdty.rs b/core/crypto/blake2/src/simd/simdty.rs new file mode 100644 index 00000000000..008b8b48c0d --- /dev/null +++ b/core/crypto/blake2/src/simd/simdty.rs @@ -0,0 +1,77 @@ +// Copyright 2016 blake2-rfc Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#![allow(dead_code, non_camel_case_types)] + +use crate::as_bytes::Safe; + +#[cfg(feature = "simd")] +macro_rules! decl_simd { + ($($decl:item)*) => { + $( + #[derive(Clone, Copy, Debug)] + #[repr(simd)] + $decl + )* + } +} + +#[cfg(not(feature = "simd"))] +macro_rules! decl_simd { + ($($decl:item)*) => { + $( + #[derive(Clone, Copy, Debug)] + #[repr(C)] + $decl + )* + } +} + +decl_simd! { + pub struct Simd2(pub T, pub T); + pub struct Simd4(pub T, pub T, pub T, pub T); + pub struct Simd8(pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T); + pub struct Simd16(pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T); + pub struct Simd32(pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T, + pub T, pub T, pub T, pub T); +} + +pub type u64x2 = Simd2; + +pub type u32x4 = Simd4; +pub type u64x4 = Simd4; + +pub type u16x8 = Simd8; +pub type u32x8 = Simd8; + +pub type u8x16 = Simd16; +pub type u16x16 = Simd16; + +pub type u8x32 = Simd32; + +impl Simd4 { + #[inline(always)] + pub fn new(e0: T, e1: T, e2: T, e3: T) -> Simd4 { + Simd4(e0, e1, e2, e3) + } +} + +unsafe impl Safe for Simd2 {} +unsafe impl Safe for Simd4 {} +unsafe impl Safe for Simd8 {} +unsafe impl Safe for Simd16 {} +unsafe impl Safe for Simd32 {} diff --git a/core/crypto/blake2/tests/compression.rs b/core/crypto/blake2/tests/compression.rs new file mode 100644 index 00000000000..e27e5645046 --- /dev/null +++ b/core/crypto/blake2/tests/compression.rs @@ -0,0 +1,76 @@ +use blake2; + +// https://tools.ietf.org/html/rfc7693#appendix-A +#[test] +fn blake2b_f_function() { + let rounds = 12; + let h: [u64; 8] = [ + 0x6a09e667f2bdc948, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, + ]; + let m: [u64; 16] = [ + 0x0000000000636261, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]; + let t: [u64; 2] = [3, 0]; + let f_bool = true; + + let output: [u8; 64] = [ + 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, + 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, + 0xa2, 0xd1, 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde, 0x45, + 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a, 0xb9, 0x23, 0x86, 0xed, + 0xd4, 0x0, 0x99, 0x23, + ]; + + let res = blake2::blake2b_f(rounds, h, m, t, f_bool); + + assert_eq!(res.as_slice(), output); +} + +// https://tools.ietf.org/html/rfc7693#appendix-A +#[test] +fn blake2s_f_function() { + let rounds = 10; + let h: [u32; 8] = [ + 0x6B08E647, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, + 0x5BE0CD19, + ]; + let m: [u32; 16] = [ + 0x00636261, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, + ]; + let t: [u32; 2] = [3, 0]; + let f_bool = true; + + let output: &[u8; 32] = &[ + 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2, 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, + 0x2f, 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29, 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, + 0x59, 0x82, + ]; + + let res = blake2::blake2s_f(rounds, h, m, t, f_bool); + + assert_eq!(res.as_slice(), output); +} diff --git a/core/crypto/blake2/tests/data/blake2b/fixed.blb b/core/crypto/blake2/tests/data/blake2b/fixed.blb new file mode 100644 index 0000000000000000000000000000000000000000..39d4192093fb7ddaba517df1112e5f4e9f7de355 GIT binary patch literal 182 zcmV;n07?I1Y;R&>c`*P$cxnRoLIGI=#>V}HB~sFIkuOI;;aEpuiiYAB_a9Ul(q0fT zukKh=6NzL*lTNTpkUD5v6iByK)o*Yb{+r^?D^zG@AaQkRV{0H{a&LETAZBlPAZm4O zaC0DUc4cxPbZBKDY+-tNAY^Z6K&Y+Mz1{tj9Nu@*K;AE&$&jg<)t$1^)N kbND0y&w8Td%O1^;DQ-U$%TyEi?RUO&1X~l4Ox)I~7-1PsX8-^I literal 0 HcmV?d00001 diff --git a/core/crypto/blake2/tests/data/blake2b/mac.blb b/core/crypto/blake2/tests/data/blake2b/mac.blb new file mode 100644 index 0000000000000000000000000000000000000000..46522340d01322321a26c48b46accc028403a067 GIT binary patch literal 66318 zcmd?ygKb^iy?^BrTYHOHD`%&BW`rK{`01VBJSK|g|lg?kK-fQW?r1O*ih{pm9dOf2l@ zIJkKD1cXGyBrizG$SEkPsA*{F=ouK9m|0la*f}`4xOsT__yr&U)V&%fh;qNMZz5O; z??%NUNNxgv`!T1O@yIXN18!rK=^k@KyJnRLUM|m%IBf*%ALTLt)r#fGmEljR$hIM z+5IG~(-W$z=9oQXl}Vh5JM1-Q^(}R5#mAN2YjW9ISCb3hVbEdp|2@p_8&p70NLWNv zO#G#Uq?ELbtem{UD@7$`mDg`n)zmdKwccv$=;{HXDj_Z(j`zPh0^hoPs%QGI4OuVG znIk{oGA6Mh)VDu%CxtbGpGy>J=$28hd4ueuEne6wSxZ{yzjwnY#k^ktx~9ROQBxmi ztI^mfu)4DEQW@y1KJ6N2OP0Ifzv1RfcM4vQKqd&y&?az94abEV%e?NczeTN*!^1Z5 z6$?Ksdu#{glWX7(x~Jiv($fHtfN0FU_=d_q64q}z_cW)oPbpwoSz*r1jAb@p6Kx-5 zb*-cD<*w;=f+_b4ToPVQijj`p#T~q57w z8R6I8o#Vu((_wP*{FixI&0e3U5!c8Sj7oWkzUF`NC<05xhPa?}qN0|+dq6K=c z8tA6Re^OH;VBb291&;l`VoFLyaZ6k?PppGm>}fu^f2No2_zOLKO35}XqVH9(qpJpO zUv*8fLsC`sK5dLoHnQ_GcZLv0x*$%8TQU#j+N5m^9ewuXdojn*M2BO#n*P z+B_^2LUm*1q}mWv`F-O4=k|!sk`cC-8&hfTL#_LtcSEO@zg$bD4SI#<<6Ndc5GoHj zjG80v<6m!RqcsJ(tl6Je))c_3D$e)0V({guJtE`3D?;KY)-irJg&~|i_FgWs{rai+ zjM)}^xk=oLC*6c!lq*y~G3OUXy{-ZyS}rbkj=&nwZO#A0wq}6y=a*->AA^-jo=kDS z=3bMZNpmwlIWrDqTnbFOg?5bBO=gnS7>6#@eb}|lR6nO-lrlFPq_|zh!<;2s`8L-H zx~|2aS=Ssuu{V8bALU=1_wIchAx!q1WOMDbD>~6N`{&fYXKX1?+Fm4wxTf7KGpKyT zWhA(C6GQ*9Bxi@>-A)S(!SZSpg6@m>ANm5Pluo>BXW2AwpULRGcxO8s7hPQEBhQ!EZwqv)1k!Wu3NHI7_fL z?%Y!Z+9+i3Fc-M0O7QAy}%QSjycX@O1z9w9bVy5O*|tI9ni~3>kFfbm<+nH^`G3> z3Lx>|J_w~PM~n;~d~~zKZ-MZ7`Geyuhw88^{iGybD->5Z<+n$TrvYUA+W0)3!Ne|- z4>yQd@RHcHpOl?Mx88!TZ1ZPVwgzyb5+Tb{$WGnO*jii}@We%*5-v66ovn&KC%1jX zx;$@be{aG)mh9x-$)=%7&5rldt_+PO$BmxH+F@|s@B9vQXWKu$vkmZeIxe{5f%TNA zdTl}N<~5ekG>^NscN%3t4HX9$F9~eE z^T&}2YujPyLtn97m?1)b(7?VNxU$^@-P-;yXl(~TT^(_!EPubzzO-hph&vi!)H#oq zF@cjf{fx)fhxhC($>^31u`iu1`NUT0duLPbbZ=v}3*jV5Rxukd)V^9i=-Li{MQwXP zzeU5e!C*4xgXC6l8OcUV3%ci2&G(!P4rpJs8XjGlVH|dWL?Qt_`cA*IT}RLUsO^I| zzc;3t4$AqeAJx6WLHBn2OL{v1SH8aT8nT5-`PD7fxde7vC^zqJL>4O{2-s%KWr-7K z9Z{uB*RbTXOl>X4d|~BOy{n-E(vIFU40i;EF4hJlfiCX!*A#aI)~i*tS^Q#c5AOZN zlhkW@y|x{aBVSOu%$niPvA3baS#D$=yjxw;JNf{dZo2!vJpdY41#$P=8-dED)Yq}p z9-x~e{m14&9O2p)eQ z5JCE8+Yt^slSHiWrOSM>!uZHn4|E*o{}|`@{CE4?t`aS+tZi)V>>V7PfR)Ov13ypm zm=Bo+o=zC2T4YqRiS&Y(dF?viJBoYeN@~%Vpe8rrq5L0AXQel$YPos_ND*Ort!f3x z7NMkW*g#iz`Kzis1HSi<-!7o1dnNE4yG}#WAOqAWfbd;~liF9rVl27j$6t&r#Z7#j zH4rq11n0k7#2(2QW_??bw6CMdp-Wewu?OA#-Cx$-1t^)hb(BJBy(V6M#WHqP7V)G@ z=Dk(y4lgS&ZfAoUDTfrkj-|)D22pN=IW4&&#rHrevd~BhP473Zf)rLHqGQnIUH`iB z?*P}Viq-fRY$S)3!p;0m_daTmAe`8?J(02?1`jO+4Gb`eZQc+7MBk-P97R#kBX>!B z2UA-gq*V-IDU20FVemk=cl!(5y8=u0!J~ou0guIrSIm6R5aw}oSf})>Kd_lJG^sb^ zU<@Sdc=1Ny$Q?1qsbNXO@?9N}1&@jTOCKd%<-~F$w?*?|||JY`Yc^u(U9qkxW zGz<7k4v)XIzdO+Nm^je5HlWo{4nBUfNt&<0xWaK2UG1eXmG-Oe(XFqI>V`*bn2!DR z8QU@6?wiYr7Z=LSG~JGz>s60`zST(wJpnxbS^y8gact&!Kh22pZ5TXtd24cN(TjIv z#qcmYFGQ=`=$o)BmbgrtFei`@S>0Z)K03E}y=wtSP3heUXTjaq(&;nk6v4AIF z3#+xh7}+r+pO$e)ndRo$f9tL;5H$XII#Y$b+7(yCIaIpTOE*I3Z9+s=W|mrnT2#H#j1dZVH*CV_Kv>i+g#XlbO zEJ}@D@4DkluTPZHyTW@guQ{?|i=c@Qp;xvYTF?))q9u&<)B9!VST)GW`ZK&CV?mg& zYF}Cx0j==i2T96BQSgb>SQnTNRn9dnZkCf>2s@?kcs#oxk#%xt+xe+zA|cNH8E6N;AHu;G zxLvQAIqJOb+mwO8FWToOz7W}_cxL}fp`xlX`t+P1IcoyCN2Xqlwq}*T(KR(@cyjTR z(y^PQPBU*gLhcQZ1ZW8V9|OVSA*+91|gda7(*nFAZPMD7%db*$Dql|Xmw#y;fxnMfPdD!e#*MWbw z0{isB@W4xA_}(A|SQ?(}N0M`-CZMN9&<|q~2tZMBt#X>HaXd;;>66cFM9tuP$R?(d zwxbRJ3clyuUc7YZ774(ta8`qG&(9xga<|Eml{K(ALDWWSuF!mXum&0<_{YHr0yZDo zKL(EYW0j}-Ly1{GKv|i)HD};Oplf5Ev8; z#PnN1l=<*J0} z1bum^s8M(99Kjz$v5VzkD5Vtg)aj@2k{E>qz6#5!usjO!t0RC;1Wgk8qme`aZs7|$ z4#KIleC6t;dEa24ahtwqia3|p`gnN7%O^o?goV)_UGq?I%npMXqiy1A7U=P~4bJ%D zP;=o5(QWGUGH8>iAI>Bac%x0fB^GAZ|CP8|p@J9Ut?kqxqyPf$%fWrE0jj9P8&CKP z$t1{^{3Vqbx#Gda91Y?FPsMxt?oth7RcRxqUw}r5{_#+v0E&y+)G?JZ`9wY!*0_Un zFE@POys})k6uE)~Z3jezO_M+)gz$T3mFW>djKqx)8K(;7T$&^OFRvV0#B$%WeFv=) z^8>0x16;2Q9P3X4T#p~+FBAy%)6sD3zWTR4gv}`_T=S2>DeKj;nbODEGUHTQB=zxgcMA9+z75*ijB5g8R76AQGj_6D0#u&%y*(k(A6T|M;_4QHVP zUtC$Vv%GfmJGzL7<3^kEQ+g7r1r#r9k;cem92MO~&VoaORpG2ioC6%tF!4VoOdJqY z<^PoPDEtBwr%ESYtBM6Iy(gx7MU&`A~M5z(c{hbP%VlqFT-kWjS)CR! z4z1De5=87VnT69h=b8I~lA`%EFQbFdYILYksi&KY{ERLilRS9^v`)$otdk7PPWDP| zpyMJ=3!R#Muj@+-#3B@kmUt>b0}tI{)3{p6rFE)mn0zE$?ddthNHGujUcjtm(^4*N zcVf!c+@5d*G|$H$nI{F1@2eYS9rjQ2TD>h|W-M!48RGvquvA_@`>y_lpyq7G184D~ z2AYGpQ6eIlWo)rUc-p}TYAarZQOeSjQQS3g&_1a@w9iKXfz#4$axvK{oozX7^I^4b zM5mgQ*MC=-NM5yjeOON9F;j9`{tNBPoG|m0wR8V2F<74Kr%h%#Y%8Aa@6GSP?`%l> zv4K(n!e^?3W;%nP-adH<@A6j+7g7rJznj!09?fg1AbaGP>Ow18{0-lXPkXvnqAyP! z@$0kgU0dAPg&fWSOEMdDc+gV_^}h-M={@R;OF>H)w(rZN(6*X_icr-PU*I|*K@m#Y zX_PnJ);TCPW)+onZb~AWC{rrneS64$7g1X-3GLbuc%7AiEEzcaK zfoboJag2ki<+O}+$OjiC(>8Mhs|uPZ<3}e-2kNPY3}B9lF#K$n=2Sk2?;z3T`Wf#U9=Tydea$M!UpvDt%c_ z<&OMDh8Q&{Tmhs6C6+~TzB%X;RAb%&r>RA-SD=-$e*&c}po8()i`-?9rgGlLMDV8H}Y7|!5_)Y z`5Bn90V`p6>C)=GldJ4#k8Tu|?EX1M-bUq5gcK(y@#eE;2L)nsPh3-!bPsr{Hh18(r-mWBe>Z#NP+Jc@=xj%(d4!|KwAt233qFKRW=k1S!WLi32nhY5dPzVL} zMm}eOTPP!InO|k_q|Dz!FI(_r%-58w&WoVBl=&587sixU`~zsHyq^Oq7wAS38Oqw{ zpDS@n^1zCb-&@SQu{P?7C^T1-?Cpf)YNTlUDpN`FL~jrcS^v!Q0WP$bTyb^o(+&69 zapsr2J$lem`9FzN9uRay&d;gQq_dJt87U-8PJL0jZEJcq!j+do0Tpt#KYl&-b#}DB zII=q2ipVK^@|ZFvYZlM_^_TTJ!@M*7nikMh1wRW_K0s-rBe-NqmpsVK_BzNA)BM@X z@g10qs`nEwTBN$!llyvQN)U!p+Fz{9ERLkbM|y-nrYO^8(Q%CtCnvR{Mp65LldI# zB<{URChwWRJC*N8slB8$pTeSCG$tj4=k z1u40yj_+USglJNtfpN})h=?!)TI0s zCRPe`q;RF49d5@F_^W8(t?EU+?fg7K?*4Q=baspR(5UP(tyl%XMM1qQY=2IKDmIiE zqW-LCDT|nTQ(5=wgmaz`G+Fu2Mpgz$?@NEYpg)4?yu2-pk8H9RjkfV2ksad5*a(GW z9#_Fq#P@J{`>NEHp#F>a5_;6Q=mRVEi|frM0`=kn4FjFWpv@|NI%16$|PZ?pnhvPoA!sGFw@G?Pi4x6}aLYXh=^3#2(kdgG` zZ21DmBI3;bSwE$RQDdY{YER+}PmeL6Alcw4lo4pQ>YtIV3W#k}#hE3H!s%_XNLllM z)jRM)YagBZj7hC*yCZDe&_+c1Qp=RfS2EjbEi8Vjr#!}O%yz~Mwo#qIxxOY;`6Fnz znxE3G8X$3XSsFLS;5j!(;4N@&oj+nagOXG+_&{nbfrxVTvgFa05B)^{`Ny4dYa{rn z7aM);TD&C#+mq`o!YEe^M0=p&YJX0+8bFivES3Qh=I}abyGGi4N2|4Xd70Lv%wIR( zhK^nWtymz2unStIzhd3xzG=**9_sdDhO?0#Nk4Ynwz?K7;VEdjx}Q|87VwNtzGmZY zT2FO4k>ijrC8{msf?CPg`es_{_?awa0y3W|;zR}5lH)g5i`eGseNU)w@8Ids+ZqA& zSZ3j!F8Kdk>VH>$h17j>3xipl{ zr=NAGR6UYN*!F#im)NhU5F&=|2yZPA4#BTq8h%>4df+q_@~}joiJoxtvdW}Fw$;I-3@HV-iih4-BaA9x`oBY6$3y%Tw?d`0T zxAyyEG;aRPOZLY_fUw693KZ2~cqZw>Ntbi3d$K+zP1G0Ae9b>IUlV|F!Fu%F24)zK zOa@MtVlpr|kcr2g-J)Z9#^&j*yJF#rfJMX0cQdGbTE5be_cbe9QuLQ!gt1II;fxlS zjj}XA`#t>!e!!#pVLqZU;69B zlfZWf6wf-ohQwCarqo17Jfm^f#%|TAN*D#KDJ@lsJaj`D!g94_&!|_B}zzNCl%$pu@1Q1ffI$DGJ?7_f)yRud$2 z#4~NOZ{D_kes9trZcWLOp~7qmM{1xCaR|?b|GEmm(xTSf;qAUgu9>@La~yTJ1w9Gd ze|Ew)V2-q9iId%MQt$A9XP+_L1--OLHB_(~ zqh;+F5Z15}otM=g9D6%q2>7{sgOlak6od>s2%w2IEqhx(-+`Wpoj*Tf2Y^=FglP;- z^s-Qxm2cgVOUqlTvEzkNXuU#488;NcZU4*B7UH+@4@tI}mrc;ATq>>ESnUNT$QG_S zU&wOnVH zsO+XLSxT?yP5y1}X2i~Y3wYLC`|P==K0%-vyMG17E?|UNi%Krp==oF)x-*68vMHH< z8&6rS&+UV=`q#kT$xk!<&JGrgxFRZvP_iYpu1XV5ES4SFXUwOS*Zu~JWu2fMdwvPW zZh-1j=aV?-5{980#2XLuF1@|g5L||2DMu}9MK`iusLYRp-%g|xyM;v?XcSIdovKeX z>uDNhZezP_EE&`l!StS1m+7wq)UllP8>N6uQfs4*#|kLLUDBXq_5Gt*zvU&Zf9;a4rM0cSqqD2Krx#$1&5{@s zwGMH+kVo@}o@S(_s6n`x*!1jozRuo+SL{ufi@H0{5+)W_<+=Wxe_Y1&56({kXKvFrzG0Ih+rH70X^SiGKn?D-si zb222o211^aROLn11ZdOakTKgr(&?u?P{>Y23|!AkahT8GgkZ6Y;v=KD*gmxrR48%&z{1R9pgZnUiWgx&DHIo7BFok8{vI>xKRp=<;J_c)@2>m_I)#yX+o`&;HCJBIFwG912nu7p7IWN{nGxBh&bj-8t)6^KwNOY|kRbFp0ZPkms zD#_D@3TR|34Tw$pfvdwfW9syG6$m=0q?x|VOI!c>+!*aAy_E#`PB&q5#B7tVF0W5_SS zQr<|R>N3YC+!OKbk)!6ve&pf7Qn)nmyW2*8Ezl9*6`D#uby?Sj;l>9UEvDk6(q~f5 zYGQH=Su)M9v9`b4;0ru7-aghedPp>7y&PZPM0^_8Dus#Kq1W8#Bct*d{Jpi$znJJK zfYT7ra;MxxcGR>?S63g+FLvRm)3Do8f!Fa`hFT$rw?VTzD@?+M6{vWdVlV4(S*P(a zT+I8@5feoRhRyW@Ea-31FTWb;XFx4c;;y30Zn(hs6RzfC6^o7;%vtRV552mCTWh@Q zz441=beY)J#)IyY(I;4wy9Y>6-H0YL*-!&b10pQdgy5g#gYgedfh3NhRlC|0_(*mq zg(szs0o%ze&&CxQ#vG-&mY}GqM5}F(pDMh&UTkABB;DfK$J=y2c}2-c#D2zDgj6+# zy$E`&$Nph13`{KS=Qy}{_ymMR#3V0B$;c@vsiF604nV4Bv+1NQaxwv_F`S=BX zlqFkV|G?nT@W|-rFF@HyF}#ji6O3$lGaPrfM)rNC4w!F80}!>@ zm<;)8Rp0n)LtUJZUYyI?!Wv4i4M*cq5om%&9sl)E$ACsd{b+)IYms$z>UE+LJY}2! z`=)63$2%rmDO~z{^ZBgii<bIP z9S01WoDkj?azwEwKpXRakV4!#j5|%UFlAHmf^AlgxXC`!OMd62(_1DaWmtpIDS3vL z2y@2$F@$@?=lwvkaU%Ga;7 z-Jq8U>Y}G*uiDGp2@eJ$gRRiGW>D-qL{S$SvRkZohj79FicbBKu9LtfD??SDS8=@N z6Vj#?iG<|HacyM}|3o=6QP)6ahasrX?drw6TdzH(^`bma1o$}#ueNCBw?vs=iWH1_ z2;f12{vMeAHDRX!exj6QmhE*Nte`40JpHO9xNr7v@q+u`w$@9V`S-+P8sL)4-grfO z77M-zj$CX*%UN`C^SBp@sjAr@FX*5Kf9i7P7nPj`?oIjBu^na}`Au!c#pGBtJ}O9( zfg!}0Cl7Qo%jgQAw-BS&=CQ_DNRzUcKUR!kCwfR5o`|!`g8$cN?w7Tl1;QE_{N-@A0l^4fHzCD7k|;%#KKWSr)&K$42tD-mRp9xJ;p&EGMV#hwZ0EL8jQQVybk*+moyJ$j7GnHoV(H*1QM~guKBlQ zyQ4ACx|si17m&Vb46mG63g)ah)gA9b5&OC&zI}%vDE*u-ZPbAYc0@cQ9E$;cJM*N& zh+IkW&Bh^R|0*%JzklJkZp<-OrdObYE&StPKl8e9YnOSLa0)!|(+gJ4+=A$*1v z*B1hsckx%|T>xx9dzU6&XV@+Dr+<>IRJMoFOQL!#rIZb68%fO&#HBzrsb~d{y#sZ# zeX9+T_*T$(vHLn25_dCwzP~Ob>jL~OzolQ=cM)jE$tTddC!M^bIDBJ%A0Ym%Y}FBR zXn$jW05V~%*HJOL(O%Te;~m9bq&3?U!fMXfSPrl){EoD3Co&=24-w!WzWnvq23`U> z!inXpUTwB@kv1(^h1x=RMx#DVpI*B!&)3L_xJ+LeVb@xhRt>bSmldp#@x#fcfNdSaPa3pjBk zdtXTQFC%$nm~yMBP1OBLA*Kb>K_jpI`pByQg<@CRPT0TTIiUv-#_|1AN zrs|id4(`mMc-%KNUSwVkM?nibPL@}X&B#PM5<<%Vo_ zBT^qjO78sR(a+Z6pVbEjY37b#b*Pz&N8@~)Pi{#lE>z|@oM7LMbrw~^?8u>hrE%&< z6N)d9sfcR_{>kbae+TAuK>s3ms6x2c2y5 zpCtQFe^!>e~7S0H@#ELW!;!VbE0{WHNbwbFx~D9C(q z^!_C+fxy}`^BzUVA=ETT&VwYc^)y0WcO7H~Qsz@w7|_sLe-G$Q;OeEba6;yH=)FC- z73EDG%zQ3;92QIFIh%bGZOG$dT(aSpJt=p21x* z?0}Zu{+mc|0RqTPkbX^jX3pw)q14onypf12ubWG6w{dF>d2sA(89dP`UEcB!%=wR6 z9>aaGFSR=(7(nWPIEYs_j=s_vv;a-L^LL@%1|}S7CsY$02OKKu9!L{K=EvTR*b~mx zvtthStdohM>?ura6%TP@Kk@8x3xtyNRC$gw?;m=lf(P6U}o6mF?oB&h>8;@3?Jg5WMtN4bJXE| zLrV+uqf=Zq=W%?`HRUQH=C|q-b!Gwon!Z@AqLXnioh!J@$3=^Y0-qSI_4p~xuUS%7 zV;9-z&a0{r8K~y)ClR?}KD%s!|A+kWZ{>Xeyhk0TrQ><3L3`|({zaH~+UAVxvqO*A z#}rT8^cdcWB6zQmqVrGnBkFa*5`k1zb>f%a#k3O0kLW5&`h}jAnSq|*M}IHyLjYg) z>-U*^ud8)bXW*7Qi-1}6L*#m?_0#tFTy;Db#? z45H6Odmb9>>qnr)vHzJkpp_Dh5o(Z3cLZD3*{dQiszk0kb+}z%8dw{&1pg4sHw14X zw;q5o6B_Pi_km^dF0uuQYU#`IOu4{|18?iyY2QLt#CKDws&^-_74t^ zfYLC_$lEIOb$@;w`TQf1kd8>=t1FqqGfA7Hz#)iP3aOqBQK?2|#+i!!m>wGZecv-x zo?FIUt9K&PZ7~L!ilE6){%+*Q0M$LG>_mhW-P6Lft3Au$mHiKiyCW?Xxb{v)5p_d%PV{_V_9fK21w0L=vZ96XV) z4>P-pJ95sVmWcGTX%|^h;@aMv%7@hXij8yZj!(zLGT z;2%D5_V+_S1(2?llmaGA{k+|#_sdaiFl%=e5kzZtC0xyI`{S2W`H=HX!o?aPtoofg zhWXH(#JKxmJQp!_`!tcz^@ZCX*@2$w=YK=>GoUi=8F~1kzqf)G?L%u|)g(YugxW#A z$tr7>v<&eL+1zE2fxqvG*Y4hPud!>BK+I*AfQovuV2Z(*ohCl_P0qhrRH70qn~AsdaJn=;73Nfurs? z)j_uBS*_4AG?Jj*FaMVA7XWucDCe{a+Sw6jos)!DCI4$4^VcoQV#zs&vsH3bFgw+ae+j%P`8r}{wAiOc*&lV% z)(mfQEVyY!uZK{j~z&@_bw-`};D5!J3`a!fR#`%?S)ZRjr2bT$=n#z%$?u?arV zQ~vsIDt`q;i#Jm}v)im%GZuCYQz3wTtDj^MG$)?)Ir({F{;65ys1DIR&jX~a&nfq4 zc3ZJ42YN+kn;o;YArt!0ETzUQX!@JKEB!T4NvyZkJzsr6xPUgc+vjl9IOyS+2#?_5 zd7VEA7h9@nKl?pFiT`@|I;oxSkuQb6%JLCJAC|p}&dOxkT9^a)U)bmW)E;nh_<9{E z8u|t2NYK{Nm!FtLt1e7tKjoWj>b%5zhyZ0A+FWR^6Cy)YG?U}6+fwl1i{&q8=gjzY z_)hf#lBT3U&x_lCn(e1Oz4|{dqmNHc&(1F{udZ(ZRNrYIxbm*D$KCJfJ=9-_y-Clf zmpfT6{A62+exLq8F~-uQj=D31b>C~^s)XboyGN|{JR^Pe2~KMU`O&0tFKGO4e_#At zKvu&}+ItN9{-?1Ysg6?2B<@)fc5(COl&#)taN z9=U#sPtw<4D>9rQPeJS7{f+g%0VbM0&4~zTSe2hgV21*{D85j`NRvC=zdxS%b{G9x z`NdWujuu;%1AVgfh;AZ1d62)8$nXT)#R;QdN)nNMB`0Y9`@b{)9gs`RA*>R{!}O*e zTNv`p*y5FEpvtKeO1m z^u}IzL$xJ^L^*Bq9Il-B1{1HI#-srB0DS*@55NQPi~@d&p7L(!b7}nT=W8+bc!Kvt z_}!@1x9J?z+5Ay2rB>RvcrxH&C%^de)nubuBDmgoA#?Cq9MXwR(Vu4PfF1#ye?9`h z@tBv|w|YW*E(JCm3n;m0#Y|qel{*?3T<+kwkQV}C7bsqqgBZr&3lX&q30S0v7nkM2 zGn7BsKiLynMbw_w2OSRgpNGQ%{4z_KEZv=yh;U=*DHQcTq3;Ij7OBrnf1|MI{`S4^ zCNrc&_NCERBd^(7GEz)JTDF#gKIxakfTL(O_Nff#y$EE!)9 zl|jeD|DWRF0cBX;@HAL2MN{cz+nr4eDOzP49vbuP_m8n_lZ;F1B(Pc$KQy|0akXbs zcqTn%=E{;?zd`HRwSo?Va>1$Yi3mC$^uOf;SU$hkT)ZkSNPgnMX!EETZXo48E{a$V zLx)WdW9!4&MurEwjSIR`ZVI(jLijs&7UtkKb17pm6WSb!G`|;Hb3f4-?>*I)KxGmc-oSK zeMo7HJ(Q*=K+Tg@6Q(Nla(HSIqZR*EgSl@ebROu0ME^@dLcouNkbCYGw5u(N9IB>E z;tM=2W!BGp1+#4#)Pu%iNaGH3*Q>&QlvZ)ZS1-utZ<5nvxJWt16L!?=F!60X1HtbG zC;s0e5&_Dw%NkGf_GS9c32Tw65p0@P+@Rzxm)>1se;$%eVV-@BY{8$c?)OS55*i6P zoCceH(kTRQi>=)W?kl?tjIcOpMw0(EBQY?7B4;`fsEWYx04*~uGkI&Uhu4fCC?8b3 z0MCZQyK8|xNF3NLWsL-pCfy1{+`9|eqSIXhKd5x-+Fm7N5b_>$$QS>6ND{zf8xb}W zBde*vy4P*aU*|ndJM@HHcBOy}+(Lc)nuRh|@JIPS?;kswG9% zPfb1qV_67+PD%PNqQG+JZd+>;RH&O#PI zc_ua8uyIgO3?8R8>ttpg);TI}?-%11`7Zc?Kb%MQuf!w;h=^+6>*v#@2`W6pna`h) zIz`fI(>>g&j?ExU{SbkB^71rcx&PY9eYnZ3%Lw5Un|ViZ$RH-wiIu5i(^1QoHfT=r ze<>#!@TD%kY}ui~xac+Y*N-W}hI;G#l{1@kQFjvkEyS``6#fFM7`Y18n=J)UKoD6~ zEbO^!(Py{)D>VLgB+YSj@aN4b{b0OgaBC?{OoMMJ- zoN?^s?=Oe7v|HL-pXy24;J+YW4=C_GBVfW{N!(%#IO;Ri0RQ9s=>JX%v=plGJwEfY z5gygWj~zCFdG@&~_4`dfK52E7;Qo`NoJ+{K3AjhW4WYzh@57qPUWNt;-K#XpSzNEA zNXZn|eF8nQl>Z_a1t4hBJ>(Ti9=|~SUKqK9pLbkk!MZ@y&>IG-Zc4c_sWsIzf?*45 znKSCSZ|ZZ=uQ->*+4R!GIcm>cZ6LCc7&AaerTSN+QUYW_vh!$shJ9Rp<^6;hXKG8@ zX=uZqe%{%S)YFb!5lQ=K=U{VAVO`k+$krld6{ljtmZFZPwmCgBH#lA-s~>{SO8qZq zr2<^WW=t#?&rmAGUOS@MWDuAO5aXg{zSm*S5yc(EX}_jmKq3-VTVNSUfPK&;Vdceq@Ci4v50wCr0+MvA6{#g z-cgZJ)-Y^Wuc(LkYI{&q7r8g^_2`l}H5=MAF?cJU%X1F&y9$yu$(c^U3#kN-hr@_g@hJM``?sNA-*aHkSP)?L zz(d%8j!XAj;?e?Tbo_@ewI}_8X}LzYTDMWrs9^LLjY534odu{E>F%B;HpJFc^Um(I z0!Rb+Wkp6SNz8BQ(B7brX+p#YeQC-DotOSM<)s50qj&8}xx41Z@X}}Id@Ip{-0`$Y zM@y9*6aC&}H6byGWF$73KUq|WPiTN?R>u|jz-lVqG4R#w4AEJmFPNqjbYO z7ET9`lY)BfqsU2PBiAwQA+a` z2R$)h{-4YMyw`_n!Y_Qg8|Tc(JCep>%dRDvUXT2Yll<7xT*cbY+b>H!?MvKz9U(+b z-(;1N;dj|`>kqjhsMX94^y3kM-y+TYo9&o@&s!O*_1WSN+x#R>JKw!fJI)+R&~M)r zhUDZjIU8r1vcE$#`PM$loTJIQ#{sJcX~jp3`r=8013;N$rS$2-4KyChZx783Y}pis zR%a~>Z)1gXrTe<3OA27G7sA-{UXPKKmBqeSly4AX(Bq_jF-tEf0VnHi%HBRqNh$M8 z*C+;&>DoIi6Lf0U-;tUHc&NI!O7+h%JK_pv{xH^@Q(d-V_=elChCuPd>+dih{Ar1^ zsC4V2!f&fX*GuUaWie(dm91Yf!+n>fR?Bmc2LA)h_IqNp0%8nUtq^a^+v_)NoYD+m z!S7Srt*xWogch9w8I$`0u_H!tHFqx_u%1I#LqV|`E%j0eT)lLur!vaS=2pYzV*$<0 z{=0Is0pl#*(KVuq^W&k-njeT&{jvUrmX&8$A z;~TgR7LL3&_a9?K%a<3Mfd2;O_ z!)j{Q3sMaw?~vJ*X^oM$5G1>m4Yc@2`UYMj7f&2%ovKBTg@GpL{GG`;fa^0`)9y_3 zK1gN>ZmWaAC)$ok@S}aw#aP}B3C7P2wH!atxuzXlSuE~dj9*w47K=E&d3TBlJ04f^ z8ad1+3H+@_uHPG-6JW&FR&H~Vi1GI6li$fx8G?`YAa(y373P;p)Nsc;Ym4=KT=r3V zU~*J1`(sggY-7Kp26`9d;LW{bpaQ;&3;b0P_wUZm1)OzJnAhp)IiYt5c8PQk5wIyO z-_K*oK)-pu=(A^yD7_teR>UdT0QFc4C$Vb94z-&V)uBx^ILonL%^3SzV`Cu)o{-h71JMtSA7fwV%+!@Pc6E0Uqy&i4!UEyhxYr zkbAe?4*l${qoV&br;|G$E34Bz-kW(CVxfUrrClRo=M{g$ZZ@H-=hj$wUDuc~q-Hkm z4&ZO4@PUcX3ygbS6;ruHZ|xH=pHx+s*rY7@bk7?*P@Fno4t~!k2?#PqJ=DO%K_x{8_22x$_*i=$}rAu z-HJ8-3`&V8@Nek_J%)gRk%bp5Ry;$q|9ZWGES?cS^Ns~IZoKsq$w^VYqJ2@n(1~SI z+3q-xfB$pi+zt4Z=ilL+UHQ*_Ru&dUEg4BbClCZV2m$~Qot6=3lA=lLz4+yO`z?`M zJfbPPZzI(RK7Zl_1B1QLoZ^m}ZG_#k^EW<;S>M$WqFO31TgYQ>t}REYUQJfvf$ks# zx`QCljj4nM=_e2g@s>&O@yPyKkMOcwUl+sJcV%6oP0YgF?4Z5)e5qo4XZq0ZaT%Gn zG0|MpBnJaoG_PT;1-}Lifi58ozJw5v;5oHCTUD6fQwVY)j*n z(Sd`(8O3Tr+n_H(Os6uJM7~D4Fxa-RO(JZTta$h`DXpA8INGvWWbS4W>?+=!N|JcVp?&7d zExMxtJs6^YL=6!@Vk-A>fAhKowzY(>?I)(f&RZZlm^05i+?JES3@GMOq-is-S>bc^ zFcB?sYHRK+qZCqP6-YBj7uh@gj(lwhx(D3<*8_ML@{k;H_10sMdkBWRWa>E+dd+2a z$)140_>$6dp{4p&67N@8U5zcacRc92v6Q2Y@DF+@kL+2}l#0$3R}aA7h!FcjL`8wQ zH`FuT9Ec(&rGC`8V(&Vel49QNPDe)jL`Q`$^av3f*9E}Pn~emKO3=e1`G<9p0KQfdb;*4c{BpF=hH)G^shIl8lB>^M zK55gNIxba-sZ}m-mhc|B-g|jcWYl)Lyp2OH0P-ch#V-8~w7*A#krwDOQh!_-Nnpm$ z0WEx9Ip-U@T1P29vFio-2*FOj6az#=MRySFz#D9L&kZ-%gOB8Q=|)v(PmYF@5Lh+0 zZHrcs*Nh=>;Y2~Vk^TeQNC9=xr+0!^Ws8;!rkTqeNJ!t^k5jovhn_?sT3Qu9xf1V! zH5PPdrSTeLBM8BIOBDDHmOkEKv&U62*(|>v3kG~0nLo0QG+=JDuM+=h_=SdQmEUwN zV#&eaM4|rP#Nk=*ZhN2#j;*eIN!LV3@xZqh+O>A`)v3t*p=HYe7i9|(p933%Ha*b8 zBm0N;kpWH$X&%XiBk2VRu+tm4Y6jw4jTONeTpkig_%FeD6tg+|%vQnFPr)B%)S1kB zmRlq%K)NXl@I<#|ET2$W9SnmmB=^S_k_83}$zp9MN?O|^-wiLkp-Bt9EuhRu7+!hWmxb2n zk1I?JUzN?ly$RA;Lj~7cGh}T@*lVhRRY(U{_>A&C;iw5`s`pdGMA@e~czVwMk9FWj z$6^0p3QT<~Ttib!d)tpXx?q0Q1~&A31}-Fwil7rR|4#WB4KvPfB16ZG`8MyoU4}E3 z?^Q@+Ruz>AUXzr2?+eB>usM?W)AV5g@VfhEaXMQHdUbK%n}h|3%j~?1O`a1xf%uY7 zXnP}C-?_Qj5_O4%BU=rx$K>u?a+}Axy1QCuF~i_^y-y8wkZ;vVJwf-&cZs&%!+`Gr z|L<Kz0<5pnh|Sopo5g(pANhXJMN2Jd83~F) ze#Jd=DbAw4i*-EiF+25x-K{9@WyW83omqjK5Ayydo14Yl0IdpCf+_&;-k?WM4J}yk zub$x5-{&2H478>04bAOt=f_iCD686(h!?#H}sWX`mQ(%!2KkB_+=aE1f zDOYw7G%H9MtUy33dHiCoL~Sj7Gq-ilVYPCv{x+gaiur}posd)z9@B1>d_+(?|ESrh zY2kIe?Oph~P!%WFE^zSe$aIQN{7?tlby6v=AYcp0rusZ36_GhnEcJxf>(j45ejh+5 zstF_mfrB*~1^g+6Zz7y^#qieo#WUV9yS&fdHL5-OE-5VTusE~tSTblBUOBLnfDtq8 z0AZu!kI2;`q;>XE_EWP&IzH?(uV}=a@WNxzNbxJznbN&O?4fzcvUJoS6Gj_gq&$ZB zsw`NZdfbKn8MKU`BpDuX9~rlYryGUyS$teggxSWK^eJD4`Mck6F8Wn6pp4_A_E=k? z2ajsI_;7*GoW_3;e1_COf2(c~qbQ+M;g+Cj!OEf$0JXtR49#J(=?Phge0@Bv{Mzhd z+~0FTj*>QHdhN(BTbl-DfXQEf5?_5rPZ$9DTQ+c&#v(T@SUdqj}3^} zboX+c;#HJK&gMco*hpr@w}(UZi}Mc%3_6J?1Op|MKOfvVH>@5~+{nS{p2s`Z-JIsx zH893nDm_`fywSN1hN+vjtl!{=S3wT8(WgU`)&%AMis@c=O?>JUA0hy~i9(czI|a-& zsseAy`rC@OKJj6pCt7{K_U>J0{nuEuJ|pL@_r1XDVzE1873g-j3DP`M1{wY8_kO!{ zB@N$NQf1ZKcM7zQs6<@|kZa#tup&?it=Rnpvas|8W>@TFFPAJyF%|N?HI>;{wj`$Y z9QR%Kco}~X8qE<7M;GSjxwIQ2&15`M1j+{dRI5;B@`%9Z&7WUjE~UX@lXJ9eQiYzd z=3t`T<@q>7&GNEFOW|hRQ@*6d90O}7mv&=2hjZ+rDoDvI3=<%*C+D;8r{ zH62JW$>-qZe{rRaqdE(n+8T9@@oe{S|BTf!^=-;$+el3I$-Coed zNM#cvfJ2H4)Pi498ov<5JFn?B@@zDD_YFkwS|6fc#T}E|?8LR1F4xO?IOc)u%za6N zEjqpe<^}6#^WBXq7N!zU@E1iSr5huGR%4fW1ewt`5N$UA@tHYnKWU54K#&?ucW`b= z2dNsz5$Kh&LZ<@yVFKnxyWfev#YhYGrfu9bmSO%eAzubM$SCC_Nx+vQG0%^ANfrEd zWEkR*#Mx0ZAWP(7dS0Y&Nw&Y;f5RWA zEds4nQ&Cle0oVJ4lpdmc31c|_@SX>uou)j&^!Nt~s$+2o^|EcPfP2W|nk}x@#FGSD Yts>M;(jDDIyOCr)5_`-Ay+Gys4=tWpd;kCd literal 0 HcmV?d00001 diff --git a/core/crypto/blake2/tests/data/blake2b/variable.blb b/core/crypto/blake2/tests/data/blake2b/variable.blb new file mode 100644 index 0000000000000000000000000000000000000000..5d150c0246f873d1bdf6136e857f96e14e3d513a GIT binary patch literal 53 zcmV-50LuSjY;R&>c`*Pivfv*kIk)FZy0E)`i1({{=}V?5EIL9{e4>bBQdy-A-JE@T L9D9u}FNTDUhs78L literal 0 HcmV?d00001 diff --git a/core/crypto/blake2/tests/data/blake2s/mac.blb b/core/crypto/blake2/tests/data/blake2s/mac.blb new file mode 100644 index 0000000000000000000000000000000000000000..2c5f3c67c5c9fdc25665e7412c3583691ebc7593 GIT binary patch literal 49870 zcmd^|ha*?*|NjZuC6tl4jBFYxTgc3w6(S;gX3w%SvLbtBWpA>xSN19^MD|Q%{XW0- z{eH%Mf3JHq&_D2cJs*#Az2E0L*E#1pnuaEtnzmN}0^$iIWR#PrXy_Q2SlFjd-Eq-bh1S6M@0{RsUEXVA1e^1C>2U&b z0u52QikJAz(h|!k3X%(G?1e|5#UA{3vEPOUF604nV2tKzH*g?mF?Pf zb`DN1ZXRB~8~g%-H-&^nM8(8!Nk~db%gD;fD<~={-@bEKMOE#dy2gD?El_K9-xR+a z@pkzl4_A_0(L#sYG=1W{_NjmqQEpwlb9&I2+CL)Z15ihXzQMhaWggs*;1HLnjOKXv zW8_DKnsyc1m`^y3IZvQDb$&=rZGhDEwreM;Hc+wdmbG@P6_$;uUq=%r=3wSzl2NKF zCLJ{B!ygk=2cTC>uga18H8b)LY{+{~^WN4QL|rf~A-|zk;dRTo;}$fj?hi`(5STS1 z850sj2IM<(%&y!kiK^daB^#)-?i>)i>i)F_?Ikp--j9l^3+|kAPp91M(`Wf(?++acTPXP{a2e^^#Mu*sRu+rXcnLlr8)An1U+iOenGbi$T0{P_){ z+gk>e3ed0yKQ633ST)aesmckvA$A26T{WzzzdvO?x?R@M?b}pSKY2X@ex5M=foTmu zYovD@A^U|PeB#mD9tyqF30L~6#CrQ8-Z*+hRpMZ+L**L%$hd~Ue(I3-@Wkb2Ip=i8E^2~=O zHvPegO+Y{@o4c94<;raF#c{=@rP7%=+Bqk~a@0I@f(0b4NndDWvmYJV6tEb_$)6T~ zq=##Kg7CIe*(l5HxO@`2ZiFwxPPwZ3nS;>G=07~M8Ayq-8pbGp$zg&j(r*9AZyOK6 ziaNLd&O0nJo6^fXi144E#g7kd4sOmowZ5)2{`@SFjHD@hx8Di8L?^6C%j*Qn<>6Xq zCQG2IAN_>X7Qi|Kk)F>|vSY4rKHOloorx^;%z0z6^>E46$7}9-gYdr&%byYZ5qNtS z=eKbQNh zYwK@&mNhmpH8Zz(WNBp$@V1tpw|Yz`vj>y-<5*eDTfN2^c++lLIuwLixfm3J4vlX6 zv!dGoOqOR-A1*QN7JK4dx8)zt(IS_-eF5*Ptg$#_I*~vd{DQ>pr)9SVbLppQ?YW*7 zht7UBXCK8+co1i`?&at)5m^{uR2X;a1XR5J&kJt{C|h+)s;7skhiR;ghB5HcLfH2d z@7ujZS9=y32Aa&rpy?fcVtRXke!+hd+k{TH*Fe{?UoJ>TSzr{igr^MwxsmY$0%{U` zp~~@R#&-bDGIr%gM6VI5wNtGYl$1TZo^(B>IA3RIr-!RRrqcKts^96S=63{f8V*z+ zqnrL<(Qq=zLOaO1#tek08U_}YR$;>nCyA|-NRr8i>8Hagb3EaIO^wI>HB0l zTqnb7>#}^99b2Io?uP-x4disU5s5JMIWrI}S9AN_enZPsM)XeklC`4y-85T4f;cFL z$D!bG2XS2y#*-YjwHIYi(dbZ&@qan%+G&YcVrqsPfiWa?BBB3N+hlIovWPY4WnI?P4blWM8C(F@Zks=DQ z)1W%Z6#rUlm#a=PH5A4Bu%LJWM6N6I-L$(SNo46cTsce{8K8yyZgwiyi2J?kiizr& zP?o2MhQ%AOF!y5SVvlk^7q=WJ36H)-9bc_gGi-ddX6SsneVOAqD2&hHfq4oVH{jGHlZg$ zN^{&U@~5kLh%ihj8InMNcAx>p@jFa7zQBtuC*#B!*)g*RkKWR}mE=CVlJ~B_1*wCN zcMn|%#~=dAnJ~;)q%Yt;#>2iDGK3(dz72|IggRGnqnwXz#$`g21o~%W0Buv_!Xr- zc#ntUxn`=3?ypz7Z)4^c8R9I?(FsKgJZwk-pyvMCaGz5YK1V)rbT7{{9>>9zd55nJ zI~U{D{4blFybomxI&@5dpqfZ8leL~Po2PCNo5(_y&VsmMCJnf!2g%g=&50)NLZN~W zA5;(^0QuTVMBPaYY~)#|#3qGWS-j`_!PA!QRlav^sg>~6t&l@V6$~sjy{?hCPDtE$ z*j5ctq39%NZ!*DL?Z3TYX=q{V$>j_^SkDh5RtT8sTuc1++IxG}_PR`)}dLry^ewSFC)_{Yrb!^68NG0qaW=(mAN9 z(0{A=AJ6*z$VrK>pZ~Lfz@Xre=Ya9a!Ycze7hYuX%`1f2A8+b96iqjdi7i?&?KyY^ z$CpFF!VV``D7b&Eb)$eE#Uy^hoazOxn$e=r2YWeujysJTy_3($pT2>Ty*Q*~VZi*t zRiRh=YtH(b(jw1q8D5mJl{5KzarVIaE#OpOJ9hDm&1@9zxip zIMHvTS_i+ji9Eb;5kMI&mV!ns)5gq7{UpN~X~EZEK}mq#hm_Bgi1AbkVFPqnMjc|h zNH7%pYH4(r8Ncjq&}&8_k^NqUO8eTk!i6(T5o?3M@`Lo1Z%9Zi(^= z=a=gQ7nTe#m>5y*T8y&jzVP{I!Eap09BRI3FuuWBMKOuy!tsX8EOz(d%3ABa7b$T> z5>~SY8=pQn!6)3YhZ`^k&^RDZxU;&woKM5aWHCZ4ur6|VgHRvK?PtBTB_>VR4*dn< z{5v5adQB;fAp=vRc-@v?pI1;(sN){x{$uZlQL@5uAcpvUL6 zc|&L9RLJhK8Q&_RchNKyGV$<3CV&?w$~;Fm+HmTU_QYP@9-CO-doNsI>V-cyc!Bcu zb3FJxikC-#G7(7oe)xFd(#+Zo!8GK-7xTM;VG4wntaz``BW>@svb}u|J(x*H0rMrO z7}mxgSkixsAzsrtu6u^UtF=Q3S>XWK$C%|UsN(ehv$r5+hx`BY!_uc?%%bDdv~8p zo#e&)EnHXlYC-A|Ax#0vQk7~o?xV3IGaB}KFHD*9Sd|FHlrKA8N@4bVX?>y}dQj7j z3Ti5ND>GMII4@Vxoauj86rY$s`CN$>B@m(#7@DZuc^5nfo4Wv7I~rXL;HSHQ-(ne|4^LTF(oVvXS!+jH?Z z)I+G*jGM^^$JXbxipQa}8ApgV9XMm(OBY$%OAf8BI$h_#E=VB6gnZUX)yrW$@ZUl*Xj*+&aF3v4skd19f&N(u{0JdtYF zQpCp`o_>6lu{JH}0Ed@vP7X?(bHs?Vf&7Cj)cB8CUbM-nNl4)vkLH_EtG_0~<7DI^ zzeD$wKmdxId(@C~z^3LY-5%$>Y#D@I+6gXKim-*j^4S=lsZJ^P%P~AGkD$zXM~*oc z$e&BF)f?DHKA_2S4LyHQTcx&hbw}U33$dX#H`syJ3<{lp^q}*=<1QWPG46bBs-@S} z6%VLxS=Xh{1(ba%T*9Q!?qJfFhf?GICpE~fOe82w_!NaXgw>(u+_|W{fBW98Nt*K* z1}mR!3{JzJv@7_}qW`)P$l;m8y-Lr>%*xKm&C3U@%1_pw=XfE>%~Hh)+pCxJKI7V{ zZJhFXh)!1c2_pplS5bHru?v7L|Cu?%{(D!*9xd_rTD591ewfOU9lj6~eUg~yLuVQM zVSu6|$z2HO-QR8Ed7Ueb-0Jj6ICIM`$JR2%4b&v&=vzBbjQGHxyDmPO;6=bYr*F-B z;oJ@4lM$iVnCQHkYKa~EOLT>i!C1EezJen3Z=>Xhk{5%{y;cPd!Cjhevg`5=H~@gx@eOEbOiKC!CMm>fhZlq*^*5BRM4uGzftvH zc8oiW6UBnUqT-U$*Jb4upqe}%!Tl^g+Zam@YTH6X^eS~M$Love42yS$u4bGbriBWq zI@$s%L14nY>ILiwC1>xtst?I`PYE)ip1j2$FyXlKIDo9@58S+~KH>(dz#W;M2+9u% z>X&g%UlHT3P1ng=8%t^_jtZ#O$ZtRPdI%i^HAh`RH5iD+H^;hCwH~NSJtM?xlD5Q01a#M1bMqg1BfshlXR}p&l6Qbt&9w;tF30ttyE5WPg%JuO>`Fk2Yg> z=SKKe-7@?%(Re&WG=SKyI^;sgRB zFet`Dcp%XeexACmxBF2>SLR$v?m(cBa1D`9Wo+{x60`{ZZ|MYhadAyrY+CnTJ!)Z6 z6ZN&VFOwD-M#YgiyQojbg1-C~TDIx8%Kq~v$cKAMTUk|I^QN}0zM&D|HMzMYbz&R( z+I647wn}A+G~M{B6WaT6L?BLQI6E9bRWu(L6;0sDDf4?1>Yw&F{q9yu2-m*$ik|)& z82F0f^}{|>1#$%jsEd|kET9&2o zwS?B=Bclam))U&IbM0=;bo6c3UhnxDSyZ1LZNqD z-X)L0e%4`R8I!Bb1J4LPL4CYERzBJR=U4C8A(t86R%c0{XLJ{uvuzC;)M&OJHLM0V z6A`2DL4|Z2FClNitIH}A#%hbh+&DO`Z}7I&QAli5RRl@(9Xdr<@7q|ySCKl8nUN0Q zAMYi-&K!-i!clGr5Tn9Nd}(~g(r#AjRoHbN=pgAjZb~{q?~}ZYCapYUZx}M2z_3RB>0o2La-*f`bx@0d^ma&?I^uZE9|5ZEJtq(b)wg`8mwko$S0`qz=>5$e`ND$0Xn< zjLqf`e3~Er*uewev%BZ`N$Cc9#%jXT^-i9lQx#CT6#gzj3LYE z6T~X-v^`~Tau!ztsjENZ%((@K5&@*FjRyE|=|7fU`T+NkTwG=5OX4yCi7Drh0)}ZR zvYpeNHWXGaw!)pA_2Peh>Aq$;q=6+77PohgG)q2C=_H$&j*Nj0DQabr6K*h(}O zcdc?}Wi+n4_`W_@D}>+>YuoV*I&j_}Upeo<`Pld{eC;Tk1AcZhx1h7vaOg5z7)Z+d zq;B{OntN`MLG7ITZ94!|5__t!*ISG@zls|bjn-B@vs{!Ur{|BF&~v45Q?V9Wc=)#q z|M&Owj^4bwyQjCWe_(Lv-Fx7dj(Wb`&^#z@+1y@yeDERO6J;UIM{Nzkyky~ji!#twI6K4+SWENI3p_Z1DzV1|DYY5bTQ8Ux-@R46w77fT}uh1u>sFtYBrf#Axo?pU8a9c@fd zjR1dz^TTmhG!Bv?ZR!G)Z=xFPe+n5jb(F@%RMichLq?!;#4KSox4H`bp-minM<2kQ zVVhi(2VtlQWjBfHo*^h8^n~$DTIk?VBD3WpQ{_oRB~2cGNfV$NKl*}`otAv^(8=W) z+O>7Mef*dB5xgl@=;Z>XmLp%GmZp9IOOqh+5*7ZV$?>JR zaVw)C_Rc#17ck`zjov&Cc#^8vhEt zOf;b{lGQ%!(_6C*UuR*cs@Y#f)h9qF=&Ix%x^ulz<#l^ll=|ixhN8iiXH+8{mAl$@ z3Dqg6tGQps)hsxd`!pY)EsDXFn?%o}*H`a&v1S$HiZ%Xei!ba@S@XY+tU2IY zHiBQyvLdl@8*eIJKEa|#|6Sidet_XiCC()oTE%owTMNICt$Co={PM+n0;!hew!56o zdy6YucuAFwG^;a~uPYX;2_G9nbuIo%x)wlzW^Lt-o6jytyJ%`Ed}PbRZM9G;@9 z?01Xyaq8p>)YsB4e+e_Gy$IRXD^(yW8*K-`ZLI)s(FOek4cc;oz>29>t{>q%P!mYe7-Pm>)(Bj_g*t}!sB4LInj?OpgnA+Cq`KA4dOetOyX z1+A?ET@Aze7tsn{yAGRT>jQ7hmr>N>)A+L5757hWhMK-;feyCMzoNDcaFf+ww0K-@ z^P-IC%1{BLfJ%B4PdC3VIU{ceX%*{q7S!A3FX`R3u&yIQM&H=I6nRfmXD@~9 z88bin8l_X;)?>a#La4YezoxiN;8r&8cCuUMIhpTyUXPS&95gy|SDwA+iV553xoE}( zB~Wu)zo@w{U`fY>clopveG~=V?PjNJw$CJs96V+>-P6(I^jJ@ic|p}}|ElV?K#hEl zxOSbrxMqDz2Nfc^Wha}#rK?S!-^pXMc%92sgYV-{^trR2FGE&V*VZ>aZ+_X@2C?-*i0B`RZ8saUZ2Jsp zv{e0isq54Fq%PXLe-Y`+B?XnY^Xtm{3c489Etog5RVls(u<38@%Ip@Le#V^CbVuZR zVt!xx`vIuE-Cx+=4mg8^8RT7-l&wvD(mdT{$*bfM$XFI9@J>MGa(c5C7X#I|_bcn$ z1$wPS3~o0ORDH4LahrraP<07?-(f7!q%|d}j!xiSgFlwC|4aMZ1MhE2oV{bOPK?yG zz1U?e9xIsqu#HC6ax9@3d9sW+(iJ)Y4}NWd`+%>Q?IdxzZ1jFuj6%(l%Gb`c!Q1&) zR5DpBX2X{Us79a$iGSZ9n0@_BMm5T%+CwJ=as8T;VT1PiEs7a#Ze)Ua5{i>(@QrlN z|9){|K;5ph8%Jr|XtYX6fWpwSXE<1!QW7wTvTi8$BJ7DE{JVrC|3mfjfSivlw0|07bvhRnLn`Vkc}C|JSreSHbYTb+x!?8m`9`cNa+0> z{25!)|1sqSz@6qjiqkQT9uQ*Q)T4ysqH-zBnzcilvEdfit{0OU{B3x$|G5DvC^~Cm z-s7?qlbq2NAS_LZnp9)EjJRjE9m{muPWc)Je1#i&BtSJ+gFqhooz@R5ahG|qh^y8o zNt-?-(k{4b*BUJx$Z10>kV7EI0AS=rBQUYT(tJ>x(5|!JP&?o^#a9y~WKS=ygF$*K z55B<$1+)h__`+U&iTgYemMjDD)zS2Id2|0$5jm`4r?^?sL-fP4;5+_P!kbV4A3~S0 z%OuTO{9b3!ydSs*c^)`Vl8DV2SHy@`EKP;gLv>O8fi9GQ)UuVl0p0rqlI3bjf`Dr* zCZ=u}rvyDpho$1;-K;wJ#Q)+SX+s4xtDZ((O)Br8!!#6;w9HF*iOxqHLxUH>lDd{( zK2rjpl=^7-q^%TYYyCSz|TAffnTo|i}BDFS``l92uFVjLDZqRwu=O9#_-3R(F0FgU0uVIz7t<2 zGCMYXwjTM9ac^mM6!e7HT{-#OMPU-!jqy)(V*p+RAI)CaW_&pz;|V+7vpR57CXmV2CO|K}a@lg629ClR3?FaODomjKdEu9n+MqKApZ6#`Eyo#iTA zp)jRebUfne*wnGwrl>gHch}Eo}@fsV@%Zi&lGh)EMDw&QG&EOtpmx$)0YU-w0|vM z5)M3bhEo5Esn11@0kSt|hH|2?-7m+JUZ^r&gdZc8Ki~8!kbW|XR4OA9Ttbf;SJ8fO zMba|HUbEZ4Moc)T$0X214vNb97rL^5i!qI>7Uhll=poGy3qG$<)oUp4*fwj|eVrn- zT+u%z0d33nSK6`yBJQS{+Hs%!(+byL(PVyD6}T2jrTq*$5@eD&bkU+T*S zRB^mbPSGmmB`l5ai!+{MQBosZndK!*r>?d5v_+>a2?f6X*BV~~s~WgNe6;Swq@~`U zI}7;uI9e>4lbK{6SFK%_H|PSic|LBzaqM8XJc@x<@1w{RS?B7XmhT=-kcNcNZj)n$fJl1 zFL`Yg@!=-_NqVqEk?qg~H~wY(#|VE)3# zO})w#>=nyxQ`%G-j4V9t%GBKu#TbmK zAJ6N#lUg|s3g9GZSncriKvmrQ1}OwVwmk2NOU;5YQrso%3tb*Tl=NdJv#!sndum6{ zn+0MLLt_Yiix@Y7B?)>jaj>8l{o{7Lr5lg^aOZC}G;Uz88jH_8OAidAhvq>2e>uQ( z6Ry&AK|geqVzCWvjSTNS5t1!EX49w;plZ$-NC}Q6# ziYVYeTN!uBV%u3WMpZGu91C$~N-T?BC#<*IhK2m{wV-Wi7V&SEMGQ!cKNHauerjck zNdCanPnQ)-F7cjDjhCdVhp2aYvkv^F%UjimzNr5_B<<&N?PrTbVZ*!PNh+-fa zEUJ5DoNn_cHRb!7fd`+uqy7IxfN0k@IV@UZda~k|vi-;GS7#0A z9zo$`{(mVnbPP-^>{F+4{^nP`!R2)YSJRH+#iUw$rO5l1GvQ0C$@H&6t_o#Y>Aj&z zDTGFn{nn9WK(ksa_v)JCspU%-yZPBo1H?TY#FgHRlDbZm(@#w4l0!4eee+DRps%xV z07X!u*MLx2Y|~)p_O;h( zax@cIe<9zxibWD&bJB>>393rrJEW2aFJ%jS*^(RGCB9~9P%~SFqn%@?uhwz8s~U4& zxQ>-+3>r)Ed&E)zIbAY4iZeEyXGB&C2cyFm@=mWf-Fv9fUnDfIqAj5bzdfe(U2-V` z)-Ttq)5*hSmp(SeS#?gV$C*A1Q+bqp%;N@ zSfuD~w~07?o3~Bp!grQekO<$vZ@u3BPRW!($6Lku?4}z7S)#Ng&V5cz1y6d5kp&+; z7rR@B-ywee7F61u?-lJfcqsg}!wlajJUYEo4W09&#{)mo34inZ_Til?XvU;MRnTnc z|CJ3SXIeXadR)j*_)>tlsJ(maHQub2Hj|_gF8z|Qf-imwwAS7Ks`ZUd8#1zT@(PMd z%D3+TWs*f&ES;L&K?jzi@X!N2`?zvOn7i zMm4l(>Q8sC<)9>#AP0AH;!B}#pciF#LDQ*z$8;*-hD>9EHA)%H2Jp@cUvK@0B9*CY z?&QCH#dms5wSWBrG@jb`jHe0+Z z=DYV@^QnQDk+hdLIZmYA_Ql3((=5GA?q-|pMrtzCdl_lv7Fj=hK~nwu2D}HRaQByO z(XNUc#k-xOTUX;@^AJD`##vBqz;`v!>Os|lD%AMS3Dp5Hga6q2c1De&bZZv(YCoOt z1I-EMdpQ?F-L}{e8M@$?viHAtL=8aeD?U_uBTRD+^^G|HinLzJz^x^w=YsN&DrSWT zs7T-!PMY66<9* Date: Thu, 20 May 2021 15:02:09 +0700 Subject: [PATCH 038/134] fix test imports --- core/crypto/blake2/tests/persona.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/crypto/blake2/tests/persona.rs b/core/crypto/blake2/tests/persona.rs index 4defcc8016c..5c2d06bb540 100644 --- a/core/crypto/blake2/tests/persona.rs +++ b/core/crypto/blake2/tests/persona.rs @@ -1,4 +1,4 @@ -use blake2::{Blake2b, Blake2s, Digest}; +use near_blake2::{Blake2b, Blake2s, Digest}; use hex_literal::hex; #[test] From 0fca391c4aa14230b9e7cf4ccacca552379dc324 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 18:50:33 +0700 Subject: [PATCH 039/134] add more pub methods to blake2 --- core/crypto/blake2/src/blake2.rs | 151 +++++++++++++++---------------- core/crypto/blake2/src/consts.rs | 3 + core/crypto/blake2/src/error.rs | 41 +++++++++ core/crypto/blake2/src/lib.rs | 7 +- 4 files changed, 120 insertions(+), 82 deletions(-) create mode 100644 core/crypto/blake2/src/error.rs diff --git a/core/crypto/blake2/src/blake2.rs b/core/crypto/blake2/src/blake2.rs index d40a89f1868..8a8a95054ef 100644 --- a/core/crypto/blake2/src/blake2.rs +++ b/core/crypto/blake2/src/blake2.rs @@ -1,5 +1,3 @@ -use digest::generic_array::GenericArray; - macro_rules! blake2_impl { ( $state:ident, $fix_state:ident, $word:ident, $vec:ident, $bytes:ident, @@ -7,6 +5,7 @@ macro_rules! blake2_impl { $vardoc:expr, $doc:expr, ) => { use $crate::as_bytes::AsBytes; + use $crate::error::Error; use $crate::simd::{$vec, Vector4}; use core::{cmp, convert::TryInto, ops::Div}; @@ -29,6 +28,13 @@ macro_rules! blake2_impl { h0: [$vec; 2], m0: [$word; 16], t0: u64, + + rounds: u32, + } + + // Can't make this a const, else it would be great as that. + fn max_rounds() -> u32 { + if $bytes::to_u8() == 64 { 12 } else { 10 } } #[inline(always)] @@ -73,42 +79,6 @@ macro_rules! blake2_impl { unshuffle(v); } - /// The compression function of the blake2 algorithm. - /// - /// Takes as an argument the state vector "h", message block vector "m" - /// (the last block is padded with zeros to full block size, if - /// required), 2w-bit offset counter "t", and final block indicator flag - /// "f". Local vector v[0..15] is used in processing. F returns a new - /// state vector. The number of rounds, "r", is 12 for BLAKE2b and 10 - /// for BLAKE2s. Rounds are numbered from 0 to r - 1. - pub fn f(rounds: u32, h: [$word; 8], m: [$word; 16], t: [$word; 2], f: bool) -> Output { - use $crate::consts::SIGMA; - let mut h: [$vec; 2] = [ - $vec::new(h[0], h[1], h[2], h[3]), - $vec::new(h[4], h[5], h[6], h[7]), - ]; - - let (f0, f1) = if f { (!0, 0) } else { (0, 0) }; - - let (t0, t1) = (t[0], t[1]); - - let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; - - for x in 1..rounds + 1 { - let x = if x > 10 { x - 11 } else { x - 1 }; - round(&mut v, &m, &SIGMA[x as usize]); - } - - h[0] = h[0] ^ (v[0] ^ v[2]); - h[1] = h[1] ^ (v[1] ^ v[3]); - - let buf = [h[0].to_le(), h[1].to_le()]; - let mut out = GenericArray::default(); - copy(buf.as_bytes(), &mut out); - - out - } - impl $state { /// Creates a new hashing context with a key. /// @@ -148,9 +118,7 @@ macro_rules! blake2_impl { } p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap()); p[5] = $word::from_le_bytes( - padded_salt[length / 2..padded_salt.len()] - .try_into() - .unwrap(), + padded_salt[length / 2..padded_salt.len()].try_into().unwrap(), ); } else { p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap()); @@ -167,9 +135,7 @@ macro_rules! blake2_impl { } p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap()); p[7] = $word::from_le_bytes( - padded_persona[length / 2..padded_persona.len()] - .try_into() - .unwrap(), + padded_persona[length / 2..padded_persona.len()].try_into().unwrap(), ); } else { p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap()); @@ -211,11 +177,33 @@ macro_rules! blake2_impl { t0: 0, m0: [0; 16], h0, + + rounds: max_rounds(), + } + } + + /// Constructs a new hashing context with a given state. + /// + /// This enables continued hashing of a pre-hashed state. + /// + /// **Warning**: The user of this method is responsible for the + /// initialization of the vectors for the first round. + pub fn with_state(rounds: u32, state: [$word; 8], t: u64) -> Result { + if rounds > 12 { + return Err(Error::TooManyRounds { max: max_rounds(), actual: rounds }); } + + let h0 = [ + $vec::new(state[0], state[1], state[2], state[3]), + $vec::new(state[4], state[5], state[6], state[7]), + ]; + let nn = $bytes::to_u8() as usize; + + Ok($state { m: [0; 16], h: h0, t, n: nn, t0: t, m0: [0; 16], h0, rounds }) } /// Updates the hashing context with more data. - fn update(&mut self, data: &[u8]) { + pub fn update(&mut self, data: &[u8]) -> Result<(), Error> { let mut rest = data; let block = 2 * $bytes::to_usize(); @@ -228,10 +216,10 @@ macro_rules! blake2_impl { rest = &rest[part.len()..]; copy(part, &mut self.m.as_mut_bytes()[off..]); - self.t = self - .t - .checked_add(part.len() as u64) - .expect("hash data length overflow"); + self.t = match self.t.checked_add(part.len() as u64) { + Some(v) => v, + None => return Err(Error::HashDataOverflow), + } } while rest.len() >= block { @@ -241,10 +229,10 @@ macro_rules! blake2_impl { rest = &rest[part.len()..]; copy(part, &mut self.m.as_mut_bytes()); - self.t = self - .t - .checked_add(part.len() as u64) - .expect("hash data length overflow"); + self.t = match self.t.checked_add(part.len() as u64) { + Some(v) => v, + None => return Err(Error::HashDataOverflow), + } } let n = rest.len(); @@ -252,11 +240,13 @@ macro_rules! blake2_impl { self.compress(0, 0); copy(rest, &mut self.m.as_mut_bytes()); - self.t = self - .t - .checked_add(rest.len() as u64) - .expect("hash data length overflow"); + self.t = match self.t.checked_add(rest.len() as u64) { + Some(v) => v, + None => return Err(Error::HashDataOverflow), + } } + + Ok(()) } #[doc(hidden)] @@ -272,14 +262,11 @@ macro_rules! blake2_impl { self.compress(!0, f1); - let buf = [self.h[0].to_le(), self.h[1].to_le()]; - - let mut out = GenericArray::default(); - copy(buf.as_bytes(), &mut out); - out + self.output() } - fn compress(&mut self, f0: $word, f1: $word) { + /// Compression `F` function. + pub fn compress(&mut self, f0: $word, f1: $word) { use $crate::consts::SIGMA; let m = &self.m; @@ -294,25 +281,29 @@ macro_rules! blake2_impl { let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; - round(&mut v, m, &SIGMA[0]); - round(&mut v, m, &SIGMA[1]); - round(&mut v, m, &SIGMA[2]); - round(&mut v, m, &SIGMA[3]); - round(&mut v, m, &SIGMA[4]); - round(&mut v, m, &SIGMA[5]); - round(&mut v, m, &SIGMA[6]); - round(&mut v, m, &SIGMA[7]); - round(&mut v, m, &SIGMA[8]); - round(&mut v, m, &SIGMA[9]); - - if $bytes::to_u8() == 64 { - round(&mut v, m, &SIGMA[0]); - round(&mut v, m, &SIGMA[1]); + for x in 1..=self.rounds { + // FIXME: this might not work if greater than 20. + let x = if x > 10 { x - 11 } else { x - 1 }; + round(&mut v, &m, &SIGMA[x as usize]); } h[0] = h[0] ^ (v[0] ^ v[2]); h[1] = h[1] ^ (v[1] ^ v[3]); } + + /// Returns the current count value `t`. + pub fn counter(&self) -> u64 { + self.t + } + + /// Returns the current hashed state. + pub fn output(&self) -> Output { + let buf = [self.h[0].to_le(), self.h[1].to_le()]; + + let mut out = GenericArray::default(); + copy(buf.as_bytes(), &mut out); + out + } } impl Default for $state { @@ -327,7 +318,7 @@ macro_rules! blake2_impl { impl Update for $state { fn update(&mut self, data: impl AsRef<[u8]>) { - self.update(data.as_ref()); + self.update(data.as_ref()).unwrap(); } } @@ -388,7 +379,7 @@ macro_rules! blake2_impl { impl Update for $fix_state { fn update(&mut self, data: impl AsRef<[u8]>) { - self.state.update(data.as_ref()); + self.state.update(data.as_ref()).unwrap(); } } @@ -428,7 +419,7 @@ macro_rules! blake2_impl { type OutputSize = $bytes; fn update(&mut self, data: &[u8]) { - self.state.update(data); + self.state.update(data).unwrap(); } fn reset(&mut self) { diff --git a/core/crypto/blake2/src/consts.rs b/core/crypto/blake2/src/consts.rs index ab76c0e1724..fed82e0ddf6 100644 --- a/core/crypto/blake2/src/consts.rs +++ b/core/crypto/blake2/src/consts.rs @@ -1,5 +1,6 @@ #![allow(clippy::unreadable_literal)] +/// Message word permutations. pub static SIGMA: [[usize; 16]; 12] = [ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], @@ -15,6 +16,7 @@ pub static SIGMA: [[usize; 16]; 12] = [ [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], ]; +/// Blake2b initialization vector. pub static BLAKE2B_IV: [u64; 8] = [ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, @@ -34,6 +36,7 @@ pub const BLAKE2B_SALTBYTES : usize = 16; pub const BLAKE2B_PERSONALBYTES : usize = 16; */ +/// Blake2s initialization vector. pub static BLAKE2S_IV: [u32; 8] = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19, ]; diff --git a/core/crypto/blake2/src/error.rs b/core/crypto/blake2/src/error.rs new file mode 100644 index 00000000000..bdef0b82004 --- /dev/null +++ b/core/crypto/blake2/src/error.rs @@ -0,0 +1,41 @@ +use core::fmt; + +/// An error that occurred during parsing or hashing. +#[derive(Clone, PartialEq)] +#[non_exhaustive] +pub enum Error { + /// A data overflow error. + HashDataOverflow, + /// Too many rounds error. + TooManyRounds { + /// Max rounds allowed. + max: u32, + /// Actual round value. + actual: u32 + }, +} + +// This prints better looking error messages if `unwrap` is called. +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use Error::*; + match *self { + HashDataOverflow => f.debug_tuple("HashDataOverflow").finish(), + TooManyRounds { ref max, ref actual } => { + f.debug_struct("TooManyRounds").field("max", max).field("actual", actual).finish() + } + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use Error::*; + match *self { + HashDataOverflow => write!(f, "Hash data length overflow."), + TooManyRounds { ref max, ref actual } => { + write!(f, "Too many rounds. Expected fewer than {}, got {}.", max, actual) + } + } + } +} diff --git a/core/crypto/blake2/src/lib.rs b/core/crypto/blake2/src/lib.rs index 044f86dd4a1..673dc30c61d 100644 --- a/core/crypto/blake2/src/lib.rs +++ b/core/crypto/blake2/src/lib.rs @@ -103,9 +103,12 @@ mod blake2; mod blake2b; mod blake2s; +mod error; pub use crypto_mac; pub use digest::{self, Digest}; -pub use crate::blake2b::{f as blake2b_f, Blake2b, VarBlake2b}; -pub use crate::blake2s::{f as blake2s_f, Blake2s, VarBlake2s}; +pub use crate::blake2b::{Blake2b, VarBlake2b}; +pub use crate::blake2s::{Blake2s, VarBlake2s}; +pub use crate::consts::{BLAKE2B_IV, BLAKE2S_IV, SIGMA}; +pub use crate::error::Error; From 83a1d11ea4001e34b46cb771e6e1eb685c4a5b79 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 18:51:05 +0700 Subject: [PATCH 040/134] add blake2 state success tests --- core/crypto/blake2/tests/compression.rs | 76 ------------------------- core/crypto/blake2/tests/state.rs | 62 ++++++++++++++++++++ 2 files changed, 62 insertions(+), 76 deletions(-) delete mode 100644 core/crypto/blake2/tests/compression.rs create mode 100644 core/crypto/blake2/tests/state.rs diff --git a/core/crypto/blake2/tests/compression.rs b/core/crypto/blake2/tests/compression.rs deleted file mode 100644 index e27e5645046..00000000000 --- a/core/crypto/blake2/tests/compression.rs +++ /dev/null @@ -1,76 +0,0 @@ -use blake2; - -// https://tools.ietf.org/html/rfc7693#appendix-A -#[test] -fn blake2b_f_function() { - let rounds = 12; - let h: [u64; 8] = [ - 0x6a09e667f2bdc948, - 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, - 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, - 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, - 0x5be0cd19137e2179, - ]; - let m: [u64; 16] = [ - 0x0000000000636261, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - ]; - let t: [u64; 2] = [3, 0]; - let f_bool = true; - - let output: [u8; 64] = [ - 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, - 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, - 0xa2, 0xd1, 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde, 0x45, - 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a, 0xb9, 0x23, 0x86, 0xed, - 0xd4, 0x0, 0x99, 0x23, - ]; - - let res = blake2::blake2b_f(rounds, h, m, t, f_bool); - - assert_eq!(res.as_slice(), output); -} - -// https://tools.ietf.org/html/rfc7693#appendix-A -#[test] -fn blake2s_f_function() { - let rounds = 10; - let h: [u32; 8] = [ - 0x6B08E647, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, - 0x5BE0CD19, - ]; - let m: [u32; 16] = [ - 0x00636261, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, - ]; - let t: [u32; 2] = [3, 0]; - let f_bool = true; - - let output: &[u8; 32] = &[ - 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2, 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, - 0x2f, 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29, 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, - 0x59, 0x82, - ]; - - let res = blake2::blake2s_f(rounds, h, m, t, f_bool); - - assert_eq!(res.as_slice(), output); -} diff --git a/core/crypto/blake2/tests/state.rs b/core/crypto/blake2/tests/state.rs new file mode 100644 index 00000000000..385d2cc90dd --- /dev/null +++ b/core/crypto/blake2/tests/state.rs @@ -0,0 +1,62 @@ +// https://tools.ietf.org/html/rfc7693#appendix-A +#[test] +fn blake2b_state() { + let rounds = 12; + // Initial IV with parameter block. + let h: [u64; 8] = [ + 0x6a09e667f2bdc948, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, + ]; + let m = b"abc"; + let t = 0; + let f0 = !0; + let f1 = 0; + + let expected: [u8; 64] = [ + 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, + 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, + 0xa2, 0xd1, 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde, 0x45, + 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a, 0xb9, 0x23, 0x86, 0xed, + 0xd4, 0x0, 0x99, 0x23, + ]; + + let mut hasher = near_blake2::VarBlake2b::with_state(rounds, h, t).unwrap(); + hasher.update(m).unwrap(); + hasher.compress(f0, f1); + let res = hasher.output(); + + assert_eq!(res.as_slice(), expected); +} + +// https://tools.ietf.org/html/rfc7693#appendix-A +#[test] +fn blake2s_state() { + let rounds = 10; + let h: [u32; 8] = [ + 0x6b08e647, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, + 0x5be0cd19, + ]; + let m: &[u8; 3] = b"abc"; + let t: u64 = 0; + let f0 = !0; + let f1 = 0; + + let expected: &[u8; 32] = &[ + 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2, 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, + 0x2f, 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29, 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, + 0x59, 0x82, + ]; + + let mut hasher = near_blake2::VarBlake2s::with_state(rounds, h, t).unwrap(); + hasher.update(m).unwrap(); + hasher.compress(f0, f1); + let res = hasher.output(); + + assert_eq!(res.as_slice(), expected); +} From bdc0904ccd102c5b5e9684bbe3f4921d242336e5 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 18:51:43 +0700 Subject: [PATCH 041/134] cargo fmt --- core/crypto/blake2/src/blake2.rs | 6 +++++- core/crypto/blake2/src/error.rs | 2 +- core/crypto/blake2/src/simd.rs | 14 ++----------- core/crypto/blake2/src/simd/simd_opt/u64x4.rs | 12 ++--------- core/crypto/blake2/src/simd/simdop.rs | 21 +++---------------- core/crypto/blake2/tests/lib.rs | 14 ++----------- core/crypto/blake2/tests/persona.rs | 2 +- 7 files changed, 16 insertions(+), 55 deletions(-) diff --git a/core/crypto/blake2/src/blake2.rs b/core/crypto/blake2/src/blake2.rs index 8a8a95054ef..a3a34e14fea 100644 --- a/core/crypto/blake2/src/blake2.rs +++ b/core/crypto/blake2/src/blake2.rs @@ -34,7 +34,11 @@ macro_rules! blake2_impl { // Can't make this a const, else it would be great as that. fn max_rounds() -> u32 { - if $bytes::to_u8() == 64 { 12 } else { 10 } + if $bytes::to_u8() == 64 { + 12 + } else { + 10 + } } #[inline(always)] diff --git a/core/crypto/blake2/src/error.rs b/core/crypto/blake2/src/error.rs index bdef0b82004..75774c0b336 100644 --- a/core/crypto/blake2/src/error.rs +++ b/core/crypto/blake2/src/error.rs @@ -11,7 +11,7 @@ pub enum Error { /// Max rounds allowed. max: u32, /// Actual round value. - actual: u32 + actual: u32, }, } diff --git a/core/crypto/blake2/src/simd.rs b/core/crypto/blake2/src/simd.rs index 8f244eaef1c..c3f8d3bcaa9 100644 --- a/core/crypto/blake2/src/simd.rs +++ b/core/crypto/blake2/src/simd.rs @@ -78,22 +78,12 @@ macro_rules! impl_vector4 { #[cfg(not(target_endian = "little"))] #[inline(always)] fn to_le(self) -> Self { - $vec::new( - self.0.to_le(), - self.1.to_le(), - self.2.to_le(), - self.3.to_le(), - ) + $vec::new(self.0.to_le(), self.1.to_le(), self.2.to_le(), self.3.to_le()) } #[inline(always)] fn to_be(self) -> Self { - $vec::new( - self.0.to_be(), - self.1.to_be(), - self.2.to_be(), - self.3.to_be(), - ) + $vec::new(self.0.to_be(), self.1.to_be(), self.2.to_be(), self.3.to_be()) } #[inline(always)] diff --git a/core/crypto/blake2/src/simd/simd_opt/u64x4.rs b/core/crypto/blake2/src/simd/simd_opt/u64x4.rs index 0a6972a8771..31bdc620938 100644 --- a/core/crypto/blake2/src/simd/simd_opt/u64x4.rs +++ b/core/crypto/blake2/src/simd/simd_opt/u64x4.rs @@ -46,11 +46,7 @@ fn rotate_right_32(vec: u64x4) -> u64x4 { #[cfg(feature = "simd_opt")] #[inline(always)] fn rotate_right_24(vec: u64x4) -> u64x4 { - if cfg!(all( - feature = "simd_asm", - target_feature = "neon", - target_arch = "arm" - )) { + if cfg!(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm")) { // 4 x vext (NEON) rotate_right_vext(vec, 3) } else if cfg!(target_feature = "ssse3") { @@ -72,11 +68,7 @@ fn rotate_right_24(vec: u64x4) -> u64x4 { #[cfg(feature = "simd_opt")] #[inline(always)] fn rotate_right_16(vec: u64x4) -> u64x4 { - if cfg!(all( - feature = "simd_asm", - target_feature = "neon", - target_arch = "arm" - )) { + if cfg!(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm")) { // 4 x vext (NEON) rotate_right_vext(vec, 2) } else if cfg!(target_feature = "ssse3") { diff --git a/core/crypto/blake2/src/simd/simdop.rs b/core/crypto/blake2/src/simd/simdop.rs index 891456d9c53..32190519f02 100644 --- a/core/crypto/blake2/src/simd/simdop.rs +++ b/core/crypto/blake2/src/simd/simdop.rs @@ -46,12 +46,7 @@ macro_rules! impl_ops { #[cfg(not(feature = "simd"))] #[inline(always)] fn bitxor(self, rhs: Self) -> Self::Output { - $vec::new( - self.0 ^ rhs.0, - self.1 ^ rhs.1, - self.2 ^ rhs.2, - self.3 ^ rhs.3, - ) + $vec::new(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2, self.3 ^ rhs.3) } } @@ -67,12 +62,7 @@ macro_rules! impl_ops { #[cfg(not(feature = "simd"))] #[inline(always)] fn shl(self, rhs: Self) -> Self::Output { - $vec::new( - self.0 << rhs.0, - self.1 << rhs.1, - self.2 << rhs.2, - self.3 << rhs.3, - ) + $vec::new(self.0 << rhs.0, self.1 << rhs.1, self.2 << rhs.2, self.3 << rhs.3) } } @@ -88,12 +78,7 @@ macro_rules! impl_ops { #[cfg(not(feature = "simd"))] #[inline(always)] fn shr(self, rhs: Self) -> Self::Output { - $vec::new( - self.0 >> rhs.0, - self.1 >> rhs.1, - self.2 >> rhs.2, - self.3 >> rhs.3, - ) + $vec::new(self.0 >> rhs.0, self.1 >> rhs.1, self.2 >> rhs.2, self.3 >> rhs.3) } } }; diff --git a/core/crypto/blake2/tests/lib.rs b/core/crypto/blake2/tests/lib.rs index ba42b9ffd2f..cce787baf64 100644 --- a/core/crypto/blake2/tests/lib.rs +++ b/core/crypto/blake2/tests/lib.rs @@ -4,15 +4,5 @@ use digest::dev::{digest_test, variable_test}; use digest::new_test; new_test!(blake2b_fixed, "blake2b/fixed", blake2::Blake2b, digest_test); -new_test!( - blake2b_variable, - "blake2b/variable", - blake2::VarBlake2b, - variable_test -); -new_test!( - blake2s_variable, - "blake2s/variable", - blake2::VarBlake2s, - variable_test -); +new_test!(blake2b_variable, "blake2b/variable", blake2::VarBlake2b, variable_test); +new_test!(blake2s_variable, "blake2s/variable", blake2::VarBlake2s, variable_test); diff --git a/core/crypto/blake2/tests/persona.rs b/core/crypto/blake2/tests/persona.rs index 5c2d06bb540..170da81e983 100644 --- a/core/crypto/blake2/tests/persona.rs +++ b/core/crypto/blake2/tests/persona.rs @@ -1,5 +1,5 @@ -use near_blake2::{Blake2b, Blake2s, Digest}; use hex_literal::hex; +use near_blake2::{Blake2b, Blake2s, Digest}; #[test] fn blake2s_persona() { From 7dbcfdb1483b72ff24fdcae3f7a0726b8030de54 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 19:08:29 +0700 Subject: [PATCH 042/134] Add initial blake2 logic to vm --- Cargo.lock | 37 +++-- core/primitives-core/src/config.rs | 24 +-- core/primitives/Cargo.toml | 2 +- runtime/near-vm-errors/Cargo.toml | 1 + runtime/near-vm-errors/src/lib.rs | 15 ++ runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/gas_counter.rs | 10 +- runtime/near-vm-logic/src/logic.rs | 177 ++++++++++++++--------- 8 files changed, 171 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1d4d56b873..d0bc44c0e6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -529,16 +529,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blake2" -version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git?branch=f-standard-out#a930c335a3b04814c37ef2a33b4a0f26ae6e047b" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "blake2b_simd" version = "0.5.11" @@ -565,6 +555,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "blobby" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" +dependencies = [ + "byteorder", +] + [[package]] name = "block-buffer" version = "0.7.3" @@ -1310,6 +1309,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ + "blobby", "generic-array 0.14.4", "subtle 2.4.0", ] @@ -1475,6 +1475,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ + "blobby", "generic-array 0.14.4", ] @@ -3000,6 +3001,16 @@ dependencies = [ "futures", ] +[[package]] +name = "near-blake2" +version = "0.9.1" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", + "hex-literal", + "opaque-debug 0.3.0", +] + [[package]] name = "near-chain" version = "0.1.0" @@ -3143,7 +3154,6 @@ name = "near-crypto" version = "0.1.0" dependencies = [ "arrayref", - "blake2", "borsh", "bs58", "c2-chacha", @@ -3153,6 +3163,7 @@ dependencies = [ "hex-literal", "lazy_static", "libc", + "near-blake2", "parity-secp256k1", "rand 0.7.3", "rand_core 0.5.1", @@ -3601,10 +3612,12 @@ name = "near-vm-logic" version = "3.0.0" dependencies = [ "base64 0.13.0", - "blake2", "borsh", "bs58", "byteorder", + "hex-literal", + "libsecp256k1", + "near-blake2", "near-primitives", "near-primitives-core", "near-runtime-utils", diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index e825ab5cfd8..b8915079cb6 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -233,12 +233,12 @@ pub struct ExtCostsConfig { /// Cost of getting blake2b base #[cfg(feature = "protocol_feature_evm")] pub blake2b_base: Gas, - /// Cost of getting blake2b per byte + /// Cost of getting blake2b per 128 byte message block. #[cfg(feature = "protocol_feature_evm")] - pub blake2b_byte: Gas, - /// Cost of calculating blake2b F compression base + pub blake2b_block: Gas, + /// Cost of a single blake2b round. #[cfg(feature = "protocol_feature_evm")] - pub blake2b_f_base: Gas, + pub blake2b_round: Gas, /// Cost of calling ecrecover #[cfg(feature = "protocol_feature_evm")] @@ -381,9 +381,9 @@ impl Default for ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO #[cfg(feature = "protocol_feature_evm")] - blake2b_byte: SAFETY_MULTIPLIER * 8039117, // TODO + blake2b_block: SAFETY_MULTIPLIER * 8039117, // TODO #[cfg(feature = "protocol_feature_evm")] - blake2b_f_base: SAFETY_MULTIPLIER * 1513656750, // TODO + blake2b_round: SAFETY_MULTIPLIER * 150000, // TODO #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, @@ -463,9 +463,9 @@ impl ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_base: 0, #[cfg(feature = "protocol_feature_evm")] - blake2b_byte: 0, + blake2b_block: 0, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_base: 0, + blake2b_round: 0, #[cfg(feature = "protocol_feature_evm")] ecrecover_base: 0, log_base: 0, @@ -546,7 +546,9 @@ pub enum ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_base, #[cfg(feature = "protocol_feature_evm")] - blake2b_byte, + blake2b_block, + #[cfg(feature = "protocol_feature_evm")] + blake2b_round, #[cfg(feature = "protocol_feature_evm")] blake2b_f_base, #[cfg(feature = "protocol_feature_evm")] @@ -682,7 +684,9 @@ impl ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_base => config.blake2b_base, #[cfg(feature = "protocol_feature_evm")] - blake2b_byte => config.blake2b_byte, + blake2b_block => config.blake2b_block, + #[cfg(feature = "protocol_feature_evm")] + blake2b_round => config.blake2b_round, #[cfg(feature = "protocol_feature_evm")] blake2b_f_base => config.blake2b_f_base, #[cfg(feature = "protocol_feature_evm")] diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index eb846b51e0d..ecbaf59fdd2 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -42,7 +42,7 @@ near-rpc-error-macro = { path = "../../tools/rpctypegen/macro" } default = ["jemallocator"] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] protocol_feature_add_account_versions = ["near-primitives-core/protocol_feature_add_account_versions"] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "near-vm-errors/protocol_feature_evm"] protocol_feature_block_header_v3 = [] protocol_feature_alt_bn128 = ["near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_tx_size_limit = ["near-primitives-core/protocol_feature_tx_size_limit"] diff --git a/runtime/near-vm-errors/Cargo.toml b/runtime/near-vm-errors/Cargo.toml index e186a7830da..c133e2d99aa 100644 --- a/runtime/near-vm-errors/Cargo.toml +++ b/runtime/near-vm-errors/Cargo.toml @@ -22,6 +22,7 @@ near-rpc-error-macro = { path = "../../tools/rpctypegen/macro", version = "0.1.0 [features] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] +protocol_feature_evm = [] protocol_feature_alt_bn128 = [] [package.metadata.workspaces] diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 4498a8a6d2b..3116aaf6a3a 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -208,6 +208,15 @@ pub enum HostError { Deprecated { method_name: String }, /// Invalid ECDSA signature. InvalidECDSASignature, + /// The length of the state is not 64. + #[cfg(feature = "protocol_feature_evm")] + Blake2InvalidStateLength { length: u64 }, + /// Blake2 hash data overflow error. + #[cfg(feature = "protocol_feature_evm")] + Blake2HashDataOverflow, + /// Too many blake2 rounds. + #[cfg(feature = "protocol_feature_evm")] + Blake2TooManyRounds { max: u32, actual: u32 }, /// Deserialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg: String }, @@ -497,6 +506,12 @@ impl std::fmt::Display for HostError { ContractSizeExceeded { size, limit } => write!(f, "The size of a contract code in DeployContract action {} exceeds the limit {}", size, limit), Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), InvalidECDSASignature => write!(f, "Invalid ECDSA signature"), + #[cfg(feature = "protocol_feature_evm")] + Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 64 bytes", length), + #[cfg(feature = "protocol_feature_evm")] + Blake2HashDataOverflow => write!(f, "Blake2 hash data length overflow."), + #[cfg(feature = "protocol_feature_evm")] + Blake2TooManyRounds { max, actual } => write!(f, "Too many blake2 rounds. Expected fewer than {}, got {}.", max, actual), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 246e09ef172..cb494551189 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { git = "https://github.com/near/near-blake2.git", branch = "f-standard-out", version = "0.9.1", optional = true } +blake2 = { package = "near-blake2", path = "../../core/crypto/blake2", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" diff --git a/runtime/near-vm-logic/src/gas_counter.rs b/runtime/near-vm-logic/src/gas_counter.rs index 4af6a225efd..0fb9e9a992e 100644 --- a/runtime/near-vm-logic/src/gas_counter.rs +++ b/runtime/near-vm-logic/src/gas_counter.rs @@ -144,18 +144,18 @@ impl GasCounter { self.deduct_gas(value, value) } - /// A helper function to pay per byte gas - pub fn pay_per_byte(&mut self, cost: ExtCosts, num_bytes: u64) -> Result<()> { - let use_gas = num_bytes + /// A helper function to pay a multiple of a cost. + pub fn pay_per(&mut self, cost: ExtCosts, num: u64) -> Result<()> { + let use_gas = num .checked_mul(cost.value(&self.ext_costs_config)) .ok_or(HostError::IntegerOverflow)?; - self.inc_ext_costs_counter(cost, num_bytes); + self.inc_ext_costs_counter(cost, num); self.update_profile_host(cost, use_gas); self.deduct_gas(use_gas, use_gas) } - /// A helper function to pay base cost gas + /// A helper function to pay base cost gas. pub fn pay_base(&mut self, cost: ExtCosts) -> Result<()> { let base_fee = cost.value(&self.ext_costs_config); self.inc_ext_costs_counter(cost, 1); diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 87f57de3c9b..9bb74980794 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -188,7 +188,7 @@ impl<'a> VMLogic<'a> { fn memory_get_into(&mut self, offset: u64, buf: &mut [u8]) -> Result<()> { self.gas_counter.pay_base(read_memory_base)?; - self.gas_counter.pay_per_byte(read_memory_byte, buf.len() as _)?; + self.gas_counter.pay_per(read_memory_byte, buf.len() as _)?; self.try_fit_mem(offset, buf.len() as _)?; self.memory.read_memory(offset, buf); Ok(()) @@ -196,7 +196,7 @@ impl<'a> VMLogic<'a> { fn memory_get_vec(&mut self, offset: u64, len: u64) -> Result> { self.gas_counter.pay_base(read_memory_base)?; - self.gas_counter.pay_per_byte(read_memory_byte, len)?; + self.gas_counter.pay_per(read_memory_byte, len)?; self.try_fit_mem(offset, len)?; let mut buf = vec![0; len as usize]; self.memory.read_memory(offset, &mut buf); @@ -229,7 +229,7 @@ impl<'a> VMLogic<'a> { fn memory_set_slice(&mut self, offset: u64, buf: &[u8]) -> Result<()> { self.gas_counter.pay_base(write_memory_base)?; - self.gas_counter.pay_per_byte(write_memory_byte, buf.len() as _)?; + self.gas_counter.pay_per(write_memory_byte, buf.len() as _)?; self.try_fit_mem(offset, buf.len() as _)?; self.memory.write_memory(offset, buf); Ok(()) @@ -244,7 +244,7 @@ impl<'a> VMLogic<'a> { fn internal_read_register(&mut self, register_id: u64) -> Result> { if let Some(data) = self.registers.get(®ister_id) { self.gas_counter.pay_base(read_register_base)?; - self.gas_counter.pay_per_byte(read_register_byte, data.len() as _)?; + self.gas_counter.pay_per(read_register_byte, data.len() as _)?; Ok(data.clone()) } else { Err(HostError::InvalidRegisterId { register_id }.into()) @@ -253,7 +253,7 @@ impl<'a> VMLogic<'a> { fn internal_write_register(&mut self, register_id: u64, data: Vec) -> Result<()> { self.gas_counter.pay_base(write_register_base)?; - self.gas_counter.pay_per_byte(write_register_byte, data.len() as u64)?; + self.gas_counter.pay_per(write_register_byte, data.len() as u64)?; if data.len() as u64 > self.config.limit_config.max_register_size || self.registers.len() as u64 >= self.config.limit_config.max_number_registers { @@ -390,7 +390,7 @@ impl<'a> VMLogic<'a> { buf.push(el); } } - self.gas_counter.pay_per_byte(utf8_decoding_byte, buf.len() as _)?; + self.gas_counter.pay_per(utf8_decoding_byte, buf.len() as _)?; String::from_utf8(buf).map_err(|_| HostError::BadUTF8.into()) } @@ -453,7 +453,7 @@ impl<'a> VMLogic<'a> { } } self.gas_counter - .pay_per_byte(utf16_decoding_byte, u16_buffer.len() as u64 * size_of::() as u64)?; + .pay_per(utf16_decoding_byte, u16_buffer.len() as u64 * size_of::() as u64)?; String::from_utf16(&u16_buffer).map_err(|_| HostError::BadUTF16.into()) } @@ -809,14 +809,14 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_base(alt_bn128_g1_multiexp_base)?; let value_buf = self.get_vec_from_memory_or_register(value_ptr, value_len)?; let len = value_buf.len() as u64; - self.gas_counter.pay_per_byte(alt_bn128_g1_multiexp_byte, len)?; + self.gas_counter.pay_per(alt_bn128_g1_multiexp_byte, len)?; let discount = (alt_bn128_g1_multiexp_base as u64 + alt_bn128_g1_multiexp_byte as u64 * len) / alt_bn128_g1_multiexp_sublinear as u64; let sublinear_complexity = crate::alt_bn128::alt_bn128_g1_multiexp_sublinear_complexity_estimate(len, discount); - self.gas_counter.pay_per_byte(alt_bn128_g1_multiexp_sublinear, sublinear_complexity)?; + self.gas_counter.pay_per(alt_bn128_g1_multiexp_sublinear, sublinear_complexity)?; let res = crate::alt_bn128::alt_bn128_g1_multiexp(&value_buf)?; @@ -845,7 +845,7 @@ impl<'a> VMLogic<'a> { ) -> Result<()> { self.gas_counter.pay_base(alt_bn128_g1_sum_base)?; let value_buf = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(alt_bn128_g1_sum_byte, value_buf.len() as u64)?; + self.gas_counter.pay_per(alt_bn128_g1_sum_byte, value_buf.len() as u64)?; let res = crate::alt_bn128::alt_bn128_g1_sum(&value_buf)?; @@ -869,7 +869,7 @@ impl<'a> VMLogic<'a> { pub fn alt_bn128_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result { self.gas_counter.pay_base(alt_bn128_pairing_check_base)?; let value_buf = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(alt_bn128_pairing_check_byte, value_buf.len() as u64)?; + self.gas_counter.pay_per(alt_bn128_pairing_check_byte, value_buf.len() as u64)?; Ok(crate::alt_bn128::alt_bn128_pairing_check(&value_buf)? as u64) } @@ -901,7 +901,7 @@ impl<'a> VMLogic<'a> { pub fn sha256(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(sha256_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(sha256_byte, value.len() as u64)?; + self.gas_counter.pay_per(sha256_byte, value.len() as u64)?; use sha2::Digest; @@ -922,7 +922,7 @@ impl<'a> VMLogic<'a> { pub fn keccak256(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(keccak256_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(keccak256_byte, value.len() as u64)?; + self.gas_counter.pay_per(keccak256_byte, value.len() as u64)?; use sha3::Digest; @@ -943,7 +943,7 @@ impl<'a> VMLogic<'a> { pub fn keccak512(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(keccak512_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(keccak512_byte, value.len() as u64)?; + self.gas_counter.pay_per(keccak512_byte, value.len() as u64)?; use sha3::Digest; @@ -965,7 +965,7 @@ impl<'a> VMLogic<'a> { pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(ripemd160_byte, value.len() as u64)?; + self.gas_counter.pay_per(ripemd160_byte, value.len() as u64)?; use ripemd160::Digest; @@ -984,56 +984,97 @@ impl<'a> VMLogic<'a> { /// /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` #[cfg(feature = "protocol_feature_evm")] - pub fn blake2b(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { - use blake2::{Blake2b, Digest}; + pub fn blake2b( + &mut self, + rounds: u32, + state_len: u64, + state_ptr: u64, + message_len: u64, + message_ptr: u64, + t: u64, + f0: u64, + f1: u64, + register_id: u64, + ) -> Result<()> { + use blake2::{Error as Blake2Error, VarBlake2b}; + use std::convert::TryFrom; - self.gas_counter.pay_base(blake2b_base)?; - let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per_byte(blake2b_byte, value.len() as u64)?; + if state_len != 64 { + return Err(HostError::Blake2InvalidStateLength { length: state_len }.into()); + } - let mut hasher = Blake2b::new(); - hasher.update(&value); - let value_hash = hasher.finalize(); - self.internal_write_register(register_id, value_hash.as_slice().to_vec()) + // Change to per block for gas. + let message_blocks = (message_len / 128 + 1); + + self.gas_counter.pay_base(blake2b_base); + self.gas_counter.pay_per(blake2b_byte, message_blocks); + self.gas_counter.pay_per(blake2b_round, (rounds * message_blocks) as u64); + + let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) + .expect("vec bytes conversion"); + let m = self.memory_get_vec(message_ptr, message_len)?; + + let mut hasher = match VarBlake2b::with_state(rounds, state, t) { + Ok(h) => h, + Err(Blake2Error::TooManyRounds { max, actual }) => { + return Err(HostError::Blake2TooManyRounds { max, actual }.into()) + } + _ => unreachable!(), + }; + if hasher.update(&m).is_err() { + return Err(HostError::Blake2HashDataOverflow.into()); + } + hasher.compress(f0, f1); + let res = hasher.output(); + + self.internal_write_register(register_id, res.as_slice().to_vec()) } - /// The compression function of the blake2 algorithm. - /// - /// Takes as an argument the state vector "h", message block vector "m" (the - /// last block is padded with zeros to full block size, if required), 2w-bit - /// offset counter "t", and final block indicator flag "f". Local vector - /// v[0..15] is used in processing. F returns a new state vector. The number - /// of rounds, "r", is 12 for BLAKE2b and 10 for BLAKE2s. Rounds are - /// numbered from 0 to r - 1. - /// - /// # Cost - /// base + write_register_base + write_register_byte * 64 + blake2b_f_base #[cfg(feature = "protocol_feature_evm")] - pub fn blake2b_f( + pub fn blake2s( &mut self, - rounds_ptr: u64, - h_ptr: u64, - m_ptr: u64, - t_ptr: u64, - f_ptr: u64, + rounds: u32, + state_len: u64, + state_ptr: u64, + message_len: u64, + message_ptr: u64, + t: u64, + f0: u32, + f1: u32, register_id: u64, ) -> Result<()> { + use blake2::{Error as Blake2Error, VarBlake2s}; use std::convert::TryFrom; - let rounds = self.memory_get_u32(rounds_ptr)?; - for _ in 0..rounds { - self.gas_counter.pay_base(blake2b_f_base)?; + if state_len != 64 { + return Err(HostError::Blake2InvalidStateLength { length: state_len }.into()); } - let h = - <[u64; 8]>::try_from(self.memory_get_vec_u64(h_ptr, 8)?).expect("vec bytes conversion"); - let m = <[u64; 16]>::try_from(self.memory_get_vec_u64(m_ptr, 16)?) + + // Change to per block for gas. + let message_blocks = (message_len / 128 + 1); + + self.gas_counter.pay_base(blake2b_base); + self.gas_counter.pay_per(blake2b_block, message_blocks); + self.gas_counter.pay_per(blake2b_round, (rounds * message_blocks) as u64); + + let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) .expect("vec bytes conversion"); - let t = - <[u64; 2]>::try_from(self.memory_get_vec_u64(t_ptr, 2)?).expect("vec bytes conversion"); - let f: bool = self.memory_get_u8(f_ptr)? != 0; + let m = self.memory_get_vec(message_ptr, message_len)?; + + let mut hasher = match VarBlake2s::with_state(rounds, state, t) { + Ok(h) => h, + Err(Blake2Error::TooManyRounds { max, actual }) => { + return Err(HostError::Blake2TooManyRounds { max, actual }.into()) + } + _ => unreachable!(), + }; + if hasher.update(&m).is_err() { + return Err(HostError::Blake2HashDataOverflow.into()); + } + hasher.compress(f0, f1); + let res = hasher.output(); - let value = blake2::blake2b_f(rounds, h, m, t, f); - self.internal_write_register(register_id, value.as_slice().to_vec()) + self.internal_write_register(register_id, res.as_slice().to_vec()) } /// Recovers an ECDSA signer address and returns it into `register_id`. @@ -1271,7 +1312,7 @@ impl<'a> VMLogic<'a> { ); } self.gas_counter.pay_base(promise_and_base)?; - self.gas_counter.pay_per_byte( + self.gas_counter.pay_per( promise_and_per_promise, promise_idx_count .checked_mul(size_of::() as u64) @@ -2125,7 +2166,7 @@ impl<'a> VMLogic<'a> { self.check_can_add_a_log_message()?; let message = self.get_utf8_string(len, ptr)?; self.gas_counter.pay_base(log_base)?; - self.gas_counter.pay_per_byte(log_byte, message.len() as u64)?; + self.gas_counter.pay_per(log_byte, message.len() as u64)?; self.checked_push_log(message) } @@ -2150,7 +2191,7 @@ impl<'a> VMLogic<'a> { let message = self.get_utf16_string(len, ptr)?; self.gas_counter.pay_base(log_base)?; // Let's not use `encode_utf16` for gas per byte here, since it's a lot of compute. - self.gas_counter.pay_per_byte(log_byte, message.len() as u64)?; + self.gas_counter.pay_per(log_byte, message.len() as u64)?; self.checked_push_log(message) } @@ -2185,7 +2226,7 @@ impl<'a> VMLogic<'a> { let message = format!("{}, filename: \"{}\" line: {} col: {}", msg, filename, line, col); self.gas_counter.pay_base(log_base)?; - self.gas_counter.pay_per_byte(log_byte, message.as_bytes().len() as u64)?; + self.gas_counter.pay_per(log_byte, message.as_bytes().len() as u64)?; self.checked_push_log(format!("ABORT: {}", message))?; Err(HostError::GuestPanic { panic_msg: message }.into()) @@ -2209,7 +2250,7 @@ impl<'a> VMLogic<'a> { fn read_and_parse_account_id(&mut self, ptr: u64, len: u64) -> Result { let buf = self.get_vec_from_memory_or_register(ptr, len)?; self.gas_counter.pay_base(utf8_decoding_base)?; - self.gas_counter.pay_per_byte(utf8_decoding_byte, buf.len() as u64)?; + self.gas_counter.pay_per(utf8_decoding_byte, buf.len() as u64)?; let account_id = AccountId::from_utf8(buf).map_err(|_| HostError::BadUTF8)?; Ok(account_id) } @@ -2266,14 +2307,14 @@ impl<'a> VMLogic<'a> { } .into()); } - self.gas_counter.pay_per_byte(storage_write_key_byte, key.len() as u64)?; - self.gas_counter.pay_per_byte(storage_write_value_byte, value.len() as u64)?; + self.gas_counter.pay_per(storage_write_key_byte, key.len() as u64)?; + self.gas_counter.pay_per(storage_write_value_byte, value.len() as u64)?; let nodes_before = self.ext.get_touched_nodes_count(); let evicted_ptr = self.ext.storage_get(&key)?; let evicted = Self::deref_value(&mut self.gas_counter, storage_write_evicted_byte, evicted_ptr)?; self.gas_counter - .pay_per_byte(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; + .pay_per(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; self.ext.storage_set(&key, &value)?; let storage_config = &self.fees_config.storage_usage_config; match evicted { @@ -2313,7 +2354,7 @@ impl<'a> VMLogic<'a> { ) -> Result>> { match value_ptr { Some(value_ptr) => { - gas_counter.pay_per_byte(cost_per_byte, value_ptr.len() as u64)?; + gas_counter.pay_per(cost_per_byte, value_ptr.len() as u64)?; value_ptr.deref().map(Some) } None => Ok(None), @@ -2348,11 +2389,11 @@ impl<'a> VMLogic<'a> { } .into()); } - self.gas_counter.pay_per_byte(storage_read_key_byte, key.len() as u64)?; + self.gas_counter.pay_per(storage_read_key_byte, key.len() as u64)?; let nodes_before = self.ext.get_touched_nodes_count(); let read = self.ext.storage_get(&key); self.gas_counter - .pay_per_byte(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; + .pay_per(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; let read = Self::deref_value(&mut self.gas_counter, storage_read_value_byte, read?)?; match read { Some(value) => { @@ -2398,7 +2439,7 @@ impl<'a> VMLogic<'a> { } .into()); } - self.gas_counter.pay_per_byte(storage_remove_key_byte, key.len() as u64)?; + self.gas_counter.pay_per(storage_remove_key_byte, key.len() as u64)?; let nodes_before = self.ext.get_touched_nodes_count(); let removed_ptr = self.ext.storage_get(&key)?; let removed = @@ -2406,7 +2447,7 @@ impl<'a> VMLogic<'a> { self.ext.storage_remove(&key)?; self.gas_counter - .pay_per_byte(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; + .pay_per(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; let storage_config = &self.fees_config.storage_usage_config; match removed { Some(value) => { @@ -2449,11 +2490,11 @@ impl<'a> VMLogic<'a> { } .into()); } - self.gas_counter.pay_per_byte(storage_has_key_byte, key.len() as u64)?; + self.gas_counter.pay_per(storage_has_key_byte, key.len() as u64)?; let nodes_before = self.ext.get_touched_nodes_count(); let res = self.ext.storage_has_key(&key); self.gas_counter - .pay_per_byte(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; + .pay_per(touching_trie_node, self.ext.get_touched_nodes_count() - nodes_before)?; Ok(res? as u64) } @@ -2576,7 +2617,7 @@ impl<'a> VMLogic<'a> { // TODO: remove, as those costs are incorrectly computed, and we shall account it on deployment. pub fn add_contract_compile_fee(&mut self, code_len: u64) -> Result<()> { - self.gas_counter.pay_per_byte(contract_compile_bytes, code_len)?; + self.gas_counter.pay_per(contract_compile_bytes, code_len)?; self.gas_counter.pay_base(contract_compile_base) } } From ee2d0f69bd10fb5e67af5856874368b2aa8a5808 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Fri, 30 Apr 2021 20:05:59 +0000 Subject: [PATCH 043/134] Fix ecrecover --- runtime/near-vm-logic/src/logic.rs | 56 ++++++++--------------- runtime/near-vm-logic/tests/test_miscs.rs | 3 +- runtime/near-vm-runner/src/imports.rs | 2 +- 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 9bb74980794..1f2c2230c66 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1090,46 +1090,30 @@ impl<'a> VMLogic<'a> { /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` #[cfg(feature = "protocol_feature_evm")] - pub fn ecrecover( - &mut self, - hash_ptr: u64, - v: u32, - r_ptr: u64, - s_ptr: u64, - register_id: u64, - ) -> Result<()> { + pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result<()> { + use sha3::Digest; self.gas_counter.pay_base(ecrecover_base)?; - if v != 27 && v != 28 { - return Err(HostError::InvalidECDSASignature.into()); - } - let hash = self.memory_get_vec(hash_ptr, 32)?; - let v = (v & 0xFF) as u8; - let r = self.memory_get_vec(r_ptr, 32)?; - let s = self.memory_get_vec(s_ptr, 32)?; - - let hash = secp256k1::Message::parse_slice(hash.as_slice()).unwrap(); - - let mut signature = [0u8; 64]; - signature[0..32].copy_from_slice(r.as_slice()); - signature[32..64].copy_from_slice(s.as_slice()); - let signature = secp256k1::Signature::parse(&signature); - let recovery_id = match secp256k1::RecoveryId::parse_rpc(v) { - Err(_) => return Err(HostError::InvalidECDSASignature.into()), - Ok(rid) => rid, - }; + let signature = self.memory_get_vec(sig_ptr, 65)?; + let hash = self.memory_get_vec(hash_ptr, 32)?; - let public_key = match secp256k1::recover(&hash, &signature, &recovery_id) { - Err(_) => return Err(HostError::InvalidECDSASignature.into()), - Ok(pk) => pk, + let hash = secp256k1::Message::parse_slice(&hash).unwrap(); + let v = signature[64]; + let signature = secp256k1::Signature::parse_slice(&signature[0..64]).unwrap(); + let bit = match v { + 0..=26 => v, + _ => v - 27, }; - - use sha3::Digest; - let result = sha3::Keccak256::digest(&public_key.serialize()[1..]); - let mut address = [0u8; 20]; - address.copy_from_slice(&result[12..]); - - self.internal_write_register(register_id, address.to_vec()) + if let Ok(recovery_id) = secp256k1::RecoveryId::parse(bit) { + if let Ok(public_key) = secp256k1::recover(&hash, &signature, &recovery_id) { + // recover returns a 65-byte key, but addresses come from the raw 64-byte key + let result = sha3::Keccak256::digest(&public_key.serialize()[1..]); + let mut address = [0u8; 20]; + address.copy_from_slice(&result[12..]); + return self.internal_write_register(register_id, address.to_vec()); + } + } + return Err(HostError::InvalidECDSASignature.into()); } /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index b5062a584dc..2d1df161759 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -684,8 +684,7 @@ fn test_ecrecover() { let signature = hex!("5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be8921b"); let signer = hex!("2cc1166f6212628A0deEf2B33BEFB2187D35b86c"); - let (r, s, v) = (&signature[0..32], &signature[32..64], signature[64] as u32); - logic.ecrecover(hash.as_ptr() as _, v, r.as_ptr() as _, s.as_ptr() as _, 0).unwrap(); + logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0).unwrap(); let result = &vec![0u8; 20]; logic.read_register(0, result.as_ptr() as _).expect("OK"); diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index d5132c96501..1ed962ad7b7 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -224,7 +224,7 @@ wrapped_imports! { #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] blake2b_f<[rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # // ##################### From ebf64bc02694b480e95f815d0d55458fc70d2dc7 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 23:20:10 +0700 Subject: [PATCH 044/134] Change blake2 `update` to `update_inner` --- core/crypto/blake2/src/blake2.rs | 9 ++++----- core/crypto/blake2/tests/state.rs | 2 +- runtime/near-vm-logic/src/logic.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/crypto/blake2/src/blake2.rs b/core/crypto/blake2/src/blake2.rs index a3a34e14fea..6a222b6910b 100644 --- a/core/crypto/blake2/src/blake2.rs +++ b/core/crypto/blake2/src/blake2.rs @@ -207,7 +207,7 @@ macro_rules! blake2_impl { } /// Updates the hashing context with more data. - pub fn update(&mut self, data: &[u8]) -> Result<(), Error> { + pub fn update_inner(&mut self, data: &[u8]) -> Result<(), Error> { let mut rest = data; let block = 2 * $bytes::to_usize(); @@ -286,7 +286,6 @@ macro_rules! blake2_impl { let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; for x in 1..=self.rounds { - // FIXME: this might not work if greater than 20. let x = if x > 10 { x - 11 } else { x - 1 }; round(&mut v, &m, &SIGMA[x as usize]); } @@ -322,7 +321,7 @@ macro_rules! blake2_impl { impl Update for $state { fn update(&mut self, data: impl AsRef<[u8]>) { - self.update(data.as_ref()).unwrap(); + self.update_inner(data.as_ref()).unwrap(); } } @@ -383,7 +382,7 @@ macro_rules! blake2_impl { impl Update for $fix_state { fn update(&mut self, data: impl AsRef<[u8]>) { - self.state.update(data.as_ref()).unwrap(); + self.state.update_inner(data.as_ref()).unwrap(); } } @@ -423,7 +422,7 @@ macro_rules! blake2_impl { type OutputSize = $bytes; fn update(&mut self, data: &[u8]) { - self.state.update(data).unwrap(); + self.state.update_inner(data).unwrap(); } fn reset(&mut self) { diff --git a/core/crypto/blake2/tests/state.rs b/core/crypto/blake2/tests/state.rs index 385d2cc90dd..76620a86f06 100644 --- a/core/crypto/blake2/tests/state.rs +++ b/core/crypto/blake2/tests/state.rs @@ -54,7 +54,7 @@ fn blake2s_state() { ]; let mut hasher = near_blake2::VarBlake2s::with_state(rounds, h, t).unwrap(); - hasher.update(m).unwrap(); + hasher.update_inner(m).unwrap(); hasher.compress(f0, f1); let res = hasher.output(); diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 1f2c2230c66..7fe3ab36d21 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1007,7 +1007,7 @@ impl<'a> VMLogic<'a> { let message_blocks = (message_len / 128 + 1); self.gas_counter.pay_base(blake2b_base); - self.gas_counter.pay_per(blake2b_byte, message_blocks); + self.gas_counter.pay_per(blake2b_block, message_blocks); self.gas_counter.pay_per(blake2b_round, (rounds * message_blocks) as u64); let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) @@ -1021,7 +1021,7 @@ impl<'a> VMLogic<'a> { } _ => unreachable!(), }; - if hasher.update(&m).is_err() { + if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); } hasher.compress(f0, f1); @@ -1068,7 +1068,7 @@ impl<'a> VMLogic<'a> { } _ => unreachable!(), }; - if hasher.update(&m).is_err() { + if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); } hasher.compress(f0, f1); From bffa86418310a74f2c4d687a8381a296f2f55055 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 23:21:02 +0700 Subject: [PATCH 045/134] Update params estimator --- core/primitives-core/src/config.rs | 33 +++- runtime/runtime-params-estimator/src/cases.rs | 24 ++- .../src/ext_costs_generator.rs | 9 +- .../test-contract/src/lib.rs | 170 +++++++++++++----- 4 files changed, 181 insertions(+), 55 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index b8915079cb6..c30f655f918 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -239,6 +239,15 @@ pub struct ExtCostsConfig { /// Cost of a single blake2b round. #[cfg(feature = "protocol_feature_evm")] pub blake2b_round: Gas, + /// Cost of getting blake2b base + #[cfg(feature = "protocol_feature_evm")] + pub blake2s_base: Gas, + /// Cost of getting blake2b per 128 byte message block. + #[cfg(feature = "protocol_feature_evm")] + pub blake2s_block: Gas, + /// Cost of a single blake2b round. + #[cfg(feature = "protocol_feature_evm")] + pub blake2s_round: Gas, /// Cost of calling ecrecover #[cfg(feature = "protocol_feature_evm")] @@ -385,6 +394,12 @@ impl Default for ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_round: SAFETY_MULTIPLIER * 150000, // TODO #[cfg(feature = "protocol_feature_evm")] + blake2s_base: SAFETY_MULTIPLIER * 1513656750, // TODO + #[cfg(feature = "protocol_feature_evm")] + blake2s_block: SAFETY_MULTIPLIER * 8039117, // TODO + #[cfg(feature = "protocol_feature_evm")] + blake2s_round: SAFETY_MULTIPLIER * 150000, // TODO + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -467,6 +482,12 @@ impl ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_round: 0, #[cfg(feature = "protocol_feature_evm")] + blake2s_base: 0, + #[cfg(feature = "protocol_feature_evm")] + blake2s_block: 0, + #[cfg(feature = "protocol_feature_evm")] + blake2s_round: 0, + #[cfg(feature = "protocol_feature_evm")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -550,7 +571,11 @@ pub enum ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_round, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_base, + blake2s_base, + #[cfg(feature = "protocol_feature_evm")] + blake2s_block, + #[cfg(feature = "protocol_feature_evm")] + blake2s_round, #[cfg(feature = "protocol_feature_evm")] ecrecover_base, log_base, @@ -688,7 +713,11 @@ impl ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_round => config.blake2b_round, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_base => config.blake2b_f_base, + blake2s_base => config.blake2s_f_base, + #[cfg(feature = "protocol_feature_evm")] + blake2s_block => config.blake2s_block, + #[cfg(feature = "protocol_feature_evm")] + blake2s_round => config.blake2s_round, #[cfg(feature = "protocol_feature_evm")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index c0ff51e2783..cfb4ecca9bd 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -203,11 +203,17 @@ pub enum Metric { #[cfg(feature = "protocol_feature_evm")] ripemd160_10kib_10k, #[cfg(feature = "protocol_feature_evm")] - blake2b_10b_10k, + blake2b_128b_0r_10k, #[cfg(feature = "protocol_feature_evm")] - blake2b_10kib_10k, + blake2b_128kb_0r_10k, #[cfg(feature = "protocol_feature_evm")] - blake2b_f_1r_10k, + blake2b_128b_12r_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2s_128b_0r_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2s_128kb_0r_10k, + #[cfg(feature = "protocol_feature_evm")] + blake2s_128b_12r_10k, #[cfg(feature = "protocol_feature_evm")] ecrecover_10k, #[cfg(feature = "protocol_feature_alt_bn128")] @@ -696,7 +702,7 @@ fn measured_to_gas( ) -> u64 { match measured.get(&cost) { Some(value) => ratio_to_gas(gas_metric, *value), - None => panic!("cost {:?} not found", cost), + None => panic!("cost {} not found", cost as u32), } } @@ -785,9 +791,15 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts #[cfg(feature = "protocol_feature_evm")] blake2b_base: measured_to_gas(metric, &measured, blake2b_base), #[cfg(feature = "protocol_feature_evm")] - blake2b_byte: measured_to_gas(metric, &measured, blake2b_byte), + blake2b_block: measured_to_gas(metric, &measured, blake2b_block), + #[cfg(feature = "protocol_feature_evm")] + blake2b_round: measured_to_gas(metric, &measured, blake2b_round), + #[cfg(feature = "protocol_feature_evm")] + blake2s_base: measured_to_gas(metric, &measured, blake2s_base), + #[cfg(feature = "protocol_feature_evm")] + blake2s_block: measured_to_gas(metric, &measured, blake2s_block), #[cfg(feature = "protocol_feature_evm")] - blake2b_f_base: measured_to_gas(metric, &measured, blake2b_f_base), + blake2s_round: measured_to_gas(metric, &measured, blake2s_round), #[cfg(feature = "protocol_feature_evm")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 76ff47f13f7..83650349a0d 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -70,9 +70,12 @@ impl ExtCostsGenerator { self.extract(ripemd160_10b_10k, ripemd160_base); self.extract(ripemd160_10kib_10k, ripemd160_byte); - self.extract(blake2b_10b_10k, blake2b_base); - self.extract(blake2b_10kib_10k, blake2b_byte); - self.extract(blake2b_f_1r_10k, blake2b_f_base); + self.extract(blake2b_128b_0r_10k, blake2b_base); + self.extract(blake2b_128kb_0r_10k, blake2b_block); + self.extract(blake2b_128b_12r_10k, blake2b_round); + self.extract(blake2s_128b_0r_10k, blake2s_base); + self.extract(blake2s_128kb_0r_10k, blake2s_block); + self.extract(blake2s_128b_12r_10k, blake2s_round); self.extract(ecrecover_10k, ecrecover_base); } diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 213aaf76b36..a9542ad0a24 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -50,9 +50,9 @@ extern "C" { #[cfg(feature = "protocol_feature_evm")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); #[cfg(feature = "protocol_feature_evm")] - fn blake2b(value_len: u64, value_ptr: u64, register_id: u64); + fn blake2b(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, 1: u64, register_id: u64,); #[cfg(feature = "protocol_feature_evm")] - fn blake2b_f(rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64); + fn blake2s(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u32, f1: u32, register_id: u64,); #[cfg(feature = "protocol_feature_evm")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### @@ -463,65 +463,147 @@ pub unsafe fn ripemd160_10kib_10k() { // Compute blake2b on 10b 10k times. #[no_mangle] #[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2b_10b_10k() { - let buffer = [65u8; 10]; +pub unsafe fn blake2b_128b_0r_10k() { + let rounds = 0; + let state = [65u8; 64]; + let buffer = [65u8; 128]; for _ in 0..10_000 { - blake2b(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); + blake2b( + rounds, + state.len() as u64, + state.as_ptr() as *const u64 as u64, + buffer.len() as u64, + buffer.as_ptr() as *const u64 as u64, + 0, + !0, + 0, + 0 + ); } } + // Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, // and `write_register_byte`. However `blake2b` computation is more expensive than register writing // so we are okay overcharging it. // Compute blake2b on 10kib 10k times. #[no_mangle] #[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2b_10kib_10k() { - let buffer = [65u8; 10240]; +pub unsafe fn blake2b_128kb_0r_10k() { + let rounds = 0; + let state = [65u8; 64]; + let buffer = [65u8; 12800]; for _ in 0..10_000 { - blake2b(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); + blake2b( + rounds, + state.len() as u64, + state.as_ptr() as *const u64 as u64, + buffer.len() as u64, + buffer.as_ptr() as *const u64 as u64, + 0, + !0, + 0, + 0 + ); } } -/// Function to measure the `blake2b_f_base` and `blake2b_byte`. Also measures `base`, -/// `write_register_base`, and `write_register_byte`. This is done at cost per -/// round. +// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `blake2b` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute blake2b on 10kib 10k times. #[no_mangle] #[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2b_f_1r_10k() { - let rounds: [u8; 4] = 1_u32.to_le_bytes(); - let h: [u64; 8] = [ - 0x6a09e667f2bdc948, - 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, - 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, - 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, - 0x5be0cd19137e2179, - ]; - let m: [u64; 16] = [ - 0x0000000000636261, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - ]; - let t: [u64; 2] = [3, 0]; - let f: [u8; 1] = 1_u8.to_le_bytes(); +pub unsafe fn blake2b_128b_12r_10k() { + let rounds = 12; + let state = [65u8; 64]; + let buffer = [65u8; 128]; + for _ in 0..10_000 { + blake2b( + rounds, + state.len() as u64, + state.as_ptr() as *const u64 as u64, + buffer.len() as u64, + buffer.as_ptr() as *const u64 as u64, + 0, + !0, + 0, + 0 + ); + } +} + +// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `blake2b` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute blake2b on 10b 10k times. +#[no_mangle] +#[cfg(feature = "protocol_feature_evm")] +pub unsafe fn blake2s_128b_0r_10k() { + let rounds = 0; + let state = [65u8; 64]; + let buffer = [65u8; 128]; + for _ in 0..10_000 { + blake2s( + rounds, + state.len() as u64, + state.as_ptr() as *const u64 as u64, + buffer.len() as u64, + buffer.as_ptr() as *const u64 as u64, + 0, + !0, + 0, + 0 + ); + } +} + +// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `blake2b` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute blake2b on 10kib 10k times. +#[no_mangle] +#[cfg(feature = "protocol_feature_evm")] +pub unsafe fn blake2s_128kb_0r_10k() { + let rounds = 0; + let state = [65u8; 64]; + let buffer = [65u8; 12800]; + for _ in 0..10_000 { + blake2s( + rounds, + state.len() as u64, + state.as_ptr() as *const u64 as u64, + buffer.len() as u64, + buffer.as_ptr() as *const u64 as u64, + 0, + !0, + 0, + 0 + ); + } +} +// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, +// and `write_register_byte`. However `blake2b` computation is more expensive than register writing +// so we are okay overcharging it. +// Compute blake2b on 10kib 10k times. +#[no_mangle] +#[cfg(feature = "protocol_feature_evm")] +pub unsafe fn blake2s_128b_12r_10k() { + let rounds = 12; + let state = [65u8; 64]; + let buffer = [65u8; 128]; for _ in 0..10_000 { - blake2b_f(rounds.as_ptr() as u64, h.as_ptr() as u64, m.as_ptr() as u64, t.as_ptr() as u64, f.as_ptr() as u64, 0); + blake2s( + rounds, + state.len() as u64, + state.as_ptr() as *const u64 as u64, + buffer.len() as u64, + buffer.as_ptr() as *const u64 as u64, + 0, + !0, + 0, + 0 + ); } } From bce76f35098cd35a2ee9972034ca9aca650b83fa Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 23:32:31 +0700 Subject: [PATCH 046/134] Remove duplicate evm feature --- core/primitives-core/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/core/primitives-core/Cargo.toml b/core/primitives-core/Cargo.toml index 4c1880fdc6d..1694b3d0e35 100644 --- a/core/primitives-core/Cargo.toml +++ b/core/primitives-core/Cargo.toml @@ -26,6 +26,5 @@ lazy_static = "1.4" default = [] protocol_feature_evm = [] protocol_feature_add_account_versions = [] -protocol_feature_evm = [] protocol_feature_alt_bn128 = [] protocol_feature_tx_size_limit = [] From ac9982df911f68f412a9b030cbc4b06eeb42dc7c Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 21 May 2021 23:41:37 +0700 Subject: [PATCH 047/134] Remove pattern --- runtime/runtime-params-estimator/test-contract/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index a9542ad0a24..60a37677583 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -50,9 +50,9 @@ extern "C" { #[cfg(feature = "protocol_feature_evm")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); #[cfg(feature = "protocol_feature_evm")] - fn blake2b(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, 1: u64, register_id: u64,); + fn blake2b(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64); #[cfg(feature = "protocol_feature_evm")] - fn blake2s(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u32, f1: u32, register_id: u64,); + fn blake2s(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u32, f1: u32, register_id: u64); #[cfg(feature = "protocol_feature_evm")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### From 55dda77377b3cafb19e5dfb60f882714c81d49d2 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Fri, 21 May 2021 17:55:08 +0000 Subject: [PATCH 048/134] Fix some compilation errors --- core/primitives-core/src/config.rs | 2 +- runtime/near-vm-logic/src/logic.rs | 26 ++++++++++++++++---------- runtime/near-vm-runner/src/imports.rs | 4 ++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index c30f655f918..0fbb22c0279 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -713,7 +713,7 @@ impl ExtCosts { #[cfg(feature = "protocol_feature_evm")] blake2b_round => config.blake2b_round, #[cfg(feature = "protocol_feature_evm")] - blake2s_base => config.blake2s_f_base, + blake2s_base => config.blake2s_base, #[cfg(feature = "protocol_feature_evm")] blake2s_block => config.blake2s_block, #[cfg(feature = "protocol_feature_evm")] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 7fe3ab36d21..0da6102937a 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1004,11 +1004,11 @@ impl<'a> VMLogic<'a> { } // Change to per block for gas. - let message_blocks = (message_len / 128 + 1); + let message_blocks = message_len / 128 + 1; - self.gas_counter.pay_base(blake2b_base); - self.gas_counter.pay_per(blake2b_block, message_blocks); - self.gas_counter.pay_per(blake2b_round, (rounds * message_blocks) as u64); + self.gas_counter.pay_base(blake2b_base)?; + self.gas_counter.pay_per(blake2b_block, message_blocks)?; + self.gas_counter.pay_per(blake2b_round, (rounds as u64) * message_blocks)?; let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) .expect("vec bytes conversion"); @@ -1051,14 +1051,20 @@ impl<'a> VMLogic<'a> { } // Change to per block for gas. - let message_blocks = (message_len / 128 + 1); + let message_blocks = message_len / 128 + 1; - self.gas_counter.pay_base(blake2b_base); - self.gas_counter.pay_per(blake2b_block, message_blocks); - self.gas_counter.pay_per(blake2b_round, (rounds * message_blocks) as u64); + self.gas_counter.pay_base(blake2b_base)?; + self.gas_counter.pay_per(blake2b_block, message_blocks)?; + self.gas_counter.pay_per(blake2b_round, (rounds as u64) * message_blocks)?; - let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) - .expect("vec bytes conversion"); + let state = { + let mut buf = [0u32; 8]; + let values = self.memory_get_vec_u64(state_ptr, 8)?; + for (x, y) in buf.iter_mut().zip(values.into_iter()) { + *x = ::try_from(y).map_err(|_| HostError::Blake2HashDataOverflow)?; + } + buf + }; let m = self.memory_get_vec(message_ptr, message_len)?; let mut hasher = match VarBlake2s::with_state(rounds, state, t) { diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 1ed962ad7b7..8ac4942e344 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -222,8 +222,8 @@ wrapped_imports! { keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2b<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2b_f<[rounds_ptr: u64, h_ptr: u64, m_ptr: u64, t_ptr: u64, f_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2b<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u32, f1: u32, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # From 77f1b2a687e1ce472ea240f068d452329421174e Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Fri, 21 May 2021 22:01:31 +0000 Subject: [PATCH 049/134] Fix runtime-params-estimator compile --- runtime/runtime-params-estimator/src/cases.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index cfb4ecca9bd..dd9c73258d1 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -598,9 +598,12 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon keccak512_10kib_10k => keccak512_10kib_10k, #["protocol_feature_evm"] ripemd160_10b_10k => ripemd160_10b_10k, #["protocol_feature_evm"] ripemd160_10kib_10k => ripemd160_10kib_10k, - #["protocol_feature_evm"] blake2b_10b_10k => blake2b_10b_10k, - #["protocol_feature_evm"] blake2b_10kib_10k => blake2b_10kib_10k, - #["protocol_feature_evm"] blake2b_f_1r_10k => blake2b_f_1r_10k, + #["protocol_feature_evm"] blake2b_128b_0r_10k => blake2b_128b_0r_10k, + #["protocol_feature_evm"] blake2b_128kb_0r_10k => blake2b_128kb_0r_10k, + #["protocol_feature_evm"] blake2b_128b_12r_10k => blake2b_128b_12r_10k, + #["protocol_feature_evm"] blake2s_128b_0r_10k => blake2s_128b_0r_10k, + #["protocol_feature_evm"] blake2s_128kb_0r_10k => blake2s_128kb_0r_10k, + #["protocol_feature_evm"] blake2s_128b_12r_10k => blake2s_128b_12r_10k, #["protocol_feature_evm"] ecrecover_10k => ecrecover_10k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_1_1k => alt_bn128_g1_multiexp_1_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_10_1k => alt_bn128_g1_multiexp_10_1k, From d461c3bef2f477d48996f0a0e62eb5e8a73762c8 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 24 May 2021 16:21:17 +0700 Subject: [PATCH 050/134] Fix tests --- core/crypto/blake2/src/lib.rs | 10 +++++----- core/crypto/blake2/tests/lib.rs | 6 +++--- core/crypto/blake2/tests/mac.rs | 4 ++-- core/crypto/blake2/tests/state.rs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/crypto/blake2/src/lib.rs b/core/crypto/blake2/src/lib.rs index 673dc30c61d..89d9449313f 100644 --- a/core/crypto/blake2/src/lib.rs +++ b/core/crypto/blake2/src/lib.rs @@ -5,7 +5,7 @@ //! `Blake2b` can be used in the following way: //! //! ```rust -//! use blake2::{Blake2b, Blake2s, Digest}; +//! use near_blake2::{Blake2b, Blake2s, Digest}; //! use hex_literal::hex; //! //! // create a Blake2b object @@ -39,8 +39,8 @@ //! trait has to be imported as well. //! //! ```rust -//! use blake2::VarBlake2b; -//! use blake2::digest::{Update, VariableOutput}; +//! use near_blake2::VarBlake2b; +//! use near_blake2::digest::{Update, VariableOutput}; //! //! let mut hasher = VarBlake2b::new(10).unwrap(); //! hasher.update(b"my_input"); @@ -54,8 +54,8 @@ //! BLAKE2 can be used as a MAC without any additional constructs: //! //! ```rust -//! use blake2::Blake2b; -//! use blake2::crypto_mac::{Mac, NewMac}; +//! use near_blake2::Blake2b; +//! use near_blake2::crypto_mac::{Mac, NewMac}; //! //! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); //! hasher.update(b"hello world"); diff --git a/core/crypto/blake2/tests/lib.rs b/core/crypto/blake2/tests/lib.rs index cce787baf64..3500c7ee4c6 100644 --- a/core/crypto/blake2/tests/lib.rs +++ b/core/crypto/blake2/tests/lib.rs @@ -3,6 +3,6 @@ use digest::dev::{digest_test, variable_test}; use digest::new_test; -new_test!(blake2b_fixed, "blake2b/fixed", blake2::Blake2b, digest_test); -new_test!(blake2b_variable, "blake2b/variable", blake2::VarBlake2b, variable_test); -new_test!(blake2s_variable, "blake2s/variable", blake2::VarBlake2s, variable_test); +new_test!(blake2b_fixed, "blake2b/fixed", near_blake2::Blake2b, digest_test); +new_test!(blake2b_variable, "blake2b/variable", near_blake2::VarBlake2b, variable_test); +new_test!(blake2s_variable, "blake2s/variable", near_blake2::VarBlake2s, variable_test); diff --git a/core/crypto/blake2/tests/mac.rs b/core/crypto/blake2/tests/mac.rs index 833c563e3a8..08867b825bc 100644 --- a/core/crypto/blake2/tests/mac.rs +++ b/core/crypto/blake2/tests/mac.rs @@ -2,5 +2,5 @@ use crypto_mac::new_test; -new_test!(blake2b_mac, "blake2b/mac", blake2::Blake2b); -new_test!(blake2s_mac, "blake2s/mac", blake2::Blake2s); +new_test!(blake2b_mac, "blake2b/mac", near_blake2::Blake2b); +new_test!(blake2s_mac, "blake2s/mac", near_blake2::Blake2s); diff --git a/core/crypto/blake2/tests/state.rs b/core/crypto/blake2/tests/state.rs index 76620a86f06..8a829661110 100644 --- a/core/crypto/blake2/tests/state.rs +++ b/core/crypto/blake2/tests/state.rs @@ -27,7 +27,7 @@ fn blake2b_state() { ]; let mut hasher = near_blake2::VarBlake2b::with_state(rounds, h, t).unwrap(); - hasher.update(m).unwrap(); + hasher.update_inner(m).unwrap(); hasher.compress(f0, f1); let res = hasher.output(); From 6207f4bed4d56b2cff92b0224ef7d519f071d211 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 25 May 2021 21:56:40 +0700 Subject: [PATCH 051/134] Reduce blake2s param estimator rounds from 12 to 10 --- runtime/runtime-params-estimator/src/cases.rs | 4 ++-- runtime/runtime-params-estimator/src/ext_costs_generator.rs | 2 +- runtime/runtime-params-estimator/test-contract/src/lib.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index dd9c73258d1..d476316b13b 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -213,7 +213,7 @@ pub enum Metric { #[cfg(feature = "protocol_feature_evm")] blake2s_128kb_0r_10k, #[cfg(feature = "protocol_feature_evm")] - blake2s_128b_12r_10k, + blake2s_128b_10r_10k, #[cfg(feature = "protocol_feature_evm")] ecrecover_10k, #[cfg(feature = "protocol_feature_alt_bn128")] @@ -603,7 +603,7 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon #["protocol_feature_evm"] blake2b_128b_12r_10k => blake2b_128b_12r_10k, #["protocol_feature_evm"] blake2s_128b_0r_10k => blake2s_128b_0r_10k, #["protocol_feature_evm"] blake2s_128kb_0r_10k => blake2s_128kb_0r_10k, - #["protocol_feature_evm"] blake2s_128b_12r_10k => blake2s_128b_12r_10k, + #["protocol_feature_evm"] blake2s_128b_10r_10k => blake2s_128b_10r_10k, #["protocol_feature_evm"] ecrecover_10k => ecrecover_10k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_1_1k => alt_bn128_g1_multiexp_1_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_10_1k => alt_bn128_g1_multiexp_10_1k, diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 83650349a0d..d20faae6229 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -75,7 +75,7 @@ impl ExtCostsGenerator { self.extract(blake2b_128b_12r_10k, blake2b_round); self.extract(blake2s_128b_0r_10k, blake2s_base); self.extract(blake2s_128kb_0r_10k, blake2s_block); - self.extract(blake2s_128b_12r_10k, blake2s_round); + self.extract(blake2s_128b_10r_10k, blake2s_round); self.extract(ecrecover_10k, ecrecover_base); } diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 60a37677583..d79c47d771b 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -588,8 +588,8 @@ pub unsafe fn blake2s_128kb_0r_10k() { // Compute blake2b on 10kib 10k times. #[no_mangle] #[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2s_128b_12r_10k() { - let rounds = 12; +pub unsafe fn blake2s_128b_10r_10k() { + let rounds = 10; let state = [65u8; 64]; let buffer = [65u8; 128]; for _ in 0..10_000 { From 3b4c098d57d9b5c675d5d97eae744268bb8c00b2 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 25 May 2021 22:10:16 +0700 Subject: [PATCH 052/134] Add protocol_feature_evm feature to standalone runner --- runtime/near-vm-runner-standalone/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/near-vm-runner-standalone/Cargo.toml b/runtime/near-vm-runner-standalone/Cargo.toml index 22d744e186c..6ec6748751c 100644 --- a/runtime/near-vm-runner-standalone/Cargo.toml +++ b/runtime/near-vm-runner-standalone/Cargo.toml @@ -39,6 +39,7 @@ near-test-contracts = { path = "../near-test-contracts" } [features] default = [] no_cache = ["near-vm-runner/no_cache"] +protocol_feature_evm = ["near-vm-logic/protocol_feature_evm", "near-vm-runner/protocol_feature_evm"] protocol_feature_alt_bn128 = ["near-vm-logic/protocol_feature_alt_bn128", "near-vm-runner/protocol_feature_alt_bn128"] [package.metadata.workspaces] From 9d84a334bd10c04d78253d26490d7b65e3a9f401 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 14:10:31 +0700 Subject: [PATCH 053/134] Add estimated gas values --- core/primitives-core/src/config.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 0fbb22c0279..e6514f1fe4d 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -384,23 +384,23 @@ impl Default for ExtCostsConfig { keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, #[cfg(feature = "protocol_feature_evm")] - ripemd160_base: SAFETY_MULTIPLIER * 1513656750, // TODO + ripemd160_base: SAFETY_MULTIPLIER * 15136567500, // 10 x sha256_base #[cfg(feature = "protocol_feature_evm")] - ripemd160_byte: SAFETY_MULTIPLIER * 8039117, // TODO + ripemd160_byte: SAFETY_MULTIPLIER * 80391170, // 10 x sha256_byte #[cfg(feature = "protocol_feature_evm")] - blake2b_base: SAFETY_MULTIPLIER * 1513656750, // TODO + blake2b_base: SAFETY_MULTIPLIER * 88256037, // same as base. #[cfg(feature = "protocol_feature_evm")] - blake2b_block: SAFETY_MULTIPLIER * 8039117, // TODO + blake2b_block: SAFETY_MULTIPLIER * 1029006976, // sha256 per byte x 128 #[cfg(feature = "protocol_feature_evm")] - blake2b_round: SAFETY_MULTIPLIER * 150000, // TODO + blake2b_round: SAFETY_MULTIPLIER * 25227612, // sha256 base / 60 #[cfg(feature = "protocol_feature_evm")] - blake2s_base: SAFETY_MULTIPLIER * 1513656750, // TODO + blake2s_base: SAFETY_MULTIPLIER * 58837358, // blake2b / (2/3) #[cfg(feature = "protocol_feature_evm")] - blake2s_block: SAFETY_MULTIPLIER * 8039117, // TODO + blake2s_block: SAFETY_MULTIPLIER * 686004650, // blake2b / (2/3) #[cfg(feature = "protocol_feature_evm")] - blake2s_round: SAFETY_MULTIPLIER * 150000, // TODO + blake2s_round: SAFETY_MULTIPLIER * 16818408, // blake2b / (2/3) #[cfg(feature = "protocol_feature_evm")] - ecrecover_base: SAFETY_MULTIPLIER * 1000000000, // TODO + ecrecover_base: SAFETY_MULTIPLIER * 75682837500, // 50 x sha256_base log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, storage_write_base: SAFETY_MULTIPLIER * 21398912000, From e0cddbb1c7624b289272c308db7f68bd1635ae76 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 14:13:19 +0700 Subject: [PATCH 054/134] Update estimated gas value note --- core/primitives-core/src/config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index e6514f1fe4d..40580af283f 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -394,11 +394,11 @@ impl Default for ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] blake2b_round: SAFETY_MULTIPLIER * 25227612, // sha256 base / 60 #[cfg(feature = "protocol_feature_evm")] - blake2s_base: SAFETY_MULTIPLIER * 58837358, // blake2b / (2/3) + blake2s_base: SAFETY_MULTIPLIER * 58837358, // blake2b * (2/3) #[cfg(feature = "protocol_feature_evm")] - blake2s_block: SAFETY_MULTIPLIER * 686004650, // blake2b / (2/3) + blake2s_block: SAFETY_MULTIPLIER * 686004650, // blake2b * (2/3) #[cfg(feature = "protocol_feature_evm")] - blake2s_round: SAFETY_MULTIPLIER * 16818408, // blake2b / (2/3) + blake2s_round: SAFETY_MULTIPLIER * 16818408, // blake2b * (2/3) #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 75682837500, // 50 x sha256_base log_base: SAFETY_MULTIPLIER * 1181104350, From 15e9ecca8c5fce004a3873c73c8e1604b589c687 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 15:16:17 +0700 Subject: [PATCH 055/134] cargo fmt --- chain/rosetta-rpc/src/models.rs | 4 +++- core/primitives/src/types.rs | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/chain/rosetta-rpc/src/models.rs b/chain/rosetta-rpc/src/models.rs index 851b423944b..7b3cf198d1c 100644 --- a/chain/rosetta-rpc/src/models.rs +++ b/chain/rosetta-rpc/src/models.rs @@ -935,7 +935,9 @@ pub(crate) struct SubNetworkIdentifier { /// The timestamp of the block in milliseconds since the Unix Epoch. The /// timestamp is stored in milliseconds because some blockchains produce blocks /// more often than once a second. -#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, Apiv2Schema)] +#[derive( + Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, Apiv2Schema, +)] pub(crate) struct Timestamp(i64); /// Transactions contain an array of Operations that are attributable to the diff --git a/core/primitives/src/types.rs b/core/primitives/src/types.rs index 638c0855419..7da4e91d8cb 100644 --- a/core/primitives/src/types.rs +++ b/core/primitives/src/types.rs @@ -53,7 +53,9 @@ pub struct AccountInfo { /// /// NOTE: Currently, this type is only used in the view_client and RPC to be able to transparently /// pretty-serialize the bytes arrays as base64-encoded strings (see `serialize.rs`). -#[derive(Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize)] +#[derive( + Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize, +)] #[as_ref(forward)] pub struct StoreKey(Vec); @@ -61,7 +63,9 @@ pub struct StoreKey(Vec); /// /// NOTE: Currently, this type is only used in the view_client and RPC to be able to transparently /// pretty-serialize the bytes arrays as base64-encoded strings (see `serialize.rs`). -#[derive(Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize)] +#[derive( + Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize, +)] #[as_ref(forward)] pub struct StoreValue(Vec); @@ -70,7 +74,9 @@ pub struct StoreValue(Vec); /// NOTE: The main reason for this to exist (except the type-safety) is that the value is /// transparently serialized and deserialized as a base64-encoded string when serde is used /// (serde_json). -#[derive(Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize)] +#[derive( + Debug, Clone, PartialEq, Eq, DeriveAsRef, DeriveFrom, BorshSerialize, BorshDeserialize, +)] #[as_ref(forward)] pub struct FunctionArgs(Vec); From 6c21c786e967b0e576bb3549b7baa87e85e39584 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 15:47:31 +0700 Subject: [PATCH 056/134] Update c2-chacha --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdc380b16f4..50fded23747 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "c2-chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb6b83fa00a7c53f420893670940c8fdfaa89f9dd9adb52062cca39482a31ab6" +checksum = "7e6002dbb7c65a76e516625443949a8b7bb0d0845fe6a3dc39e2dd7ae39dcb9c" dependencies = [ "cipher", "ppv-lite86", From 4483cd4b41378bbbddd025adb76f6393e9ad1e39 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 16:23:43 +0700 Subject: [PATCH 057/134] Remove nightly features from lib blake2 --- core/crypto/blake2/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/crypto/blake2/src/lib.rs b/core/crypto/blake2/src/lib.rs index 89d9449313f..2191fb9918a 100644 --- a/core/crypto/blake2/src/lib.rs +++ b/core/crypto/blake2/src/lib.rs @@ -87,8 +87,6 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] -#![cfg_attr(feature = "simd", feature(platform_intrinsics, repr_simd))] -#![cfg_attr(feature = "simd_asm", feature(asm))] #[cfg(feature = "std")] extern crate std; From 4a1c26e1996eaac58bbb7e0ec4ac4f2946a5c4e7 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 17:44:49 +0700 Subject: [PATCH 058/134] Add blake2 pass tests --- runtime/near-vm-errors/src/lib.rs | 2 +- runtime/near-vm-logic/src/logic.rs | 11 +- runtime/near-vm-logic/tests/test_miscs.rs | 153 ++++++++++++---------- 3 files changed, 93 insertions(+), 73 deletions(-) diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 3116aaf6a3a..1f9c3694e34 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -507,7 +507,7 @@ impl std::fmt::Display for HostError { Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), InvalidECDSASignature => write!(f, "Invalid ECDSA signature"), #[cfg(feature = "protocol_feature_evm")] - Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 64 bytes", length), + Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), #[cfg(feature = "protocol_feature_evm")] Blake2HashDataOverflow => write!(f, "Blake2 hash data length overflow."), #[cfg(feature = "protocol_feature_evm")] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 0da6102937a..e9a185ab9b9 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -999,7 +999,7 @@ impl<'a> VMLogic<'a> { use blake2::{Error as Blake2Error, VarBlake2b}; use std::convert::TryFrom; - if state_len != 64 { + if state_len != 8 { return Err(HostError::Blake2InvalidStateLength { length: state_len }.into()); } @@ -1038,7 +1038,8 @@ impl<'a> VMLogic<'a> { state_ptr: u64, message_len: u64, message_ptr: u64, - t: u64, + t0: u32, + t1: u32, f0: u32, f1: u32, register_id: u64, @@ -1046,7 +1047,7 @@ impl<'a> VMLogic<'a> { use blake2::{Error as Blake2Error, VarBlake2s}; use std::convert::TryFrom; - if state_len != 64 { + if state_len != 8 { return Err(HostError::Blake2InvalidStateLength { length: state_len }.into()); } @@ -1067,6 +1068,10 @@ impl<'a> VMLogic<'a> { }; let m = self.memory_get_vec(message_ptr, message_len)?; + let mut t_buf = [0u8; 8]; + t_buf[0..4].copy_from_slice(&t0.to_le_bytes()); + t_buf[4..8].copy_from_slice(&t1.to_le_bytes()); + let t = u64::from_le_bytes(t_buf); let mut hasher = match VarBlake2s::with_state(rounds, state, t) { Ok(h) => h, Err(Blake2Error::TooManyRounds { max, actual }) => { diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 2d1df161759..4fbef5eabe4 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -566,23 +566,52 @@ fn test_blake2b() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); - let data = b"tesdsst"; - logic.blake2b(data.len() as _, data.as_ptr() as _, 0).unwrap(); - let res = &vec![0u8; 64]; + let rounds = 12; + let h: [u64; 8] = [ + 0x6a09e667f2bdc948, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, + ]; + let m = b"abc"; + let t = 0; + let f0 = !0; + let f1 = 0; + + logic + .blake2b( + rounds, + h.len() as u64, + h.as_ptr() as _, + m.len() as u64, + m.as_ptr() as _, + t, + f0, + f1, + 0, + ) + .unwrap(); + + let res = [0u8; 64]; logic.read_register(0, res.as_ptr() as _).expect("OK"); - assert_eq!( - res, - &[ - 144, 12, 165, 192, 98, 246, 37, 228, 134, 61, 43, 212, 111, 32, 204, 204, 186, 212, 47, - 44, 209, 53, 167, 80, 195, 200, 226, 84, 34, 162, 249, 135, 172, 3, 90, 122, 205, 96, - 211, 100, 188, 18, 134, 125, 111, 130, 31, 143, 25, 108, 194, 209, 205, 73, 169, 10, - 132, 222, 75, 219, 103, 234, 67, 180 - ] - ); - let len = data.len() as u64; + + let expected: [u8; 64] = [ + 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, + 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, + 0xa2, 0xd1, 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde, 0x45, + 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a, 0xb9, 0x23, 0x86, 0xed, + 0xd4, 0x0, 0x99, 0x23, + ]; + assert_eq!(res, expected); + + let len = m.len() as u64 + (h.len() as u64 * 8); assert_costs(map! { ExtCosts::base: 1, - ExtCosts::read_memory_base: 1, + ExtCosts::read_memory_base: 2, ExtCosts::read_memory_byte: len, ExtCosts::write_memory_base: 1, ExtCosts::write_memory_byte: 64, @@ -591,82 +620,68 @@ fn test_blake2b() { ExtCosts::write_register_base: 1, ExtCosts::write_register_byte: 64, ExtCosts::blake2b_base: 1, - ExtCosts::blake2b_byte: len, + ExtCosts::blake2b_block: 1, + ExtCosts::blake2b_round: 12, }); } #[test] #[cfg(feature = "protocol_feature_evm")] -fn test_blake2b_f() { +fn test_blake2s() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); - let rounds: [u8; 4] = 1_u32.to_le_bytes(); + let rounds = 10; + // These must be u64, even though they are actually u32. let h: [u64; 8] = [ - 0x6a09e667f2bdc948, - 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, - 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, - 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, - 0x5be0cd19137e2179, - ]; - let m: [u64; 16] = [ - 0x0000000000636261, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, + 0x6b08e647, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, + 0x5be0cd19, ]; - let t: [u64; 2] = [3, 0]; - let f_bool: [u8; 1] = 1_u8.to_le_bytes(); + let m: &[u8; 3] = b"abc"; + let t0: u32 = 0; + let t1: u32 = 0; + let f0: u32 = !0; + let f1: u32 = 0; + logic - .blake2b_f( - rounds.as_ptr() as u64, - h.as_ptr() as u64, - m.as_ptr() as u64, - t.as_ptr() as u64, - f_bool.as_ptr() as u64, + .blake2s( + rounds, + h.len() as u64, + h.as_ptr() as _, + m.len() as u64, + m.as_ptr() as _, + t0, + t1, + f0, + f1, 0, ) .unwrap(); - let res = &vec![0u8; 64]; + let res = [0u8; 32]; logic.read_register(0, res.as_ptr() as _).expect("OK"); - assert_eq!( - res, - &[ - 0xB6, 0x3A, 0x38, 0x0C, 0xB2, 0x89, 0x7D, 0x52, 0x19, 0x94, 0xA8, 0x52, 0x34, 0xEE, - 0x2C, 0x18, 0x1B, 0x5F, 0x84, 0x4D, 0x2C, 0x62, 0x4C, 0x00, 0x26, 0x77, 0xE9, 0x70, - 0x34, 0x49, 0xD2, 0xFB, 0xA5, 0x51, 0xB3, 0xA8, 0x33, 0x3B, 0xCD, 0xF5, 0xF2, 0xF7, - 0xE0, 0x89, 0x93, 0xD5, 0x39, 0x23, 0xDE, 0x3D, 0x64, 0xFC, 0xC6, 0x8C, 0x03, 0x4E, - 0x71, 0x7B, 0x92, 0x93, 0xFE, 0xD7, 0xA4, 0x21 - ], - ); + let expected: [u8; 32] = [ + 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2, 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, + 0x2f, 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29, 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, + 0x59, 0x82, + ]; + assert_eq!(res, expected); + + let len = m.len() as u64 + (h.len() as u64 * 8); assert_costs(map! { ExtCosts::base: 1, - ExtCosts::blake2b_f_base: 1, + ExtCosts::read_memory_base: 2, + ExtCosts::read_memory_byte: len, + ExtCosts::write_memory_base: 1, + ExtCosts::write_memory_byte: 32, ExtCosts::read_register_base: 1, - ExtCosts::read_register_byte: 64, + ExtCosts::read_register_byte: 32, ExtCosts::write_register_base: 1, - ExtCosts::write_register_byte: 64, - ExtCosts::read_memory_base: 5, - ExtCosts::read_memory_byte: 4 + 64 + 128 + 8 + 8 + 1, // 213 per EIP-152 - ExtCosts::write_memory_base: 1, - ExtCosts::write_memory_byte: 64, + ExtCosts::write_register_byte: 32, + ExtCosts::blake2b_base: 1, + ExtCosts::blake2b_block: 1, + ExtCosts::blake2b_round: 10, }); } From bcc7dd2538030b2fd94d9e1a633d383ec888c1f5 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 17:45:13 +0700 Subject: [PATCH 059/134] Fix up ecrecover test --- runtime/near-vm-logic/Cargo.toml | 3 +-- runtime/near-vm-logic/tests/test_miscs.rs | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index cb494551189..5c75511d5a2 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -32,12 +32,11 @@ near-runtime-utils = { path = "../near-runtime-utils", version = "3.0.0" } bn = { package = "zeropool-bn", version = "0.5.9", features = [], optional = true } [dev-dependencies] -hex-literal = "0.2" serde_json = {version= "1", features= ["preserve_order"]} [features] default = [] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "blake2", "ripemd160", "libsecp256k1"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "near-vm-errors/protocol_feature_evm", "blake2", "ripemd160", "libsecp256k1"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 4fbef5eabe4..72a92f02b6f 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -688,16 +688,23 @@ fn test_blake2s() { #[test] #[cfg(feature = "protocol_feature_evm")] fn test_ecrecover() { - use hex_literal::hex; - let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); // See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/cryptography/ECDSA.test.js use sha3::Digest; let hash = sha3::Keccak256::digest(b"OpenZeppelin"); - let signature = hex!("5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be8921b"); - let signer = hex!("2cc1166f6212628A0deEf2B33BEFB2187D35b86c"); + let signature: [u8; 65] = [ + 0x5d, 0x99, 0xb6, 0xf7, 0xf6, 0xd1, 0xf7, 0x3d, 0x1a, 0x26, 0x49, 0x7f, 0x2b, 0x1c, 0x89, + 0xb2, 0x4c, 0x09, 0x93, 0x91, 0x3f, 0x86, 0xe9, 0xa2, 0xd0, 0x2c, 0xd6, 0x98, 0x87, 0xd9, + 0xc9, 0x4f, 0x3c, 0x88, 0x03, 0x58, 0x57, 0x9d, 0x81, 0x1b, 0x21, 0xdd, 0x1b, 0x7f, 0xd9, + 0xbb, 0x01, 0xc1, 0xd8, 0x1d, 0x10, 0xe6, 0x9f, 0x03, 0x84, 0xe6, 0x75, 0xc3, 0x2b, 0x39, + 0x64, 0x3b, 0xe8, 0x92, 0x1b, + ]; + let signer: [u8; 20] = [ + 0x2c, 0xc1, 0x16, 0x6f, 0x62, 0x12, 0x62, 0x8a, 0x0d, 0xee, 0xf2, 0xb3, 0x3b, 0xef, 0xb2, + 0x18, 0x7d, 0x35, 0xb8, 0x6c, + ]; logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0).unwrap(); @@ -707,8 +714,8 @@ fn test_ecrecover() { assert_eq!(result.to_vec(), signer); assert_costs(map! { ExtCosts::base: 1, - ExtCosts::read_memory_base: 3, - ExtCosts::read_memory_byte: 96, + ExtCosts::read_memory_base: 2, + ExtCosts::read_memory_byte: 97, ExtCosts::write_memory_base: 1, ExtCosts::write_memory_byte: 20, ExtCosts::read_register_base: 1, From 2f7cd2fadaff8f2d5ab4170822ec3b5ab2cfc108 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 27 May 2021 18:14:39 +0700 Subject: [PATCH 060/134] Fix blake2s args --- Cargo.lock | 1 - runtime/near-vm-runner/src/imports.rs | 2 +- runtime/runtime-params-estimator/test-contract/src/lib.rs | 5 ++++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50fded23747..90d465f507b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3627,7 +3627,6 @@ dependencies = [ "borsh", "bs58", "byteorder", - "hex-literal", "libsecp256k1", "near-blake2", "near-primitives", diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 8ac4942e344..eb3c39781ff 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -223,7 +223,7 @@ wrapped_imports! { keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] blake2b<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u32, f1: u32, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u32, t1: u32, f0: u32, f1: u32, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> []>, // ##################### // # Miscellaneous API # diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index d79c47d771b..bbb00f2155f 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -52,7 +52,7 @@ extern "C" { #[cfg(feature = "protocol_feature_evm")] fn blake2b(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64); #[cfg(feature = "protocol_feature_evm")] - fn blake2s(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u32, f1: u32, register_id: u64); + fn blake2s(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u32, t1: u32, f0: u32, f1: u32, register_id: u64); #[cfg(feature = "protocol_feature_evm")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### @@ -550,6 +550,7 @@ pub unsafe fn blake2s_128b_0r_10k() { buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0, + 0, !0, 0, 0 @@ -575,6 +576,7 @@ pub unsafe fn blake2s_128kb_0r_10k() { buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0, + 0, !0, 0, 0 @@ -600,6 +602,7 @@ pub unsafe fn blake2s_128b_10r_10k() { buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0, + 0, !0, 0, 0 From 844da2e69823669cae152f6c5e378f73977dd388 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 2 Jun 2021 21:34:31 +0700 Subject: [PATCH 061/134] Remove blake2 lib --- Cargo.lock | 13 +- core/crypto/Cargo.toml | 2 +- core/crypto/blake2/CHANGELOG.md | 62 --- core/crypto/blake2/Cargo.lock | 106 ----- core/crypto/blake2/Cargo.toml | 30 -- core/crypto/blake2/LICENSE-APACHE | 201 -------- core/crypto/blake2/LICENSE-MIT | 26 - core/crypto/blake2/README.md | 57 --- core/crypto/blake2/benches/blake2b.rs | 4 - core/crypto/blake2/benches/blake2s.rs | 4 - core/crypto/blake2/examples/blake2b_sum.rs | 47 -- core/crypto/blake2/examples/blake2s_sum.rs | 47 -- core/crypto/blake2/src/as_bytes.rs | 44 -- core/crypto/blake2/src/blake2.rs | 447 ------------------ core/crypto/blake2/src/blake2b.rs | 18 - core/crypto/blake2/src/blake2s.rs | 18 - core/crypto/blake2/src/consts.rs | 50 -- core/crypto/blake2/src/error.rs | 41 -- core/crypto/blake2/src/lib.rs | 112 ----- core/crypto/blake2/src/simd.rs | 142 ------ core/crypto/blake2/src/simd/simd_opt.rs | 51 -- core/crypto/blake2/src/simd/simd_opt/u32x4.rs | 67 --- core/crypto/blake2/src/simd/simd_opt/u64x4.rs | 132 ------ core/crypto/blake2/src/simd/simdint.rs | 22 - core/crypto/blake2/src/simd/simdop.rs | 88 ---- core/crypto/blake2/src/simd/simdty.rs | 77 --- .../blake2/tests/data/blake2b/fixed.blb | Bin 182 -> 0 bytes core/crypto/blake2/tests/data/blake2b/mac.blb | Bin 66318 -> 0 bytes .../blake2/tests/data/blake2b/variable.blb | Bin 53 -> 0 bytes core/crypto/blake2/tests/data/blake2s/mac.blb | Bin 49870 -> 0 bytes .../blake2/tests/data/blake2s/variable.blb | 1 - core/crypto/blake2/tests/lib.rs | 8 - core/crypto/blake2/tests/mac.rs | 6 - core/crypto/blake2/tests/persona.rs | 23 - core/crypto/blake2/tests/state.rs | 62 --- runtime/near-vm-logic/Cargo.toml | 2 +- 36 files changed, 3 insertions(+), 2007 deletions(-) delete mode 100644 core/crypto/blake2/CHANGELOG.md delete mode 100644 core/crypto/blake2/Cargo.lock delete mode 100644 core/crypto/blake2/Cargo.toml delete mode 100644 core/crypto/blake2/LICENSE-APACHE delete mode 100644 core/crypto/blake2/LICENSE-MIT delete mode 100644 core/crypto/blake2/README.md delete mode 100644 core/crypto/blake2/benches/blake2b.rs delete mode 100644 core/crypto/blake2/benches/blake2s.rs delete mode 100644 core/crypto/blake2/examples/blake2b_sum.rs delete mode 100644 core/crypto/blake2/examples/blake2s_sum.rs delete mode 100644 core/crypto/blake2/src/as_bytes.rs delete mode 100644 core/crypto/blake2/src/blake2.rs delete mode 100644 core/crypto/blake2/src/blake2b.rs delete mode 100644 core/crypto/blake2/src/blake2s.rs delete mode 100644 core/crypto/blake2/src/consts.rs delete mode 100644 core/crypto/blake2/src/error.rs delete mode 100644 core/crypto/blake2/src/lib.rs delete mode 100644 core/crypto/blake2/src/simd.rs delete mode 100644 core/crypto/blake2/src/simd/simd_opt.rs delete mode 100644 core/crypto/blake2/src/simd/simd_opt/u32x4.rs delete mode 100644 core/crypto/blake2/src/simd/simd_opt/u64x4.rs delete mode 100644 core/crypto/blake2/src/simd/simdint.rs delete mode 100644 core/crypto/blake2/src/simd/simdop.rs delete mode 100644 core/crypto/blake2/src/simd/simdty.rs delete mode 100644 core/crypto/blake2/tests/data/blake2b/fixed.blb delete mode 100644 core/crypto/blake2/tests/data/blake2b/mac.blb delete mode 100644 core/crypto/blake2/tests/data/blake2b/variable.blb delete mode 100644 core/crypto/blake2/tests/data/blake2s/mac.blb delete mode 100644 core/crypto/blake2/tests/data/blake2s/variable.blb delete mode 100644 core/crypto/blake2/tests/lib.rs delete mode 100644 core/crypto/blake2/tests/mac.rs delete mode 100644 core/crypto/blake2/tests/persona.rs delete mode 100644 core/crypto/blake2/tests/state.rs diff --git a/Cargo.lock b/Cargo.lock index 9b2a25325f1..e67301d78b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -566,15 +566,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "blobby" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" -dependencies = [ - "byteorder", -] - [[package]] name = "block-buffer" version = "0.7.3" @@ -1320,7 +1311,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "blobby", "generic-array 0.14.4", "subtle 2.4.0", ] @@ -1486,7 +1476,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "blobby", "generic-array 0.14.4", ] @@ -3030,10 +3019,10 @@ dependencies = [ [[package]] name = "near-blake2" version = "0.9.1" +source = "git+https://github.com/near/near-blake2.git#0a21d378670234e943d7efcc79e0b85629c99f57" dependencies = [ "crypto-mac 0.8.0", "digest 0.9.0", - "hex-literal", "opaque-debug 0.3.0", ] diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index 31be2938d38..e27f479f6f0 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { package = "near-blake2", path = "./blake2" } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/core/crypto/blake2/CHANGELOG.md b/core/crypto/blake2/CHANGELOG.md deleted file mode 100644 index 22ee2af94cd..00000000000 --- a/core/crypto/blake2/CHANGELOG.md +++ /dev/null @@ -1,62 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.9.1 (2020-10-26) -### Changed -- Bump `opaque-debug` to v0.3 ([#168]) -- Bump `block-buffer` to v0.9 ([#164]) - -[#168]: https://github.com/RustCrypto/hashes/pull/168 -[#164]: https://github.com/RustCrypto/hashes/pull/164 - -## 0.9.0 (2020-06-10) -### Added -- Support for Persona and Salt ([#78]) - -### Changed -- Update to `digest` v0.9 release; MSRV 1.41+ ([#155]) -- Use new `*Dirty` traits from the `digest` crate ([#153]) -- Bump `crypto-mac` to v0.8 release ([#152]) -- Bump `block-buffer` to v0.8 release ([#151]) -- Rename `*result*` to `finalize` ([#148]) -- Upgrade to Rust 2018 edition ([#119]) - -[#155]: https://github.com/RustCrypto/hashes/pull/155 -[#153]: https://github.com/RustCrypto/hashes/pull/153 -[#152]: https://github.com/RustCrypto/hashes/pull/152 -[#151]: https://github.com/RustCrypto/hashes/pull/151 -[#148]: https://github.com/RustCrypto/hashes/pull/148 -[#119]: https://github.com/RustCrypto/hashes/pull/133 -[#78]: https://github.com/RustCrypto/hashes/pull/78 - -## 0.8.1 (2019-08-25) - -## 0.8.0 (2018-10-11) - -## 0.7.1 (2018-04-30) - -## 0.7.0 (2017-11-15) - -## 0.6.1 (2017-07-24) - -## 0.6.0 (2017-06-12) - -## 0.5.2 (2017-05-17) - -## 0.5.1 (2017-05-02) - -## 0.5.0 (2017-04-06) - -## 0.4.0 (2017-03-06) - -## 0.3.0 (2016-11-17) - -## 0.2.0 (2016-10-14) - -## 0.1.1 (2016-10-11) - -## 0.1.0 (2016-10-09) diff --git a/core/crypto/blake2/Cargo.lock b/core/crypto/blake2/Cargo.lock deleted file mode 100644 index 77bc64f337f..00000000000 --- a/core/crypto/blake2/Cargo.lock +++ /dev/null @@ -1,106 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blake2" -version = "0.9.1" -dependencies = [ - "crypto-mac", - "digest", - "hex-literal", - "opaque-debug", -] - -[[package]] -name = "blobby" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" -dependencies = [ - "byteorder", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "blobby", - "generic-array", - "subtle", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "blobby", - "generic-array", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "hex-literal" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] - -[[package]] -name = "hex-literal-impl" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" -dependencies = [ - "proc-macro-hack", -] - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "subtle" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" - -[[package]] -name = "typenum" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" diff --git a/core/crypto/blake2/Cargo.toml b/core/crypto/blake2/Cargo.toml deleted file mode 100644 index c07f9c328ee..00000000000 --- a/core/crypto/blake2/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "near-blake2" -version = "0.9.1" -description = "BLAKE2 hash functions" -authors = [ - "RustCrypto Developers", - "Near Inc ", -] -license = "MIT OR Apache-2.0" -readme = "README.md" -edition = "2018" -keywords = ["crypto", "blake2", "hash", "digest"] -categories = ["cryptography", "no-std"] - -[dependencies] -digest = "0.9" -crypto-mac = "0.8" -opaque-debug = "0.3" - -[dev-dependencies] -digest = { version = "0.9", features = ["dev"] } -crypto-mac = { version = "0.8", features = ["dev"] } -hex-literal = "0.2" - -[features] -default = ["std"] -std = ["digest/std", "crypto-mac/std"] -simd = [] -simd_opt = ["simd"] -simd_asm = ["simd_opt"] diff --git a/core/crypto/blake2/LICENSE-APACHE b/core/crypto/blake2/LICENSE-APACHE deleted file mode 100644 index 78173fa2e75..00000000000 --- a/core/crypto/blake2/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/core/crypto/blake2/LICENSE-MIT b/core/crypto/blake2/LICENSE-MIT deleted file mode 100644 index 872e206f2fe..00000000000 --- a/core/crypto/blake2/LICENSE-MIT +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2015-2016 The blake2-rfc Developers, Cesar Barros -Copyright (c) 2017 Artyom Pavlov - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/core/crypto/blake2/README.md b/core/crypto/blake2/README.md deleted file mode 100644 index 6915156d4a7..00000000000 --- a/core/crypto/blake2/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# RustCrypto: BLAKE2 - -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] - -Pure Rust implementation of the [BLAKE2 hash function][1] family with changes to -the compression function to specify an amount of rounds. - -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.41** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - -## License - -Licensed under either of: - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://img.shields.io/crates/v/blake2.svg -[crate-link]: https://crates.io/crates/blake2 -[docs-image]: https://docs.rs/blake2/badge.svg -[docs-link]: https://docs.rs/blake2/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[build-image]: https://github.com/RustCrypto/hashes/workflows/blake2/badge.svg?branch=master -[build-link]: https://github.com/RustCrypto/hashes/actions?query=workflow%3Ablake2 - -[//]: # (general links) - -[1]: https://blake2.net/ diff --git a/core/crypto/blake2/benches/blake2b.rs b/core/crypto/blake2/benches/blake2b.rs deleted file mode 100644 index 5c3f4e7e7d3..00000000000 --- a/core/crypto/blake2/benches/blake2b.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![no_std] -#![feature(test)] - -digest::bench!(blake2::Blake2b); diff --git a/core/crypto/blake2/benches/blake2s.rs b/core/crypto/blake2/benches/blake2s.rs deleted file mode 100644 index dba70e921cd..00000000000 --- a/core/crypto/blake2/benches/blake2s.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![no_std] -#![feature(test)] - -digest::bench!(blake2::Blake2s); diff --git a/core/crypto/blake2/examples/blake2b_sum.rs b/core/crypto/blake2/examples/blake2b_sum.rs deleted file mode 100644 index 01a39e1a072..00000000000 --- a/core/crypto/blake2/examples/blake2b_sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use near_blake2::{Blake2b, Digest}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/core/crypto/blake2/examples/blake2s_sum.rs b/core/crypto/blake2/examples/blake2s_sum.rs deleted file mode 100644 index c3b7a4898cd..00000000000 --- a/core/crypto/blake2/examples/blake2s_sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use near_blake2::{Blake2s, Digest}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/core/crypto/blake2/src/as_bytes.rs b/core/crypto/blake2/src/as_bytes.rs deleted file mode 100644 index 02cca6bbade..00000000000 --- a/core/crypto/blake2/src/as_bytes.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use core::mem; -use core::slice; - -pub unsafe trait Safe {} - -pub trait AsBytes { - fn as_bytes(&self) -> &[u8]; - fn as_mut_bytes(&mut self) -> &mut [u8]; -} - -impl AsBytes for [T] { - #[inline] - fn as_bytes(&self) -> &[u8] { - unsafe { - slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * mem::size_of::()) - } - } - - #[inline] - fn as_mut_bytes(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self.as_mut_ptr() as *mut u8, - self.len() * mem::size_of::(), - ) - } - } -} - -unsafe impl Safe for u8 {} -unsafe impl Safe for u16 {} -unsafe impl Safe for u32 {} -unsafe impl Safe for u64 {} -unsafe impl Safe for i8 {} -unsafe impl Safe for i16 {} -unsafe impl Safe for i32 {} -unsafe impl Safe for i64 {} diff --git a/core/crypto/blake2/src/blake2.rs b/core/crypto/blake2/src/blake2.rs deleted file mode 100644 index 6a222b6910b..00000000000 --- a/core/crypto/blake2/src/blake2.rs +++ /dev/null @@ -1,447 +0,0 @@ -macro_rules! blake2_impl { - ( - $state:ident, $fix_state:ident, $word:ident, $vec:ident, $bytes:ident, - $block_size:ident, $R1:expr, $R2:expr, $R3:expr, $R4:expr, $IV:expr, - $vardoc:expr, $doc:expr, - ) => { - use $crate::as_bytes::AsBytes; - use $crate::error::Error; - use $crate::simd::{$vec, Vector4}; - - use core::{cmp, convert::TryInto, ops::Div}; - use crypto_mac::{InvalidKeyLength, Mac, NewMac}; - use digest::generic_array::typenum::{Unsigned, U4}; - use digest::generic_array::GenericArray; - use digest::InvalidOutputSize; - use digest::{BlockInput, FixedOutputDirty, Reset, Update, VariableOutputDirty}; - - type Output = GenericArray; - - #[derive(Clone)] - #[doc=$vardoc] - pub struct $state { - m: [$word; 16], - h: [$vec; 2], - t: u64, - n: usize, - - h0: [$vec; 2], - m0: [$word; 16], - t0: u64, - - rounds: u32, - } - - // Can't make this a const, else it would be great as that. - fn max_rounds() -> u32 { - if $bytes::to_u8() == 64 { - 12 - } else { - 10 - } - } - - #[inline(always)] - fn iv0() -> $vec { - $vec::new($IV[0], $IV[1], $IV[2], $IV[3]) - } - #[inline(always)] - fn iv1() -> $vec { - $vec::new($IV[4], $IV[5], $IV[6], $IV[7]) - } - - #[inline(always)] - fn quarter_round(v: &mut [$vec; 4], rd: u32, rb: u32, m: $vec) { - v[0] = v[0].wrapping_add(v[1]).wrapping_add(m.from_le()); - v[3] = (v[3] ^ v[0]).rotate_right_const(rd); - v[2] = v[2].wrapping_add(v[3]); - v[1] = (v[1] ^ v[2]).rotate_right_const(rb); - } - - #[inline(always)] - fn shuffle(v: &mut [$vec; 4]) { - v[1] = v[1].shuffle_left_1(); - v[2] = v[2].shuffle_left_2(); - v[3] = v[3].shuffle_left_3(); - } - - #[inline(always)] - fn unshuffle(v: &mut [$vec; 4]) { - v[1] = v[1].shuffle_right_1(); - v[2] = v[2].shuffle_right_2(); - v[3] = v[3].shuffle_right_3(); - } - - #[inline(always)] - fn round(v: &mut [$vec; 4], m: &[$word; 16], s: &[usize; 16]) { - quarter_round(v, $R1, $R2, $vec::gather(m, s[0], s[2], s[4], s[6])); - quarter_round(v, $R3, $R4, $vec::gather(m, s[1], s[3], s[5], s[7])); - - shuffle(v); - quarter_round(v, $R1, $R2, $vec::gather(m, s[8], s[10], s[12], s[14])); - quarter_round(v, $R3, $R4, $vec::gather(m, s[9], s[11], s[13], s[15])); - unshuffle(v); - } - - impl $state { - /// Creates a new hashing context with a key. - /// - /// **WARNING!** If you plan to use it for variable output MAC, then - /// make sure to compare codes in constant time! It can be done - /// for example by using `subtle` crate. - pub fn new_keyed(key: &[u8], output_size: usize) -> Self { - Self::with_params(key, &[], &[], output_size) - } - - /// Creates a new hashing context with the full set of sequential-mode parameters. - pub fn with_params( - key: &[u8], - salt: &[u8], - persona: &[u8], - output_size: usize, - ) -> Self { - let kk = key.len(); - assert!(kk <= $bytes::to_usize()); - assert!(output_size <= $bytes::to_usize()); - - // The number of bytes needed to express two words. - let length = $bytes::to_usize() / 4; - assert!(salt.len() <= length); - assert!(persona.len() <= length); - - // Build a parameter block - let mut p = [0 as $word; 8]; - p[0] = 0x0101_0000 ^ ((kk as $word) << 8) ^ (output_size as $word); - - // salt is two words long - if salt.len() < length { - let mut padded_salt = - GenericArray::>::Output>::default(); - for i in 0..salt.len() { - padded_salt[i] = salt[i]; - } - p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap()); - p[5] = $word::from_le_bytes( - padded_salt[length / 2..padded_salt.len()].try_into().unwrap(), - ); - } else { - p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap()); - p[5] = - $word::from_le_bytes(salt[salt.len() / 2..salt.len()].try_into().unwrap()); - } - - // persona is also two words long - if persona.len() < length { - let mut padded_persona = - GenericArray::>::Output>::default(); - for i in 0..persona.len() { - padded_persona[i] = persona[i]; - } - p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap()); - p[7] = $word::from_le_bytes( - padded_persona[length / 2..padded_persona.len()].try_into().unwrap(), - ); - } else { - p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap()); - p[7] = $word::from_le_bytes( - persona[length / 2..persona.len()].try_into().unwrap(), - ); - } - - let mut state = Self::with_parameter_block(&p); - - if kk > 0 { - copy(key, state.m.as_mut_bytes()); - state.t = 2 * $bytes::to_u64(); - } - - state.t0 = state.t; - state.m0 = state.m; - state - } - - #[doc(hidden)] - pub fn with_parameter_block(p: &[$word; 8]) -> Self { - let nn = p[0] as u8 as usize; - let kk = (p[0] >> 8) as u8 as usize; - assert!(nn >= 1 && nn <= $bytes::to_usize()); - assert!(kk <= $bytes::to_usize()); - - let h0 = [ - iv0() ^ $vec::new(p[0], p[1], p[2], p[3]), - iv1() ^ $vec::new(p[4], p[5], p[6], p[7]), - ]; - - $state { - m: [0; 16], - h: h0, - t: 0, - n: nn, - - t0: 0, - m0: [0; 16], - h0, - - rounds: max_rounds(), - } - } - - /// Constructs a new hashing context with a given state. - /// - /// This enables continued hashing of a pre-hashed state. - /// - /// **Warning**: The user of this method is responsible for the - /// initialization of the vectors for the first round. - pub fn with_state(rounds: u32, state: [$word; 8], t: u64) -> Result { - if rounds > 12 { - return Err(Error::TooManyRounds { max: max_rounds(), actual: rounds }); - } - - let h0 = [ - $vec::new(state[0], state[1], state[2], state[3]), - $vec::new(state[4], state[5], state[6], state[7]), - ]; - let nn = $bytes::to_u8() as usize; - - Ok($state { m: [0; 16], h: h0, t, n: nn, t0: t, m0: [0; 16], h0, rounds }) - } - - /// Updates the hashing context with more data. - pub fn update_inner(&mut self, data: &[u8]) -> Result<(), Error> { - let mut rest = data; - - let block = 2 * $bytes::to_usize(); - - let off = self.t as usize % block; - if off != 0 || self.t == 0 { - let len = cmp::min(block - off, rest.len()); - - let part = &rest[..len]; - rest = &rest[part.len()..]; - - copy(part, &mut self.m.as_mut_bytes()[off..]); - self.t = match self.t.checked_add(part.len() as u64) { - Some(v) => v, - None => return Err(Error::HashDataOverflow), - } - } - - while rest.len() >= block { - self.compress(0, 0); - - let part = &rest[..block]; - rest = &rest[part.len()..]; - - copy(part, &mut self.m.as_mut_bytes()); - self.t = match self.t.checked_add(part.len() as u64) { - Some(v) => v, - None => return Err(Error::HashDataOverflow), - } - } - - let n = rest.len(); - if n > 0 { - self.compress(0, 0); - - copy(rest, &mut self.m.as_mut_bytes()); - self.t = match self.t.checked_add(rest.len() as u64) { - Some(v) => v, - None => return Err(Error::HashDataOverflow), - } - } - - Ok(()) - } - - #[doc(hidden)] - pub fn finalize_last_node(mut self) -> Output { - self.finalize_with_flag(!0) - } - - fn finalize_with_flag(&mut self, f1: $word) -> Output { - let off = self.t as usize % (2 * $bytes::to_usize()); - if off != 0 { - self.m.as_mut_bytes()[off..].iter_mut().for_each(|b| *b = 0); - } - - self.compress(!0, f1); - - self.output() - } - - /// Compression `F` function. - pub fn compress(&mut self, f0: $word, f1: $word) { - use $crate::consts::SIGMA; - - let m = &self.m; - let h = &mut self.h; - - let t0 = self.t as $word; - let t1 = match $bytes::to_u8() { - 64 => 0, - 32 => (self.t >> 32) as $word, - _ => unreachable!(), - }; - - let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; - - for x in 1..=self.rounds { - let x = if x > 10 { x - 11 } else { x - 1 }; - round(&mut v, &m, &SIGMA[x as usize]); - } - - h[0] = h[0] ^ (v[0] ^ v[2]); - h[1] = h[1] ^ (v[1] ^ v[3]); - } - - /// Returns the current count value `t`. - pub fn counter(&self) -> u64 { - self.t - } - - /// Returns the current hashed state. - pub fn output(&self) -> Output { - let buf = [self.h[0].to_le(), self.h[1].to_le()]; - - let mut out = GenericArray::default(); - copy(buf.as_bytes(), &mut out); - out - } - } - - impl Default for $state { - fn default() -> Self { - Self::new_keyed(&[], $bytes::to_usize()) - } - } - - impl BlockInput for $state { - type BlockSize = $block_size; - } - - impl Update for $state { - fn update(&mut self, data: impl AsRef<[u8]>) { - self.update_inner(data.as_ref()).unwrap(); - } - } - - impl VariableOutputDirty for $state { - fn new(output_size: usize) -> Result { - if output_size == 0 || output_size > $bytes::to_usize() { - return Err(InvalidOutputSize); - } - Ok(Self::new_keyed(&[], output_size)) - } - - fn output_size(&self) -> usize { - self.n - } - - fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])) { - let n = self.n; - let res = self.finalize_with_flag(0); - f(&res[..n]); - } - } - - impl Reset for $state { - fn reset(&mut self) { - self.t = self.t0; - self.m = self.m0; - self.h = self.h0; - } - } - - opaque_debug::implement!($state); - digest::impl_write!($state); - - #[derive(Clone)] - #[doc=$doc] - pub struct $fix_state { - state: $state, - } - - impl $fix_state { - /// Creates a new hashing context with the full set of sequential-mode parameters. - pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8]) -> Self { - let state = $state::with_params(key, salt, persona, $bytes::to_usize()); - Self { state } - } - } - - impl Default for $fix_state { - fn default() -> Self { - let state = $state::new_keyed(&[], $bytes::to_usize()); - Self { state } - } - } - - impl BlockInput for $fix_state { - type BlockSize = $block_size; - } - - impl Update for $fix_state { - fn update(&mut self, data: impl AsRef<[u8]>) { - self.state.update_inner(data.as_ref()).unwrap(); - } - } - - impl FixedOutputDirty for $fix_state { - type OutputSize = $bytes; - - fn finalize_into_dirty(&mut self, out: &mut Output) { - out.copy_from_slice(&self.state.finalize_with_flag(0)); - } - } - - impl Reset for $fix_state { - fn reset(&mut self) { - self.state.reset() - } - } - - impl NewMac for $fix_state { - type KeySize = $bytes; - - fn new(key: &GenericArray) -> Self { - let state = $state::new_keyed(key, $bytes::to_usize()); - Self { state } - } - - fn new_varkey(key: &[u8]) -> Result { - if key.len() > $bytes::to_usize() { - Err(InvalidKeyLength) - } else { - let state = $state::new_keyed(key, $bytes::to_usize()); - Ok(Self { state }) - } - } - } - - impl Mac for $fix_state { - type OutputSize = $bytes; - - fn update(&mut self, data: &[u8]) { - self.state.update_inner(data).unwrap(); - } - - fn reset(&mut self) { - ::reset(self) - } - - fn finalize(mut self) -> crypto_mac::Output { - crypto_mac::Output::new(self.state.finalize_with_flag(0)) - } - } - - opaque_debug::implement!($fix_state); - digest::impl_write!($fix_state); - - fn copy(src: &[u8], dst: &mut [u8]) { - assert!(dst.len() >= src.len()); - unsafe { - core::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()); - } - } - }; -} diff --git a/core/crypto/blake2/src/blake2b.rs b/core/crypto/blake2/src/blake2b.rs deleted file mode 100644 index 3afc18d84a5..00000000000 --- a/core/crypto/blake2/src/blake2b.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::consts::BLAKE2B_IV; -use digest::generic_array::typenum::{U128, U64}; - -blake2_impl!( - VarBlake2b, - Blake2b, - u64, - u64x4, - U64, - U128, - 32, - 24, - 16, - 63, - BLAKE2B_IV, - "Blake2b instance with a variable output.", - "Blake2b instance with a fixed output.", -); diff --git a/core/crypto/blake2/src/blake2s.rs b/core/crypto/blake2/src/blake2s.rs deleted file mode 100644 index 5306ed99218..00000000000 --- a/core/crypto/blake2/src/blake2s.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::consts::BLAKE2S_IV; -use digest::generic_array::typenum::{U32, U64}; - -blake2_impl!( - VarBlake2s, - Blake2s, - u32, - u32x4, - U32, - U64, - 16, - 12, - 8, - 7, - BLAKE2S_IV, - "Blake2s instance with a variable output.", - "Blake2s instance with a fixed output.", -); diff --git a/core/crypto/blake2/src/consts.rs b/core/crypto/blake2/src/consts.rs deleted file mode 100644 index fed82e0ddf6..00000000000 --- a/core/crypto/blake2/src/consts.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![allow(clippy::unreadable_literal)] - -/// Message word permutations. -pub static SIGMA: [[usize; 16]; 12] = [ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], - [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], - [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], - [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], - [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], - [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], - [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], - [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], - [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], -]; - -/// Blake2b initialization vector. -pub static BLAKE2B_IV: [u64; 8] = [ - 0x6a09e667f3bcc908, - 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, - 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, - 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, - 0x5be0cd19137e2179, -]; - -/* -pub const BLAKE2B_BLOCKBYTES : usize = 128; -pub const BLAKE2B_OUTBYTES : usize = 64; -pub const BLAKE2B_KEYBYTES : usize = 64; -pub const BLAKE2B_SALTBYTES : usize = 16; -pub const BLAKE2B_PERSONALBYTES : usize = 16; -*/ - -/// Blake2s initialization vector. -pub static BLAKE2S_IV: [u32; 8] = [ - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19, -]; - -/* -pub const BLAKE2S_BLOCKBYTES : usize = 64; -pub const BLAKE2S_OUTBYTES : usize = 32; -pub const BLAKE2S_KEYBYTES : usize = 32; -pub const BLAKE2S_SALTBYTES : usize = 8; -pub const BLAKE2S_PERSONALBYTES : usize = 8; -*/ diff --git a/core/crypto/blake2/src/error.rs b/core/crypto/blake2/src/error.rs deleted file mode 100644 index 75774c0b336..00000000000 --- a/core/crypto/blake2/src/error.rs +++ /dev/null @@ -1,41 +0,0 @@ -use core::fmt; - -/// An error that occurred during parsing or hashing. -#[derive(Clone, PartialEq)] -#[non_exhaustive] -pub enum Error { - /// A data overflow error. - HashDataOverflow, - /// Too many rounds error. - TooManyRounds { - /// Max rounds allowed. - max: u32, - /// Actual round value. - actual: u32, - }, -} - -// This prints better looking error messages if `unwrap` is called. -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use Error::*; - match *self { - HashDataOverflow => f.debug_tuple("HashDataOverflow").finish(), - TooManyRounds { ref max, ref actual } => { - f.debug_struct("TooManyRounds").field("max", max).field("actual", actual).finish() - } - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use Error::*; - match *self { - HashDataOverflow => write!(f, "Hash data length overflow."), - TooManyRounds { ref max, ref actual } => { - write!(f, "Too many rounds. Expected fewer than {}, got {}.", max, actual) - } - } - } -} diff --git a/core/crypto/blake2/src/lib.rs b/core/crypto/blake2/src/lib.rs deleted file mode 100644 index 2191fb9918a..00000000000 --- a/core/crypto/blake2/src/lib.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! An implementation of the [BLAKE2][1] hash functions. -//! -//! # Usage -//! -//! `Blake2b` can be used in the following way: -//! -//! ```rust -//! use near_blake2::{Blake2b, Blake2s, Digest}; -//! use hex_literal::hex; -//! -//! // create a Blake2b object -//! let mut hasher = Blake2b::new(); -//! -//! // write input message -//! hasher.update(b"hello world"); -//! -//! // read hash digest and consume hasher -//! let res = hasher.finalize(); -//! assert_eq!(res[..], hex!(" -//! 021ced8799296ceca557832ab941a50b4a11f83478cf141f51f933f653ab9fbc -//! c05a037cddbed06e309bf334942c4e58cdf1a46e237911ccd7fcf9787cbc7fd0 -//! ")[..]); -//! -//! // same example for `Blake2s`: -//! let mut hasher = Blake2s::new(); -//! hasher.update(b"hello world"); -//! let res = hasher.finalize(); -//! assert_eq!(res[..], hex!(" -//! 9aec6806794561107e594b1f6a8a6b0c92a0cba9acf5e5e93cca06f781813b0b -//! ")[..]); -//! ``` -//! -//! Also see [RustCrypto/hashes](https://github.com/RustCrypto/hashes) readme. -//! -//! ## Variable output size -//! -//! If you need variable sized output you can use `VarBlake2b` and `VarBlake2s` -//! which support variable output sizes through `VariableOutput` trait. `Update` -//! trait has to be imported as well. -//! -//! ```rust -//! use near_blake2::VarBlake2b; -//! use near_blake2::digest::{Update, VariableOutput}; -//! -//! let mut hasher = VarBlake2b::new(10).unwrap(); -//! hasher.update(b"my_input"); -//! hasher.finalize_variable(|res| { -//! assert_eq!(res, [44, 197, 92, 132, 228, 22, 146, 78, 100, 0]) -//! }) -//! ``` -//! -//! ## Message Authentication Code (MAC) -//! -//! BLAKE2 can be used as a MAC without any additional constructs: -//! -//! ```rust -//! use near_blake2::Blake2b; -//! use near_blake2::crypto_mac::{Mac, NewMac}; -//! -//! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); -//! hasher.update(b"hello world"); -//! -//! // `result` has type `crypto_mac::Output` which is a thin wrapper around -//! // a byte array and provides a constant time equality check -//! let result = hasher.finalize(); -//! // To get underlying array use the `into_bytes` method, but be careful, -//! // since incorrect use of the code value may permit timing attacks which -//! // defeat the security provided by the `crypto_mac::Output` -//! let code_bytes = result.into_bytes(); -//! -//! // To verify the message it's recommended to use `verify` method -//! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); -//! hasher.update(b"hello world"); -//! // `verify` return `Ok(())` if code is correct, `Err(MacError)` otherwise -//! hasher.verify(&code_bytes).unwrap(); -//! ``` -//! -//! # Acknowledgment -//! Based on the [blake2-rfc][2] crate. -//! -//! [1]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2 -//! [2]: https://github.com/cesarb/blake2-rfc - -#![no_std] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - -mod as_bytes; -mod consts; - -mod simd; - -#[macro_use] -mod blake2; - -mod blake2b; -mod blake2s; -mod error; - -pub use crypto_mac; -pub use digest::{self, Digest}; - -pub use crate::blake2b::{Blake2b, VarBlake2b}; -pub use crate::blake2s::{Blake2s, VarBlake2s}; -pub use crate::consts::{BLAKE2B_IV, BLAKE2S_IV, SIGMA}; -pub use crate::error::Error; diff --git a/core/crypto/blake2/src/simd.rs b/core/crypto/blake2/src/simd.rs deleted file mode 100644 index c3f8d3bcaa9..00000000000 --- a/core/crypto/blake2/src/simd.rs +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2015 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -mod simd_opt; -mod simdint; -mod simdop; -mod simdty; - -pub use self::simdty::{u32x4, u64x4}; - -pub trait Vector4: Copy { - fn gather(src: &[T], i0: usize, i1: usize, i2: usize, i3: usize) -> Self; - - // Usually, this should be fixed but to keep it inline with blake2 upstream, - // we will leave it as is for maximum compatibility. - #[allow(clippy::wrong_self_convention)] - fn from_le(self) -> Self; - fn to_le(self) -> Self; - fn to_be(self) -> Self; - - fn wrapping_add(self, rhs: Self) -> Self; - - fn rotate_right_const(self, n: u32) -> Self; - - fn shuffle_left_1(self) -> Self; - fn shuffle_left_2(self) -> Self; - fn shuffle_left_3(self) -> Self; - - #[inline(always)] - fn shuffle_right_1(self) -> Self { - self.shuffle_left_3() - } - #[inline(always)] - fn shuffle_right_2(self) -> Self { - self.shuffle_left_2() - } - #[inline(always)] - fn shuffle_right_3(self) -> Self { - self.shuffle_left_1() - } -} - -macro_rules! impl_vector4 { - ($vec:ident, $word:ident) => { - impl Vector4<$word> for $vec { - #[inline(always)] - fn gather(src: &[$word], i0: usize, i1: usize, i2: usize, i3: usize) -> Self { - $vec::new(src[i0], src[i1], src[i2], src[i3]) - } - - #[cfg(target_endian = "little")] - #[inline(always)] - fn from_le(self) -> Self { - self - } - - #[cfg(not(target_endian = "little"))] - #[inline(always)] - fn from_le(self) -> Self { - $vec::new( - $word::from_le(self.0), - $word::from_le(self.1), - $word::from_le(self.2), - $word::from_le(self.3), - ) - } - - #[cfg(target_endian = "little")] - #[inline(always)] - fn to_le(self) -> Self { - self - } - - #[cfg(not(target_endian = "little"))] - #[inline(always)] - fn to_le(self) -> Self { - $vec::new(self.0.to_le(), self.1.to_le(), self.2.to_le(), self.3.to_le()) - } - - #[inline(always)] - fn to_be(self) -> Self { - $vec::new(self.0.to_be(), self.1.to_be(), self.2.to_be(), self.3.to_be()) - } - - #[inline(always)] - fn wrapping_add(self, rhs: Self) -> Self { - self + rhs - } - - #[inline(always)] - fn rotate_right_const(self, n: u32) -> Self { - simd_opt::$vec::rotate_right_const(self, n) - } - - #[cfg(feature = "simd")] - #[inline(always)] - fn shuffle_left_1(self) -> Self { - use crate::simd::simdint::simd_shuffle4; - unsafe { simd_shuffle4(self, self, [1, 2, 3, 0]) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn shuffle_left_1(self) -> Self { - $vec::new(self.1, self.2, self.3, self.0) - } - - #[cfg(feature = "simd")] - #[inline(always)] - fn shuffle_left_2(self) -> Self { - use crate::simd::simdint::simd_shuffle4; - unsafe { simd_shuffle4(self, self, [2, 3, 0, 1]) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn shuffle_left_2(self) -> Self { - $vec::new(self.2, self.3, self.0, self.1) - } - - #[cfg(feature = "simd")] - #[inline(always)] - fn shuffle_left_3(self) -> Self { - use crate::simd::simdint::simd_shuffle4; - unsafe { simd_shuffle4(self, self, [3, 0, 1, 2]) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn shuffle_left_3(self) -> Self { - $vec::new(self.3, self.0, self.1, self.2) - } - } - }; -} - -impl_vector4!(u32x4, u32); -impl_vector4!(u64x4, u64); diff --git a/core/crypto/blake2/src/simd/simd_opt.rs b/core/crypto/blake2/src/simd/simd_opt.rs deleted file mode 100644 index e143ba4ec80..00000000000 --- a/core/crypto/blake2/src/simd/simd_opt.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -#[allow(unused_macros)] -#[cfg(feature = "simd")] -macro_rules! transmute_shuffle { - ($tmp:ident, $shuffle:ident, $vec:expr, $idx:expr) => { - unsafe { - use crate::simd::simdint::$shuffle; - use crate::simd::simdty::$tmp; - use core::mem::transmute; - - let tmp_i: $tmp = transmute($vec); - let tmp_o: $tmp = $shuffle(tmp_i, tmp_i, $idx); - transmute(tmp_o) - } - }; -} - -#[cfg(feature = "simd")] -pub mod u32x4; -#[cfg(feature = "simd")] -pub mod u64x4; - -#[cfg(not(feature = "simd"))] -macro_rules! simd_opt { - ($vec:ident) => { - pub mod $vec { - use crate::simd::simdty::$vec; - - #[inline(always)] - pub fn rotate_right_const(vec: $vec, n: u32) -> $vec { - $vec::new( - vec.0.rotate_right(n), - vec.1.rotate_right(n), - vec.2.rotate_right(n), - vec.3.rotate_right(n), - ) - } - } - }; -} - -#[cfg(not(feature = "simd"))] -simd_opt!(u32x4); -#[cfg(not(feature = "simd"))] -simd_opt!(u64x4); diff --git a/core/crypto/blake2/src/simd/simd_opt/u32x4.rs b/core/crypto/blake2/src/simd/simd_opt/u32x4.rs deleted file mode 100644 index a3d8e3d6d4a..00000000000 --- a/core/crypto/blake2/src/simd/simd_opt/u32x4.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use crate::simd::simdty::u32x4; - -#[cfg(feature = "simd_opt")] -#[inline(always)] -pub fn rotate_right_const(vec: u32x4, n: u32) -> u32x4 { - match n { - 16 => rotate_right_16(vec), - 8 => rotate_right_8(vec), - _ => rotate_right_any(vec, n), - } -} - -#[cfg(not(feature = "simd_opt"))] -#[inline(always)] -pub fn rotate_right_const(vec: u32x4, n: u32) -> u32x4 { - rotate_right_any(vec, n) -} - -#[inline(always)] -fn rotate_right_any(vec: u32x4, n: u32) -> u32x4 { - let r = n as u32; - let l = 32 - r; - - (vec >> u32x4::new(r, r, r, r)) ^ (vec << u32x4::new(l, l, l, l)) -} - -#[cfg(feature = "simd_opt")] -#[inline(always)] -fn rotate_right_16(vec: u32x4) -> u32x4 { - if cfg!(target_feature = "ssse3") { - // pshufb (SSSE3) / vpshufb (AVX2) - transmute_shuffle!( - u8x16, - simd_shuffle16, - vec, - [2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13] - ) - } else if cfg!(any(target_feature = "sse2", target_feature = "neon")) { - // pshuflw+pshufhw (SSE2) / vrev (NEON) - transmute_shuffle!(u16x8, simd_shuffle8, vec, [1, 0, 3, 2, 5, 4, 7, 6]) - } else { - rotate_right_any(vec, 16) - } -} - -#[cfg(feature = "simd_opt")] -#[inline(always)] -fn rotate_right_8(vec: u32x4) -> u32x4 { - if cfg!(target_feature = "ssse3") { - // pshufb (SSSE3) / vpshufb (AVX2) - transmute_shuffle!( - u8x16, - simd_shuffle16, - vec, - [1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12] - ) - } else { - rotate_right_any(vec, 8) - } -} diff --git a/core/crypto/blake2/src/simd/simd_opt/u64x4.rs b/core/crypto/blake2/src/simd/simd_opt/u64x4.rs deleted file mode 100644 index 31bdc620938..00000000000 --- a/core/crypto/blake2/src/simd/simd_opt/u64x4.rs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2015 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use crate::simd::simdty::u64x4; - -#[cfg(feature = "simd_opt")] -#[inline(always)] -pub fn rotate_right_const(vec: u64x4, n: u32) -> u64x4 { - match n { - 32 => rotate_right_32(vec), - 24 => rotate_right_24(vec), - 16 => rotate_right_16(vec), - _ => rotate_right_any(vec, n), - } -} - -#[cfg(not(feature = "simd_opt"))] -#[inline(always)] -pub fn rotate_right_const(vec: u64x4, n: u32) -> u64x4 { - rotate_right_any(vec, n) -} - -#[inline(always)] -fn rotate_right_any(vec: u64x4, n: u32) -> u64x4 { - let r = n as u64; - let l = 64 - r; - - (vec >> u64x4::new(r, r, r, r)) ^ (vec << u64x4::new(l, l, l, l)) -} - -#[cfg(feature = "simd_opt")] -#[inline(always)] -fn rotate_right_32(vec: u64x4) -> u64x4 { - if cfg!(any(target_feature = "sse2", target_feature = "neon")) { - // 2 x pshufd (SSE2) / vpshufd (AVX2) / 2 x vrev (NEON) - transmute_shuffle!(u32x8, simd_shuffle8, vec, [1, 0, 3, 2, 5, 4, 7, 6]) - } else { - rotate_right_any(vec, 32) - } -} - -#[cfg(feature = "simd_opt")] -#[inline(always)] -fn rotate_right_24(vec: u64x4) -> u64x4 { - if cfg!(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm")) { - // 4 x vext (NEON) - rotate_right_vext(vec, 3) - } else if cfg!(target_feature = "ssse3") { - // 2 x pshufb (SSSE3) / vpshufb (AVX2) - transmute_shuffle!( - u8x32, - simd_shuffle32, - vec, - [ - 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 19, 20, 21, 22, 23, 16, 17, - 18, 27, 28, 29, 30, 31, 24, 25, 26 - ] - ) - } else { - rotate_right_any(vec, 24) - } -} - -#[cfg(feature = "simd_opt")] -#[inline(always)] -fn rotate_right_16(vec: u64x4) -> u64x4 { - if cfg!(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm")) { - // 4 x vext (NEON) - rotate_right_vext(vec, 2) - } else if cfg!(target_feature = "ssse3") { - // 2 x pshufb (SSSE3) / vpshufb (AVX2) - transmute_shuffle!( - u8x32, - simd_shuffle32, - vec, - [ - 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 18, 19, 20, 21, 22, 23, 16, - 17, 26, 27, 28, 29, 30, 31, 24, 25 - ] - ) - } else if cfg!(target_feature = "sse2") { - // 2 x pshuflw+pshufhw (SSE2) - transmute_shuffle!( - u16x16, - simd_shuffle16, - vec, - [1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12] - ) - } else { - rotate_right_any(vec, 16) - } -} - -#[cfg(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm"))] -mod simd_asm_neon_arm { - use crate::simd::simdty::{u64x2, u64x4}; - - #[inline(always)] - fn vext_u64(vec: u64x2, b: u8) -> u64x2 { - unsafe { - let result: u64x2; - asm!("vext.8 ${0:e}, ${1:e}, ${1:e}, $2\nvext.8 ${0:f}, ${1:f}, ${1:f}, $2" - : "=w" (result) - : "w" (vec), "n" (b)); - result - } - } - - #[inline(always)] - pub fn rotate_right_vext(vec: u64x4, b: u8) -> u64x4 { - use crate::simd::simdint::{simd_shuffle2, simd_shuffle4}; - - unsafe { - let tmp0 = vext_u64(simd_shuffle2(vec, vec, [0, 1]), b); - let tmp1 = vext_u64(simd_shuffle2(vec, vec, [2, 3]), b); - simd_shuffle4(tmp0, tmp1, [0, 1, 2, 3]) - } - } -} - -#[cfg(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm"))] -use self::simd_asm_neon_arm::rotate_right_vext; - -#[cfg(feature = "simd_opt")] -#[cfg(not(all(feature = "simd_asm", target_feature = "neon", target_arch = "arm")))] -fn rotate_right_vext(_vec: u64x4, _n: u8) -> u64x4 { - unreachable!() -} diff --git a/core/crypto/blake2/src/simd/simdint.rs b/core/crypto/blake2/src/simd/simdint.rs deleted file mode 100644 index d876d553820..00000000000 --- a/core/crypto/blake2/src/simd/simdint.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -#![allow(dead_code)] - -#[cfg(feature = "simd")] -extern "platform-intrinsic" { - pub fn simd_add(x: T, y: T) -> T; - pub fn simd_shl(x: T, y: T) -> T; - pub fn simd_shr(x: T, y: T) -> T; - pub fn simd_xor(x: T, y: T) -> T; - - pub fn simd_shuffle2(v: T, w: T, idx: [u32; 2]) -> U; - pub fn simd_shuffle4(v: T, w: T, idx: [u32; 4]) -> U; - pub fn simd_shuffle8(v: T, w: T, idx: [u32; 8]) -> U; - pub fn simd_shuffle16(v: T, w: T, idx: [u32; 16]) -> U; - pub fn simd_shuffle32(v: T, w: T, idx: [u32; 32]) -> U; -} diff --git a/core/crypto/blake2/src/simd/simdop.rs b/core/crypto/blake2/src/simd/simdop.rs deleted file mode 100644 index 32190519f02..00000000000 --- a/core/crypto/blake2/src/simd/simdop.rs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2015 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -#[cfg(feature = "simd")] -use crate::simd::simdint; -use crate::simd::simdty::{u32x4, u64x4}; - -use core::ops::{Add, BitXor, Shl, Shr}; - -macro_rules! impl_ops { - ($vec:ident) => { - impl Add for $vec { - type Output = Self; - - #[cfg(feature = "simd")] - #[inline(always)] - fn add(self, rhs: Self) -> Self::Output { - unsafe { simdint::simd_add(self, rhs) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn add(self, rhs: Self) -> Self::Output { - $vec::new( - self.0.wrapping_add(rhs.0), - self.1.wrapping_add(rhs.1), - self.2.wrapping_add(rhs.2), - self.3.wrapping_add(rhs.3), - ) - } - } - - impl BitXor for $vec { - type Output = Self; - - #[cfg(feature = "simd")] - #[inline(always)] - fn bitxor(self, rhs: Self) -> Self::Output { - unsafe { simdint::simd_xor(self, rhs) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn bitxor(self, rhs: Self) -> Self::Output { - $vec::new(self.0 ^ rhs.0, self.1 ^ rhs.1, self.2 ^ rhs.2, self.3 ^ rhs.3) - } - } - - impl Shl<$vec> for $vec { - type Output = Self; - - #[cfg(feature = "simd")] - #[inline(always)] - fn shl(self, rhs: Self) -> Self::Output { - unsafe { simdint::simd_shl(self, rhs) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn shl(self, rhs: Self) -> Self::Output { - $vec::new(self.0 << rhs.0, self.1 << rhs.1, self.2 << rhs.2, self.3 << rhs.3) - } - } - - impl Shr<$vec> for $vec { - type Output = Self; - - #[cfg(feature = "simd")] - #[inline(always)] - fn shr(self, rhs: Self) -> Self::Output { - unsafe { simdint::simd_shr(self, rhs) } - } - - #[cfg(not(feature = "simd"))] - #[inline(always)] - fn shr(self, rhs: Self) -> Self::Output { - $vec::new(self.0 >> rhs.0, self.1 >> rhs.1, self.2 >> rhs.2, self.3 >> rhs.3) - } - } - }; -} - -impl_ops!(u32x4); -impl_ops!(u64x4); diff --git a/core/crypto/blake2/src/simd/simdty.rs b/core/crypto/blake2/src/simd/simdty.rs deleted file mode 100644 index 008b8b48c0d..00000000000 --- a/core/crypto/blake2/src/simd/simdty.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2016 blake2-rfc Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -#![allow(dead_code, non_camel_case_types)] - -use crate::as_bytes::Safe; - -#[cfg(feature = "simd")] -macro_rules! decl_simd { - ($($decl:item)*) => { - $( - #[derive(Clone, Copy, Debug)] - #[repr(simd)] - $decl - )* - } -} - -#[cfg(not(feature = "simd"))] -macro_rules! decl_simd { - ($($decl:item)*) => { - $( - #[derive(Clone, Copy, Debug)] - #[repr(C)] - $decl - )* - } -} - -decl_simd! { - pub struct Simd2(pub T, pub T); - pub struct Simd4(pub T, pub T, pub T, pub T); - pub struct Simd8(pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T); - pub struct Simd16(pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T); - pub struct Simd32(pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T, - pub T, pub T, pub T, pub T); -} - -pub type u64x2 = Simd2; - -pub type u32x4 = Simd4; -pub type u64x4 = Simd4; - -pub type u16x8 = Simd8; -pub type u32x8 = Simd8; - -pub type u8x16 = Simd16; -pub type u16x16 = Simd16; - -pub type u8x32 = Simd32; - -impl Simd4 { - #[inline(always)] - pub fn new(e0: T, e1: T, e2: T, e3: T) -> Simd4 { - Simd4(e0, e1, e2, e3) - } -} - -unsafe impl Safe for Simd2 {} -unsafe impl Safe for Simd4 {} -unsafe impl Safe for Simd8 {} -unsafe impl Safe for Simd16 {} -unsafe impl Safe for Simd32 {} diff --git a/core/crypto/blake2/tests/data/blake2b/fixed.blb b/core/crypto/blake2/tests/data/blake2b/fixed.blb deleted file mode 100644 index 39d4192093fb7ddaba517df1112e5f4e9f7de355..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmV;n07?I1Y;R&>c`*P$cxnRoLIGI=#>V}HB~sFIkuOI;;aEpuiiYAB_a9Ul(q0fT zukKh=6NzL*lTNTpkUD5v6iByK)o*Yb{+r^?D^zG@AaQkRV{0H{a&LETAZBlPAZm4O zaC0DUc4cxPbZBKDY+-tNAY^Z6K&Y+Mz1{tj9Nu@*K;AE&$&jg<)t$1^)N kbND0y&w8Td%O1^;DQ-U$%TyEi?RUO&1X~l4Ox)I~7-1PsX8-^I diff --git a/core/crypto/blake2/tests/data/blake2b/mac.blb b/core/crypto/blake2/tests/data/blake2b/mac.blb deleted file mode 100644 index 46522340d01322321a26c48b46accc028403a067..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66318 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 Yts>M;(jDDIyOCr)5_`-Ay+Gys4=tWpd;kCd diff --git a/core/crypto/blake2/tests/data/blake2b/variable.blb b/core/crypto/blake2/tests/data/blake2b/variable.blb deleted file mode 100644 index 5d150c0246f873d1bdf6136e857f96e14e3d513a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmV-50LuSjY;R&>c`*Pivfv*kIk)FZy0E)`i1({{=}V?5EIL9{e4>bBQdy-A-JE@T L9D9u}FNTDUhs78L diff --git a/core/crypto/blake2/tests/data/blake2s/mac.blb b/core/crypto/blake2/tests/data/blake2s/mac.blb deleted file mode 100644 index 2c5f3c67c5c9fdc25665e7412c3583691ebc7593..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49870 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 Date: Wed, 2 Jun 2021 22:25:47 +0700 Subject: [PATCH 062/134] Update documentation for blake2 --- runtime/near-vm-logic/src/logic.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index e9a185ab9b9..f09c196f364 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -973,16 +973,22 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } - /// Hashes the given value using BLAKE2b and returns it into `register_id`. + /// Hashes the given message using BLAKE2b and returns it into `register_id`. /// /// # Errors /// /// If `value_len + value_ptr` points outside the memory or the registers use more memory than /// the limit with `MemoryAccessViolation`. /// + /// If the message is too long and overflows, an error is returned with + /// `Blake2HashDataOverflow`. + /// /// # Cost /// - /// `base + write_register_base + write_register_byte * num_bytes + blake2b_base + blake2b_byte * num_bytes` + /// Where `message_blocks` is `(message_len / 128 + 1)`. + /// + /// `base + write_register_base + write_register_byte * num_bytes + + /// message_blocks * blake2b_block + rounds * message_blocks` #[cfg(feature = "protocol_feature_evm")] pub fn blake2b( &mut self, @@ -1030,6 +1036,22 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, res.as_slice().to_vec()) } + /// Hashes the given message using BLAKE2s and returns it into `register_id`. + /// + /// # Errors + /// + /// If `value_len + value_ptr` points outside the memory or the registers use more memory than + /// the limit with `MemoryAccessViolation`. + /// + /// If the message is too long and overflows, an error is returned with + /// `Blake2HashDataOverflow`. + /// + /// # Cost + /// + /// Where `message_blocks` is `(message_len / 128 + 1)`. + /// + /// `base + write_register_base + write_register_byte * num_bytes + + /// message_blocks * blake2s_block + rounds * message_blocks` #[cfg(feature = "protocol_feature_evm")] pub fn blake2s( &mut self, From 76e2a2e0fa7b77fea3fcfd69f7e665cac3b39241 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 2 Jun 2021 22:25:59 +0700 Subject: [PATCH 063/134] Pin comment for blake2 lib --- Cargo.lock | 2 +- core/crypto/Cargo.toml | 2 +- runtime/near-vm-logic/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e67301d78b6..18fe95663ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3019,7 +3019,7 @@ dependencies = [ [[package]] name = "near-blake2" version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git#0a21d378670234e943d7efcc79e0b85629c99f57" +source = "git+https://github.com/near/near-blake2.git?rev=5e9890f#5e9890f4906e930e28fe7d6479fc5fa53122d1f0" dependencies = [ "crypto-mac 0.8.0", "digest 0.9.0", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index e27f479f6f0..2484d3891f3 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git" } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "5e9890f" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index d5a06feeeb6..4363d06e0d8 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", optional = true } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "5e9890f", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" From ec72a48c3f1e22e93dc30fc3401f990aa48d10c9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 4 Jun 2021 11:57:56 +0700 Subject: [PATCH 064/134] Fix with_state --- Cargo.lock | 2 +- core/crypto/Cargo.toml | 2 +- runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/logic.rs | 20 ++++---------------- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18fe95663ba..f05992b4f48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3019,7 +3019,7 @@ dependencies = [ [[package]] name = "near-blake2" version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git?rev=5e9890f#5e9890f4906e930e28fe7d6479fc5fa53122d1f0" +source = "git+https://github.com/near/near-blake2.git?rev=650b67#650b67912f4bfc08517ed3a3df453e7cf22fb1ef" dependencies = [ "crypto-mac 0.8.0", "digest 0.9.0", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index 2484d3891f3..ede5331babd 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "5e9890f" } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "650b67" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 4363d06e0d8..9a0ad74b7c6 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "5e9890f", optional = true } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "650b67", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index f09c196f364..eb7349e8045 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1002,7 +1002,7 @@ impl<'a> VMLogic<'a> { f1: u64, register_id: u64, ) -> Result<()> { - use blake2::{Error as Blake2Error, VarBlake2b}; + use blake2::VarBlake2b; use std::convert::TryFrom; if state_len != 8 { @@ -1020,13 +1020,7 @@ impl<'a> VMLogic<'a> { .expect("vec bytes conversion"); let m = self.memory_get_vec(message_ptr, message_len)?; - let mut hasher = match VarBlake2b::with_state(rounds, state, t) { - Ok(h) => h, - Err(Blake2Error::TooManyRounds { max, actual }) => { - return Err(HostError::Blake2TooManyRounds { max, actual }.into()) - } - _ => unreachable!(), - }; + let mut hasher = VarBlake2b::with_state(rounds, state, t); if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); } @@ -1066,7 +1060,7 @@ impl<'a> VMLogic<'a> { f1: u32, register_id: u64, ) -> Result<()> { - use blake2::{Error as Blake2Error, VarBlake2s}; + use blake2::VarBlake2b; use std::convert::TryFrom; if state_len != 8 { @@ -1094,13 +1088,7 @@ impl<'a> VMLogic<'a> { t_buf[0..4].copy_from_slice(&t0.to_le_bytes()); t_buf[4..8].copy_from_slice(&t1.to_le_bytes()); let t = u64::from_le_bytes(t_buf); - let mut hasher = match VarBlake2s::with_state(rounds, state, t) { - Ok(h) => h, - Err(Blake2Error::TooManyRounds { max, actual }) => { - return Err(HostError::Blake2TooManyRounds { max, actual }.into()) - } - _ => unreachable!(), - }; + let mut hasher = VarBlake2s::with_state(rounds, state, t); if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); } From e395b1ca19aee7e60542d57ddeb5691aaca3d47d Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 11 Jun 2021 12:50:38 +0700 Subject: [PATCH 065/134] Return a bool for ecrecover, not abort --- runtime/near-vm-errors/src/lib.rs | 2 -- runtime/near-vm-logic/src/logic.rs | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 1f9c3694e34..7efe8624f47 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -206,8 +206,6 @@ pub enum HostError { ContractSizeExceeded { size: u64, limit: u64 }, /// The host function was deprecated. Deprecated { method_name: String }, - /// Invalid ECDSA signature. - InvalidECDSASignature, /// The length of the state is not 64. #[cfg(feature = "protocol_feature_evm")] Blake2InvalidStateLength { length: u64 }, diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index eb7349e8045..f4f63da6a96 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1111,7 +1111,7 @@ impl<'a> VMLogic<'a> { /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` #[cfg(feature = "protocol_feature_evm")] - pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result<()> { + pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result { use sha3::Digest; self.gas_counter.pay_base(ecrecover_base)?; @@ -1131,10 +1131,11 @@ impl<'a> VMLogic<'a> { let result = sha3::Keccak256::digest(&public_key.serialize()[1..]); let mut address = [0u8; 20]; address.copy_from_slice(&result[12..]); - return self.internal_write_register(register_id, address.to_vec()); + self.internal_write_register(register_id, address.to_vec()) + return Ok(true); } } - return Err(HostError::InvalidECDSASignature.into()); + return Ok(false); } /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. From fe76336dc7c125fb713b08ccbc0c01a4bfb1955a Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 11 Jun 2021 12:57:04 +0700 Subject: [PATCH 066/134] Fix VarBlake2b -> VarBlake2s --- chain/jsonrpc/res/rpc_errors_schema.json | 5 ----- runtime/near-vm-errors/src/lib.rs | 1 - runtime/near-vm-logic/src/logic.rs | 6 +++--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index c7dc48937b3..e5ac6cec66e 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -76,11 +76,6 @@ "method_name": "" } }, - "InvalidECDSASignature": { - "name": "InvalidECDSASignature", - "subtypes": [], - "props": {} - }, "Deserialization": { "name": "Deserialization", "subtypes": [], diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 7efe8624f47..5f991158c72 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -503,7 +503,6 @@ impl std::fmt::Display for HostError { ReturnedValueLengthExceeded { length, limit } => write!(f, "The length of a returned value {} exceeds the limit {}", length, limit), ContractSizeExceeded { size, limit } => write!(f, "The size of a contract code in DeployContract action {} exceeds the limit {}", size, limit), Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), - InvalidECDSASignature => write!(f, "Invalid ECDSA signature"), #[cfg(feature = "protocol_feature_evm")] Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), #[cfg(feature = "protocol_feature_evm")] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index f4f63da6a96..ed69ca367ef 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1060,7 +1060,7 @@ impl<'a> VMLogic<'a> { f1: u32, register_id: u64, ) -> Result<()> { - use blake2::VarBlake2b; + use blake2::VarBlake2s; use std::convert::TryFrom; if state_len != 8 { @@ -1100,12 +1100,12 @@ impl<'a> VMLogic<'a> { /// Recovers an ECDSA signer address and returns it into `register_id`. /// + /// Returns a bool indicating success or failure. + /// /// # Errors /// /// * If `hash_ptr`, `r_ptr`, or `s_ptr` point outside the memory or the registers use more /// memory than the limit, then returns `MemoryAccessViolation`. - /// * If `v` is invalid (not 27 or 28), then returns `InvalidECDSASignature`. - /// * If the ECDSA recovery fails for any reason, then returns `InvalidECDSASignature`. /// /// # Cost /// From bda2e42b57fb1ae4ac3ec384f1d2400b46ff9a01 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 11 Jun 2021 13:58:07 +0700 Subject: [PATCH 067/134] Add errors to RPC errors schema --- chain/jsonrpc/res/rpc_errors_schema.json | 25 +++++++++++++++++++++++- runtime/near-vm-logic/src/logic.rs | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index e5ac6cec66e..56274f1e00e 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -15,6 +15,26 @@ "subtypes": [], "props": {} }, + "Blake2HashDataOverflow": { + "name": "Blake2HashDataOverflow", + "subtypes": [], + "props": {} + }, + "Blake2InvalidStateLength": { + "name": "Blake2InvalidStateLength", + "subtypes": [], + "props": { + "length": "" + } + }, + "Blake2TooManyRounds": { + "name": "Blake2TooManyRounds", + "subtypes": [], + "props": { + "max": "", + "actual": "" + } + }, "BreakpointTrap": { "name": "BreakpointTrap", "subtypes": [], @@ -163,7 +183,10 @@ "NumberInputDataDependenciesExceeded", "ReturnedValueLengthExceeded", "ContractSizeExceeded", - "Deprecated" + "Deprecated", + "Blake2InvalidStateLength", + "Blake2HashDataOverflow", + "Blake2TooManyRounds" ], "props": {} }, diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index ed69ca367ef..f9bca106f29 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1131,7 +1131,7 @@ impl<'a> VMLogic<'a> { let result = sha3::Keccak256::digest(&public_key.serialize()[1..]); let mut address = [0u8; 20]; address.copy_from_slice(&result[12..]); - self.internal_write_register(register_id, address.to_vec()) + self.internal_write_register(register_id, address.to_vec())?; return Ok(true); } } From cf61d158308df4c3d3762c858928b0f36f8258b9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 11 Jun 2021 20:14:08 +0700 Subject: [PATCH 068/134] Add bool return to wrapped imports --- runtime/near-vm-logic/src/logic.rs | 6 +++--- runtime/near-vm-runner/src/imports.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index f9bca106f29..d0eb5d5c51a 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1111,7 +1111,7 @@ impl<'a> VMLogic<'a> { /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` #[cfg(feature = "protocol_feature_evm")] - pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result { + pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result { use sha3::Digest; self.gas_counter.pay_base(ecrecover_base)?; @@ -1132,10 +1132,10 @@ impl<'a> VMLogic<'a> { let mut address = [0u8; 20]; address.copy_from_slice(&result[12..]); self.internal_write_register(register_id, address.to_vec())?; - return Ok(true); + return Ok(true as u64); } } - return Ok(false); + return Ok(false as u64); } /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index eb3c39781ff..d69ca141118 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -224,7 +224,7 @@ wrapped_imports! { #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] blake2b<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u32, t1: u32, f0: u32, f1: u32, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### From 23cd417fc7db039d0b8ffcafd9ff2098c0762752 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 14 Jun 2021 23:31:49 +0700 Subject: [PATCH 069/134] Take t0 and t1 for blake2b --- runtime/near-vm-logic/src/logic.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index d0eb5d5c51a..5605573167e 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -997,7 +997,8 @@ impl<'a> VMLogic<'a> { state_ptr: u64, message_len: u64, message_ptr: u64, - t: u64, + t0: u32, + t1: u32, f0: u64, f1: u64, register_id: u64, @@ -1020,6 +1021,10 @@ impl<'a> VMLogic<'a> { .expect("vec bytes conversion"); let m = self.memory_get_vec(message_ptr, message_len)?; + let mut t_buf = [0u8; 8]; + t_buf[0..4].copy_from_slice(&t0.to_le_bytes()); + t_buf[4..8].copy_from_slice(&t1.to_le_bytes()); + let t = u64::from_le_bytes(t_buf); let mut hasher = VarBlake2b::with_state(rounds, state, t); if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); @@ -1054,8 +1059,7 @@ impl<'a> VMLogic<'a> { state_ptr: u64, message_len: u64, message_ptr: u64, - t0: u32, - t1: u32, + t: u64, f0: u32, f1: u32, register_id: u64, @@ -1084,10 +1088,6 @@ impl<'a> VMLogic<'a> { }; let m = self.memory_get_vec(message_ptr, message_len)?; - let mut t_buf = [0u8; 8]; - t_buf[0..4].copy_from_slice(&t0.to_le_bytes()); - t_buf[4..8].copy_from_slice(&t1.to_le_bytes()); - let t = u64::from_le_bytes(t_buf); let mut hasher = VarBlake2s::with_state(rounds, state, t); if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); From 48fb8dd82c039a0c0eb05640dcc89a9a01255882 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 15 Jun 2021 00:08:47 +0700 Subject: [PATCH 070/134] Charge ripemd160 by blocks, not bytes --- core/primitives-core/src/config.rs | 14 +++++++------- runtime/near-vm-logic/src/logic.rs | 17 +++++++++++------ runtime/near-vm-logic/tests/test_miscs.rs | 14 +++++++------- runtime/runtime-params-estimator/src/cases.rs | 2 +- .../src/ext_costs_generator.rs | 2 +- .../test-contract/src/lib.rs | 4 ++-- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 40580af283f..d7910ded23c 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -226,9 +226,9 @@ pub struct ExtCostsConfig { /// Cost of getting ripemd160 base #[cfg(feature = "protocol_feature_evm")] pub ripemd160_base: Gas, - /// Cost of getting ripemd160 per byte + /// Cost of getting ripemd160 per message block #[cfg(feature = "protocol_feature_evm")] - pub ripemd160_byte: Gas, + pub ripemd160_block: Gas, /// Cost of getting blake2b base #[cfg(feature = "protocol_feature_evm")] @@ -386,7 +386,7 @@ impl Default for ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] ripemd160_base: SAFETY_MULTIPLIER * 15136567500, // 10 x sha256_base #[cfg(feature = "protocol_feature_evm")] - ripemd160_byte: SAFETY_MULTIPLIER * 80391170, // 10 x sha256_byte + ripemd160_block: SAFETY_MULTIPLIER * 80391170 * 8, // 10 x sha256_byte x 8 bytes #[cfg(feature = "protocol_feature_evm")] blake2b_base: SAFETY_MULTIPLIER * 88256037, // same as base. #[cfg(feature = "protocol_feature_evm")] @@ -474,7 +474,7 @@ impl ExtCostsConfig { #[cfg(feature = "protocol_feature_evm")] ripemd160_base: 0, #[cfg(feature = "protocol_feature_evm")] - ripemd160_byte: 0, + ripemd160_block: 0, #[cfg(feature = "protocol_feature_evm")] blake2b_base: 0, #[cfg(feature = "protocol_feature_evm")] @@ -563,7 +563,7 @@ pub enum ExtCosts { #[cfg(feature = "protocol_feature_evm")] ripemd160_base, #[cfg(feature = "protocol_feature_evm")] - ripemd160_byte, + ripemd160_block, #[cfg(feature = "protocol_feature_evm")] blake2b_base, #[cfg(feature = "protocol_feature_evm")] @@ -705,7 +705,7 @@ impl ExtCosts { #[cfg(feature = "protocol_feature_evm")] ripemd160_base => config.ripemd160_base, #[cfg(feature = "protocol_feature_evm")] - ripemd160_byte => config.ripemd160_byte, + ripemd160_block => config.ripemd160_block, #[cfg(feature = "protocol_feature_evm")] blake2b_base => config.blake2b_base, #[cfg(feature = "protocol_feature_evm")] @@ -795,7 +795,7 @@ impl ExtCosts { "keccak512_base", "keccak512_byte", "ripemd160_base", - "ripemd160_byte", + "ripemd160_block", "blake2b_base", "blake2b_byte", "ecrecover_base", diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 5605573167e..1c748facc37 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -960,12 +960,17 @@ impl<'a> VMLogic<'a> { /// /// # Cost /// - /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_byte * num_bytes` + /// Where `message_blocks` is `max(message_len / 8, 1)`. + /// + /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks` #[cfg(feature = "protocol_feature_evm")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - self.gas_counter.pay_per(ripemd160_byte, value.len() as u64)?; + + let message_blocks = std::cmp::max(value_len / 8, 1); + + self.gas_counter.pay_per(ripemd160_block, message_blocks)?; use ripemd160::Digest; @@ -985,7 +990,7 @@ impl<'a> VMLogic<'a> { /// /// # Cost /// - /// Where `message_blocks` is `(message_len / 128 + 1)`. + /// Where `message_blocks` is `max(message_len / 128, 1)`. /// /// `base + write_register_base + write_register_byte * num_bytes + /// message_blocks * blake2b_block + rounds * message_blocks` @@ -1011,7 +1016,7 @@ impl<'a> VMLogic<'a> { } // Change to per block for gas. - let message_blocks = message_len / 128 + 1; + let message_blocks = std::cmp::max(message_len / 128, 1); self.gas_counter.pay_base(blake2b_base)?; self.gas_counter.pay_per(blake2b_block, message_blocks)?; @@ -1047,7 +1052,7 @@ impl<'a> VMLogic<'a> { /// /// # Cost /// - /// Where `message_blocks` is `(message_len / 128 + 1)`. + /// Where `message_blocks` is `max(message_len / 128, 1)`. /// /// `base + write_register_base + write_register_byte * num_bytes + /// message_blocks * blake2s_block + rounds * message_blocks` @@ -1072,7 +1077,7 @@ impl<'a> VMLogic<'a> { } // Change to per block for gas. - let message_blocks = message_len / 128 + 1; + let message_blocks = std::cmp::max(message_len / 64, 1); self.gas_counter.pay_base(blake2b_base)?; self.gas_counter.pay_per(blake2b_block, message_blocks)?; diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 72a92f02b6f..978855bf4d1 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -556,7 +556,7 @@ fn test_ripemd160() { ExtCosts::write_register_base: 1, ExtCosts::write_register_byte: 20, ExtCosts::ripemd160_base: 1, - ExtCosts::ripemd160_byte: len, + ExtCosts::ripemd160_block: 1, }); } @@ -578,7 +578,8 @@ fn test_blake2b() { 0x5be0cd19137e2179, ]; let m = b"abc"; - let t = 0; + let t0 = 0; + let t1 = 0; let f0 = !0; let f1 = 0; @@ -589,7 +590,8 @@ fn test_blake2b() { h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, - t, + t0, + t1, f0, f1, 0, @@ -638,8 +640,7 @@ fn test_blake2s() { 0x5be0cd19, ]; let m: &[u8; 3] = b"abc"; - let t0: u32 = 0; - let t1: u32 = 0; + let t: u64 = 0; let f0: u32 = !0; let f1: u32 = 0; @@ -650,8 +651,7 @@ fn test_blake2s() { h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, - t0, - t1, + t, f0, f1, 0, diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index d476316b13b..e0238594a1c 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -790,7 +790,7 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts #[cfg(feature = "protocol_feature_evm")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), #[cfg(feature = "protocol_feature_evm")] - ripemd160_byte: measured_to_gas(metric, &measured, ripemd160_byte), + ripemd160_block: measured_to_gas(metric, &measured, ripemd160_block), #[cfg(feature = "protocol_feature_evm")] blake2b_base: measured_to_gas(metric, &measured, blake2b_base), #[cfg(feature = "protocol_feature_evm")] diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index d20faae6229..880148a6eab 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -68,7 +68,7 @@ impl ExtCostsGenerator { #[cfg(feature = "protocol_feature_evm")] { self.extract(ripemd160_10b_10k, ripemd160_base); - self.extract(ripemd160_10kib_10k, ripemd160_byte); + self.extract(ripemd160_10kib_10k, ripemd160_block); self.extract(blake2b_128b_0r_10k, blake2b_base); self.extract(blake2b_128kb_0r_10k, blake2b_block); diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index bbb00f2155f..d77fdf07878 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -432,7 +432,7 @@ pub unsafe fn keccak512_10kib_10k() { } } -// Function to measure `ripemd160_base` and `ripemd160_byte`. Also measures `base`, `write_register_base`, +// Function to measure `ripemd160_base` and `ripemd160_block`. Also measures `base`, `write_register_base`, // and `write_register_byte`. However `ripemd160` computation is more expensive than register writing // so we are okay overcharging it. // Compute ripemd160 on 10b 10k times. @@ -444,7 +444,7 @@ pub unsafe fn ripemd160_10b_10k() { ripemd160(buffer.len() as u64, buffer.as_ptr() as *const u64 as u64, 0); } } -// Function to measure `ripemd160_base` and `ripemd160_byte`. Also measures `base`, `write_register_base`, +// Function to measure `ripemd160_base` and `ripemd160_block`. Also measures `base`, `write_register_base`, // and `write_register_byte`. However `ripemd160` computation is more expensive than register writing // so we are okay overcharging it. // Compute ripemd160 on 10kib 10k times. From f9853796700ab43303be895fb1eb985598402cdc Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 16 Jun 2021 01:06:56 +0700 Subject: [PATCH 071/134] Correctly send both t0 and t1 to blake2 --- Cargo.lock | 2 +- core/crypto/Cargo.toml | 2 +- runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/logic.rs | 14 ++++++-------- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25f822ba620..24dfc1065bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3019,7 +3019,7 @@ dependencies = [ [[package]] name = "near-blake2" version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git?rev=650b67#650b67912f4bfc08517ed3a3df453e7cf22fb1ef" +source = "git+https://github.com/near/near-blake2.git?rev=4e2427#4e24273b0feb24b835f00a2606fe1287bec3b557" dependencies = [ "crypto-mac 0.8.0", "digest 0.9.0", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index ede5331babd..51ebd67cc13 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "650b67" } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "4e2427" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 9a0ad74b7c6..fc1c88f3b71 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "650b67", optional = true } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "4e2427", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 1c748facc37..6bf50325c27 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1002,8 +1002,8 @@ impl<'a> VMLogic<'a> { state_ptr: u64, message_len: u64, message_ptr: u64, - t0: u32, - t1: u32, + t0: u64, + t1: u64, f0: u64, f1: u64, register_id: u64, @@ -1026,11 +1026,7 @@ impl<'a> VMLogic<'a> { .expect("vec bytes conversion"); let m = self.memory_get_vec(message_ptr, message_len)?; - let mut t_buf = [0u8; 8]; - t_buf[0..4].copy_from_slice(&t0.to_le_bytes()); - t_buf[4..8].copy_from_slice(&t1.to_le_bytes()); - let t = u64::from_le_bytes(t_buf); - let mut hasher = VarBlake2b::with_state(rounds, state, t); + let mut hasher = VarBlake2b::with_state(rounds, state, [t0, t1]); if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); } @@ -1093,7 +1089,9 @@ impl<'a> VMLogic<'a> { }; let m = self.memory_get_vec(message_ptr, message_len)?; - let mut hasher = VarBlake2s::with_state(rounds, state, t); + let t0 = t as u32; + let t1 = (t >> 32) as u32; + let mut hasher = VarBlake2s::with_state(rounds, state, [t0, t1]); if hasher.update_inner(&m).is_err() { return Err(HostError::Blake2HashDataOverflow.into()); } From 93240c6f9509f2afc99b97c0da9242d541efe356 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 16 Jun 2021 01:09:42 +0700 Subject: [PATCH 072/134] Remove too many rounds error --- chain/jsonrpc/res/rpc_errors_schema.json | 11 +---------- runtime/near-vm-errors/src/lib.rs | 5 ----- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index 56274f1e00e..60727e093fa 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -27,14 +27,6 @@ "length": "" } }, - "Blake2TooManyRounds": { - "name": "Blake2TooManyRounds", - "subtypes": [], - "props": { - "max": "", - "actual": "" - } - }, "BreakpointTrap": { "name": "BreakpointTrap", "subtypes": [], @@ -185,8 +177,7 @@ "ContractSizeExceeded", "Deprecated", "Blake2InvalidStateLength", - "Blake2HashDataOverflow", - "Blake2TooManyRounds" + "Blake2HashDataOverflow" ], "props": {} }, diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 5f991158c72..f75776eb0f5 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -212,9 +212,6 @@ pub enum HostError { /// Blake2 hash data overflow error. #[cfg(feature = "protocol_feature_evm")] Blake2HashDataOverflow, - /// Too many blake2 rounds. - #[cfg(feature = "protocol_feature_evm")] - Blake2TooManyRounds { max: u32, actual: u32 }, /// Deserialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg: String }, @@ -507,8 +504,6 @@ impl std::fmt::Display for HostError { Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), #[cfg(feature = "protocol_feature_evm")] Blake2HashDataOverflow => write!(f, "Blake2 hash data length overflow."), - #[cfg(feature = "protocol_feature_evm")] - Blake2TooManyRounds { max, actual } => write!(f, "Too many blake2 rounds. Expected fewer than {}, got {}.", max, actual), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] From 764f4a101322c615467e2c55124306c497fb2202 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 16 Jun 2021 01:16:52 +0700 Subject: [PATCH 073/134] Remove any near-blake2 errors --- Cargo.lock | 2 +- core/crypto/Cargo.toml | 2 +- runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/logic.rs | 8 ++------ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24dfc1065bf..ec196d13b4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3019,7 +3019,7 @@ dependencies = [ [[package]] name = "near-blake2" version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git?rev=4e2427#4e24273b0feb24b835f00a2606fe1287bec3b557" +source = "git+https://github.com/near/near-blake2.git?rev=29a15a#29a15a1ffa3bfb7baa54318c89ee6cfebaf4d590" dependencies = [ "crypto-mac 0.8.0", "digest 0.9.0", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index 51ebd67cc13..d34891a713b 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "4e2427" } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "29a15a" } borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index fc1c88f3b71..22253f32958 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,7 +14,7 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "4e2427", optional = true } +blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "29a15a", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 6bf50325c27..593834eddad 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1027,9 +1027,7 @@ impl<'a> VMLogic<'a> { let m = self.memory_get_vec(message_ptr, message_len)?; let mut hasher = VarBlake2b::with_state(rounds, state, [t0, t1]); - if hasher.update_inner(&m).is_err() { - return Err(HostError::Blake2HashDataOverflow.into()); - } + hasher.update_inner(&m); hasher.compress(f0, f1); let res = hasher.output(); @@ -1092,9 +1090,7 @@ impl<'a> VMLogic<'a> { let t0 = t as u32; let t1 = (t >> 32) as u32; let mut hasher = VarBlake2s::with_state(rounds, state, [t0, t1]); - if hasher.update_inner(&m).is_err() { - return Err(HostError::Blake2HashDataOverflow.into()); - } + hasher.update_inner(&m); hasher.compress(f0, f1); let res = hasher.output(); From 8be6dac66cd77232fe74c8e3ed9c7d24d56a94f9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 16 Jun 2021 01:20:18 +0700 Subject: [PATCH 074/134] Remove hash data overflow error --- chain/jsonrpc/res/rpc_errors_schema.json | 8 +------- runtime/near-vm-errors/src/lib.rs | 5 ----- runtime/near-vm-logic/src/logic.rs | 8 +------- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index 60727e093fa..101d9d01f4f 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -15,11 +15,6 @@ "subtypes": [], "props": {} }, - "Blake2HashDataOverflow": { - "name": "Blake2HashDataOverflow", - "subtypes": [], - "props": {} - }, "Blake2InvalidStateLength": { "name": "Blake2InvalidStateLength", "subtypes": [], @@ -176,8 +171,7 @@ "ReturnedValueLengthExceeded", "ContractSizeExceeded", "Deprecated", - "Blake2InvalidStateLength", - "Blake2HashDataOverflow" + "Blake2InvalidStateLength" ], "props": {} }, diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index f75776eb0f5..3ffca0805a5 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -209,9 +209,6 @@ pub enum HostError { /// The length of the state is not 64. #[cfg(feature = "protocol_feature_evm")] Blake2InvalidStateLength { length: u64 }, - /// Blake2 hash data overflow error. - #[cfg(feature = "protocol_feature_evm")] - Blake2HashDataOverflow, /// Deserialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg: String }, @@ -502,8 +499,6 @@ impl std::fmt::Display for HostError { Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), #[cfg(feature = "protocol_feature_evm")] Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), - #[cfg(feature = "protocol_feature_evm")] - Blake2HashDataOverflow => write!(f, "Blake2 hash data length overflow."), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 593834eddad..387cf5574ab 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -985,9 +985,6 @@ impl<'a> VMLogic<'a> { /// If `value_len + value_ptr` points outside the memory or the registers use more memory than /// the limit with `MemoryAccessViolation`. /// - /// If the message is too long and overflows, an error is returned with - /// `Blake2HashDataOverflow`. - /// /// # Cost /// /// Where `message_blocks` is `max(message_len / 128, 1)`. @@ -1041,9 +1038,6 @@ impl<'a> VMLogic<'a> { /// If `value_len + value_ptr` points outside the memory or the registers use more memory than /// the limit with `MemoryAccessViolation`. /// - /// If the message is too long and overflows, an error is returned with - /// `Blake2HashDataOverflow`. - /// /// # Cost /// /// Where `message_blocks` is `max(message_len / 128, 1)`. @@ -1081,7 +1075,7 @@ impl<'a> VMLogic<'a> { let mut buf = [0u32; 8]; let values = self.memory_get_vec_u64(state_ptr, 8)?; for (x, y) in buf.iter_mut().zip(values.into_iter()) { - *x = ::try_from(y).map_err(|_| HostError::Blake2HashDataOverflow)?; + *x = ::try_from(y).map_err(|_| HostError::IntegerOverflow)?; } buf }; From b58d765acc0632b0438b944d89646a8c527adfa1 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Wed, 16 Jun 2021 01:22:30 +0700 Subject: [PATCH 075/134] Rename Blake2InvalidStateLength -> Blake2StateLengthExceeded --- chain/jsonrpc/res/rpc_errors_schema.json | 6 +++--- runtime/near-vm-errors/src/lib.rs | 4 ++-- runtime/near-vm-logic/src/logic.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index 101d9d01f4f..e4d37938f6b 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -15,8 +15,8 @@ "subtypes": [], "props": {} }, - "Blake2InvalidStateLength": { - "name": "Blake2InvalidStateLength", + "Blake2StateLengthExceeded": { + "name": "Blake2StateLengthExceeded", "subtypes": [], "props": { "length": "" @@ -171,7 +171,7 @@ "ReturnedValueLengthExceeded", "ContractSizeExceeded", "Deprecated", - "Blake2InvalidStateLength" + "Blake2StateLengthExceeded" ], "props": {} }, diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 3ffca0805a5..f58e0ba536d 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -208,7 +208,7 @@ pub enum HostError { Deprecated { method_name: String }, /// The length of the state is not 64. #[cfg(feature = "protocol_feature_evm")] - Blake2InvalidStateLength { length: u64 }, + Blake2StateLengthExceeded { length: u64 }, /// Deserialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg: String }, @@ -498,7 +498,7 @@ impl std::fmt::Display for HostError { ContractSizeExceeded { size, limit } => write!(f, "The size of a contract code in DeployContract action {} exceeds the limit {}", size, limit), Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), #[cfg(feature = "protocol_feature_evm")] - Blake2InvalidStateLength { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), + Blake2StateLengthExceeded { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 387cf5574ab..bc12a719df9 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1009,7 +1009,7 @@ impl<'a> VMLogic<'a> { use std::convert::TryFrom; if state_len != 8 { - return Err(HostError::Blake2InvalidStateLength { length: state_len }.into()); + return Err(HostError::Blake2StateLengthExceeded { length: state_len }.into()); } // Change to per block for gas. @@ -1061,7 +1061,7 @@ impl<'a> VMLogic<'a> { use std::convert::TryFrom; if state_len != 8 { - return Err(HostError::Blake2InvalidStateLength { length: state_len }.into()); + return Err(HostError::Blake2StateLengthExceeded { length: state_len }.into()); } // Change to per block for gas. From 1410e6d68b871524f8d128b73ef1d7a0b4706bff Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 11:25:02 +0700 Subject: [PATCH 076/134] Small ecrecover clarifications --- runtime/near-vm-logic/src/logic.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index bc12a719df9..b0ae3df838c 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1093,7 +1093,7 @@ impl<'a> VMLogic<'a> { /// Recovers an ECDSA signer address and returns it into `register_id`. /// - /// Returns a bool indicating success or failure. + /// Returns a bool indicating success or failure as a `u64`. /// /// # Errors /// @@ -1108,15 +1108,15 @@ impl<'a> VMLogic<'a> { use sha3::Digest; self.gas_counter.pay_base(ecrecover_base)?; - let signature = self.memory_get_vec(sig_ptr, 65)?; - let hash = self.memory_get_vec(hash_ptr, 32)?; + let r = self.memory_get_vec(hash_ptr, 32)?; + let s = self.memory_get_vec(sig_ptr, 65)?; + let v = s[64]; - let hash = secp256k1::Message::parse_slice(&hash).unwrap(); - let v = signature[64]; + let hash = secp256k1::Message::parse_slice(&r).unwrap(); let signature = secp256k1::Signature::parse_slice(&signature[0..64]).unwrap(); let bit = match v { - 0..=26 => v, - _ => v - 27, + 27 | 28 => v - 27, + _ => return Ok(false as u64), }; if let Ok(recovery_id) = secp256k1::RecoveryId::parse(bit) { if let Ok(public_key) = secp256k1::recover(&hash, &signature, &recovery_id) { From 0210eab6bf7d87a4a093774d9c710c23f8c73611 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 11:37:10 +0700 Subject: [PATCH 077/134] Return public key in ecrecover --- runtime/near-vm-logic/src/logic.rs | 8 ++------ runtime/near-vm-logic/tests/test_miscs.rs | 17 ++++++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index b0ae3df838c..ff52bb024fc 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1105,7 +1105,6 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` #[cfg(feature = "protocol_feature_evm")] pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result { - use sha3::Digest; self.gas_counter.pay_base(ecrecover_base)?; let r = self.memory_get_vec(hash_ptr, 32)?; @@ -1113,7 +1112,7 @@ impl<'a> VMLogic<'a> { let v = s[64]; let hash = secp256k1::Message::parse_slice(&r).unwrap(); - let signature = secp256k1::Signature::parse_slice(&signature[0..64]).unwrap(); + let signature = secp256k1::Signature::parse_slice(&s[0..64]).unwrap(); let bit = match v { 27 | 28 => v - 27, _ => return Ok(false as u64), @@ -1121,10 +1120,7 @@ impl<'a> VMLogic<'a> { if let Ok(recovery_id) = secp256k1::RecoveryId::parse(bit) { if let Ok(public_key) = secp256k1::recover(&hash, &signature, &recovery_id) { // recover returns a 65-byte key, but addresses come from the raw 64-byte key - let result = sha3::Keccak256::digest(&public_key.serialize()[1..]); - let mut address = [0u8; 20]; - address.copy_from_slice(&result[12..]); - self.internal_write_register(register_id, address.to_vec())?; + self.internal_write_register(register_id, public_key.serialize().to_vec())?; return Ok(true as u64); } } diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 978855bf4d1..0c143b7cfce 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -701,14 +701,17 @@ fn test_ecrecover() { 0xbb, 0x01, 0xc1, 0xd8, 0x1d, 0x10, 0xe6, 0x9f, 0x03, 0x84, 0xe6, 0x75, 0xc3, 0x2b, 0x39, 0x64, 0x3b, 0xe8, 0x92, 0x1b, ]; - let signer: [u8; 20] = [ - 0x2c, 0xc1, 0x16, 0x6f, 0x62, 0x12, 0x62, 0x8a, 0x0d, 0xee, 0xf2, 0xb3, 0x3b, 0xef, 0xb2, - 0x18, 0x7d, 0x35, 0xb8, 0x6c, + let signer: [u8; 65] = [ + 0x04, 0xb3, 0x68, 0x70, 0xea, 0xab, 0x31, 0xcb, 0xeb, 0x1a, 0x5c, 0x07, 0x46, 0x7b, 0x42, + 0x97, 0x40, 0x7c, 0x62, 0x11, 0x7a, 0x31, 0x15, 0x47, 0xc4, 0x30, 0x5e, 0x14, 0x71, 0x52, + 0x1b, 0x53, 0x01, 0xc2, 0x59, 0x9d, 0x4e, 0xad, 0xdf, 0xd3, 0x84, 0x9d, 0xf9, 0xd5, 0x99, + 0x38, 0xfd, 0x8f, 0x16, 0x56, 0x47, 0x77, 0x32, 0x66, 0x80, 0x66, 0xff, 0xa1, 0x2e, 0xb3, + 0x47, 0xea, 0xb4, 0x7b, 0x9c, ]; logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0).unwrap(); - let result = &vec![0u8; 20]; + let result = &vec![0u8; 65]; logic.read_register(0, result.as_ptr() as _).expect("OK"); assert_eq!(result.to_vec(), signer); @@ -717,11 +720,11 @@ fn test_ecrecover() { ExtCosts::read_memory_base: 2, ExtCosts::read_memory_byte: 97, ExtCosts::write_memory_base: 1, - ExtCosts::write_memory_byte: 20, + ExtCosts::write_memory_byte: 65, ExtCosts::read_register_base: 1, - ExtCosts::read_register_byte: 20, + ExtCosts::read_register_byte: 65, ExtCosts::write_register_base: 1, - ExtCosts::write_register_byte: 20, + ExtCosts::write_register_byte: 65, ExtCosts::ecrecover_base: 1, }); } From 4f82dc98fa578715a5748a279f487dbb37842ad9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 11:49:44 +0700 Subject: [PATCH 078/134] Correct blake2 message block math --- Cargo.lock | 1 + runtime/near-vm-logic/Cargo.toml | 1 + runtime/near-vm-logic/src/logic.rs | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec196d13b4d..d81f0f4822f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3638,6 +3638,7 @@ dependencies = [ "near-primitives-core", "near-runtime-utils", "near-vm-errors", + "num-integer", "ripemd160", "serde", "serde_json", diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 22253f32958..6e4546c5823 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -19,6 +19,7 @@ borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" libsecp256k1 = { version = "0.3.5", optional = true } +num-integer = "0.1" ripemd160 = { version = "0.9.0", optional = true } serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index ff52bb024fc..5fd4b539b64 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1006,6 +1006,7 @@ impl<'a> VMLogic<'a> { register_id: u64, ) -> Result<()> { use blake2::VarBlake2b; + use num_integer::Integer; use std::convert::TryFrom; if state_len != 8 { @@ -1013,7 +1014,7 @@ impl<'a> VMLogic<'a> { } // Change to per block for gas. - let message_blocks = std::cmp::max(message_len / 128, 1); + let message_blocks = std::cmp::max(message_len.div_ceil(&128), 1); self.gas_counter.pay_base(blake2b_base)?; self.gas_counter.pay_per(blake2b_block, message_blocks)?; @@ -1058,6 +1059,7 @@ impl<'a> VMLogic<'a> { register_id: u64, ) -> Result<()> { use blake2::VarBlake2s; + use num_integer::Integer; use std::convert::TryFrom; if state_len != 8 { @@ -1065,7 +1067,7 @@ impl<'a> VMLogic<'a> { } // Change to per block for gas. - let message_blocks = std::cmp::max(message_len / 64, 1); + let message_blocks = std::cmp::max(message_len.div_ceil(&64), 1); self.gas_counter.pay_base(blake2b_base)?; self.gas_counter.pay_per(blake2b_block, message_blocks)?; From c79cd20a0b054aba825b74e5c3b806f9b2392bbf Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 11:52:48 +0700 Subject: [PATCH 079/134] Correct ripemd160 message block math --- runtime/near-vm-logic/src/logic.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 5fd4b539b64..0873d7e525f 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -965,10 +965,12 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks` #[cfg(feature = "protocol_feature_evm")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { + use num_integer::Integer; + self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - let message_blocks = std::cmp::max(value_len / 8, 1); + let message_blocks = (value_len + 9).div_ceil(&64); self.gas_counter.pay_per(ripemd160_block, message_blocks)?; From 98ae102552765263d4642256a479b15717db66ce Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 12:03:40 +0700 Subject: [PATCH 080/134] Read blake2s as u32 not u64 --- runtime/near-vm-logic/src/logic.rs | 21 +++++++++++++-------- runtime/near-vm-logic/tests/test_miscs.rs | 4 ++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 0873d7e525f..9793a49a221 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -208,6 +208,17 @@ impl<'a> VMLogic<'a> { memory_get!(u16, memory_get_u16); memory_get!(u8, memory_get_u8); + /// Reads an arrow of `u32` elements. + fn memory_get_vec_u32(&mut self, offset: u64, num_elements: u64) -> Result> { + let memory_len = num_elements + .checked_mul(size_of::() as u64) + .ok_or(HostError::MemoryAccessViolation)?; + let data = self.memory_get_vec(offset, memory_len)?; + let mut res = vec![0u32; num_elements as usize]; + byteorder::LittleEndian::read_u32_into(&data, &mut res); + Ok(res) + } + /// Reads an array of `u64` elements. fn memory_get_vec_u64(&mut self, offset: u64, num_elements: u64) -> Result> { let memory_len = num_elements @@ -1075,14 +1086,8 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_per(blake2b_block, message_blocks)?; self.gas_counter.pay_per(blake2b_round, (rounds as u64) * message_blocks)?; - let state = { - let mut buf = [0u32; 8]; - let values = self.memory_get_vec_u64(state_ptr, 8)?; - for (x, y) in buf.iter_mut().zip(values.into_iter()) { - *x = ::try_from(y).map_err(|_| HostError::IntegerOverflow)?; - } - buf - }; + let state = <[u32; 8]>::try_from(self.memory_get_vec_u32(state_ptr, 8)?) + .expect("vec bytes conversion"); let m = self.memory_get_vec(message_ptr, message_len)?; let t0 = t as u32; diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 0c143b7cfce..88c844ffd73 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -635,7 +635,7 @@ fn test_blake2s() { let rounds = 10; // These must be u64, even though they are actually u32. - let h: [u64; 8] = [ + let h: [u32; 8] = [ 0x6b08e647, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, ]; @@ -668,7 +668,7 @@ fn test_blake2s() { ]; assert_eq!(res, expected); - let len = m.len() as u64 + (h.len() as u64 * 8); + let len = m.len() as u64 + (h.len() as u64 * 4); assert_costs(map! { ExtCosts::base: 1, ExtCosts::read_memory_base: 2, From 6db13240ccc4846bbefebdc5a41e6e1bf8dc2698 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 12:29:52 +0700 Subject: [PATCH 081/134] Remove `state_len` and blake2 len error --- chain/jsonrpc/res/rpc_errors_schema.json | 10 +--------- runtime/near-vm-errors/src/lib.rs | 5 ----- runtime/near-vm-logic/src/logic.rs | 10 ---------- runtime/near-vm-logic/tests/test_miscs.rs | 2 -- 4 files changed, 1 insertion(+), 26 deletions(-) diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index e4d37938f6b..e5ac6cec66e 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -15,13 +15,6 @@ "subtypes": [], "props": {} }, - "Blake2StateLengthExceeded": { - "name": "Blake2StateLengthExceeded", - "subtypes": [], - "props": { - "length": "" - } - }, "BreakpointTrap": { "name": "BreakpointTrap", "subtypes": [], @@ -170,8 +163,7 @@ "NumberInputDataDependenciesExceeded", "ReturnedValueLengthExceeded", "ContractSizeExceeded", - "Deprecated", - "Blake2StateLengthExceeded" + "Deprecated" ], "props": {} }, diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index f58e0ba536d..9311eb01030 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -206,9 +206,6 @@ pub enum HostError { ContractSizeExceeded { size: u64, limit: u64 }, /// The host function was deprecated. Deprecated { method_name: String }, - /// The length of the state is not 64. - #[cfg(feature = "protocol_feature_evm")] - Blake2StateLengthExceeded { length: u64 }, /// Deserialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg: String }, @@ -497,8 +494,6 @@ impl std::fmt::Display for HostError { ReturnedValueLengthExceeded { length, limit } => write!(f, "The length of a returned value {} exceeds the limit {}", length, limit), ContractSizeExceeded { size, limit } => write!(f, "The size of a contract code in DeployContract action {} exceeds the limit {}", size, limit), Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), - #[cfg(feature = "protocol_feature_evm")] - Blake2StateLengthExceeded { length } => write!(f, "Invalid Blake2 state length {}, must be 8 words of 8 bytes", length), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 9793a49a221..09133f96f83 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1008,7 +1008,6 @@ impl<'a> VMLogic<'a> { pub fn blake2b( &mut self, rounds: u32, - state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, @@ -1022,10 +1021,6 @@ impl<'a> VMLogic<'a> { use num_integer::Integer; use std::convert::TryFrom; - if state_len != 8 { - return Err(HostError::Blake2StateLengthExceeded { length: state_len }.into()); - } - // Change to per block for gas. let message_blocks = std::cmp::max(message_len.div_ceil(&128), 1); @@ -1062,7 +1057,6 @@ impl<'a> VMLogic<'a> { pub fn blake2s( &mut self, rounds: u32, - state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, @@ -1075,10 +1069,6 @@ impl<'a> VMLogic<'a> { use num_integer::Integer; use std::convert::TryFrom; - if state_len != 8 { - return Err(HostError::Blake2StateLengthExceeded { length: state_len }.into()); - } - // Change to per block for gas. let message_blocks = std::cmp::max(message_len.div_ceil(&64), 1); diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 88c844ffd73..cef620cdb73 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -586,7 +586,6 @@ fn test_blake2b() { logic .blake2b( rounds, - h.len() as u64, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, @@ -647,7 +646,6 @@ fn test_blake2s() { logic .blake2s( rounds, - h.len() as u64, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, From ed8b9c89fbb0c0b9aba2d3a800434e900e6fef38 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 12:32:46 +0700 Subject: [PATCH 082/134] Add `saturating_mul` to blake2 math --- runtime/near-vm-logic/src/logic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 09133f96f83..d2fd2db4189 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1026,7 +1026,7 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_base(blake2b_base)?; self.gas_counter.pay_per(blake2b_block, message_blocks)?; - self.gas_counter.pay_per(blake2b_round, (rounds as u64) * message_blocks)?; + self.gas_counter.pay_per(blake2b_round, (rounds as u64).saturating_mul(message_blocks))?; let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) .expect("vec bytes conversion"); @@ -1074,7 +1074,7 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_base(blake2b_base)?; self.gas_counter.pay_per(blake2b_block, message_blocks)?; - self.gas_counter.pay_per(blake2b_round, (rounds as u64) * message_blocks)?; + self.gas_counter.pay_per(blake2b_round, (rounds as u64).saturating_mul(message_blocks))?; let state = <[u32; 8]>::try_from(self.memory_get_vec_u32(state_ptr, 8)?) .expect("vec bytes conversion"); From fa448b1a3d64b665c41b6d082fae4bb8a88687cb Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 12:54:22 +0700 Subject: [PATCH 083/134] Don't allocate an extra vec on blake2 --- Cargo.lock | 1 + runtime/near-vm-logic/Cargo.toml | 5 +++-- runtime/near-vm-logic/src/logic.rs | 23 +++++++-------------- runtime/near-vm-logic/tests/test_miscs.rs | 25 ++--------------------- 4 files changed, 13 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d81f0f4822f..df296da9c52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3631,6 +3631,7 @@ dependencies = [ "base64 0.13.0", "borsh", "bs58", + "byte-slice-cast", "byteorder", "libsecp256k1", "near-blake2", diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 6e4546c5823..babb8a23e44 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -17,9 +17,10 @@ base64 = "0.13" blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "29a15a", optional = true } borsh = "0.8.1" bs58 = "0.4" +byte-slice-cast = { version = "1.0", optional = true } byteorder = "1.2" libsecp256k1 = { version = "0.3.5", optional = true } -num-integer = "0.1" +num-integer = { version = "0.1", optional = true } ripemd160 = { version = "0.9.0", optional = true } serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" @@ -37,7 +38,7 @@ serde_json = {version= "1", features= ["preserve_order"]} [features] default = [] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "near-vm-errors/protocol_feature_evm", "blake2", "ripemd160", "libsecp256k1"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "near-vm-errors/protocol_feature_evm", "blake2", "ripemd160", "libsecp256k1", "byte-slice-cast", "num-integer"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index d2fd2db4189..67fad8f5b61 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -208,17 +208,6 @@ impl<'a> VMLogic<'a> { memory_get!(u16, memory_get_u16); memory_get!(u8, memory_get_u8); - /// Reads an arrow of `u32` elements. - fn memory_get_vec_u32(&mut self, offset: u64, num_elements: u64) -> Result> { - let memory_len = num_elements - .checked_mul(size_of::() as u64) - .ok_or(HostError::MemoryAccessViolation)?; - let data = self.memory_get_vec(offset, memory_len)?; - let mut res = vec![0u32; num_elements as usize]; - byteorder::LittleEndian::read_u32_into(&data, &mut res); - Ok(res) - } - /// Reads an array of `u64` elements. fn memory_get_vec_u64(&mut self, offset: u64, num_elements: u64) -> Result> { let memory_len = num_elements @@ -1018,8 +1007,8 @@ impl<'a> VMLogic<'a> { register_id: u64, ) -> Result<()> { use blake2::VarBlake2b; + use byte_slice_cast::AsMutByteSlice; use num_integer::Integer; - use std::convert::TryFrom; // Change to per block for gas. let message_blocks = std::cmp::max(message_len.div_ceil(&128), 1); @@ -1028,8 +1017,9 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_per(blake2b_block, message_blocks)?; self.gas_counter.pay_per(blake2b_round, (rounds as u64).saturating_mul(message_blocks))?; - let state = <[u64; 8]>::try_from(self.memory_get_vec_u64(state_ptr, 8)?) - .expect("vec bytes conversion"); + let mut state = [0u64; 8]; + self.memory_get_into(state_ptr, state.as_mut_byte_slice())?; + let m = self.memory_get_vec(message_ptr, message_len)?; let mut hasher = VarBlake2b::with_state(rounds, state, [t0, t1]); @@ -1066,6 +1056,7 @@ impl<'a> VMLogic<'a> { register_id: u64, ) -> Result<()> { use blake2::VarBlake2s; + use byte_slice_cast::AsMutByteSlice; use num_integer::Integer; use std::convert::TryFrom; @@ -1076,8 +1067,8 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_per(blake2b_block, message_blocks)?; self.gas_counter.pay_per(blake2b_round, (rounds as u64).saturating_mul(message_blocks))?; - let state = <[u32; 8]>::try_from(self.memory_get_vec_u32(state_ptr, 8)?) - .expect("vec bytes conversion"); + let mut state = [0u32; 8]; + self.memory_get_into(state_ptr, state.as_mut_byte_slice())?; let m = self.memory_get_vec(message_ptr, message_len)?; let t0 = t as u32; diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index cef620cdb73..5f4473be06b 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -584,17 +584,7 @@ fn test_blake2b() { let f1 = 0; logic - .blake2b( - rounds, - h.as_ptr() as _, - m.len() as u64, - m.as_ptr() as _, - t0, - t1, - f0, - f1, - 0, - ) + .blake2b(rounds, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, t0, t1, f0, f1, 0) .unwrap(); let res = [0u8; 64]; @@ -643,18 +633,7 @@ fn test_blake2s() { let f0: u32 = !0; let f1: u32 = 0; - logic - .blake2s( - rounds, - h.as_ptr() as _, - m.len() as u64, - m.as_ptr() as _, - t, - f0, - f1, - 0, - ) - .unwrap(); + logic.blake2s(rounds, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, t, f0, f1, 0).unwrap(); let res = [0u8; 32]; logic.read_register(0, res.as_ptr() as _).expect("OK"); From 60a426b7b749aeb290e8d65c2d3fa596579a1c02 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 13:10:42 +0700 Subject: [PATCH 084/134] Remove unused import --- runtime/near-vm-logic/src/logic.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 67fad8f5b61..1745ac43d45 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1058,7 +1058,6 @@ impl<'a> VMLogic<'a> { use blake2::VarBlake2s; use byte_slice_cast::AsMutByteSlice; use num_integer::Integer; - use std::convert::TryFrom; // Change to per block for gas. let message_blocks = std::cmp::max(message_len.div_ceil(&64), 1); From c1eba41a891037735d4a1af28830e67bc9719423 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 13:22:52 +0700 Subject: [PATCH 085/134] Fix args in wrapped imports --- runtime/near-vm-logic/src/logic.rs | 6 ++++-- runtime/near-vm-runner/src/imports.rs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 1745ac43d45..0206455dd61 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1051,8 +1051,7 @@ impl<'a> VMLogic<'a> { message_len: u64, message_ptr: u64, t: u64, - f0: u32, - f1: u32, + f: u64, register_id: u64, ) -> Result<()> { use blake2::VarBlake2s; @@ -1074,6 +1073,9 @@ impl<'a> VMLogic<'a> { let t1 = (t >> 32) as u32; let mut hasher = VarBlake2s::with_state(rounds, state, [t0, t1]); hasher.update_inner(&m); + + let f0 = f as u32; + let f1 = (f >> 32) as u32; hasher.compress(f0, f1); let res = hasher.output(); diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index d69ca141118..f1dbdb95c14 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -222,8 +222,8 @@ wrapped_imports! { keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2b<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u32, t1: u32, f0: u32, f1: u32, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2b<[rounds: u32, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u64, t1: u64, f0: u64, f1: u64, register_id: u64] -> []>, + #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f: u64, register_id: u64] -> []>, #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # From 881aaee9766e1404f8537a33bc4add904897de28 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sat, 19 Jun 2021 14:12:42 +0700 Subject: [PATCH 086/134] Fix blake2s test --- runtime/near-vm-logic/tests/test_miscs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 5f4473be06b..a116a42ed72 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -630,10 +630,10 @@ fn test_blake2s() { ]; let m: &[u8; 3] = b"abc"; let t: u64 = 0; - let f0: u32 = !0; - let f1: u32 = 0; + // equivalent to !0 for u32. + let f = u32::MAX as u64; - logic.blake2s(rounds, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, t, f0, f1, 0).unwrap(); + logic.blake2s(rounds, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, t, f, 0).unwrap(); let res = [0u8; 32]; logic.read_register(0, res.as_ptr() as _).expect("OK"); From 08d50cb811dc32bf807c310f0e4d784b195388a4 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sun, 20 Jun 2021 23:04:24 +0700 Subject: [PATCH 087/134] Remove blake2 and added protocol_feature_evm conditional comps --- Cargo.lock | 1 - core/primitives-core/src/config.rs | 84 --------- core/primitives/Cargo.toml | 2 +- runtime/near-vm-errors/Cargo.toml | 1 - runtime/near-vm-logic/Cargo.toml | 3 +- runtime/near-vm-logic/src/logic.rs | 104 ----------- runtime/near-vm-logic/tests/test_miscs.rs | 104 ----------- runtime/near-vm-runner-standalone/Cargo.toml | 2 +- runtime/near-vm-runner/src/imports.rs | 6 +- runtime/runtime-params-estimator/src/cases.rs | 42 +---- .../src/ext_costs_generator.rs | 16 +- runtime/runtime-params-estimator/src/lib.rs | 12 +- .../test-contract/src/lib.rs | 162 ------------------ 13 files changed, 17 insertions(+), 522 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a80826b0029..fc4daf5b2d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3631,7 +3631,6 @@ dependencies = [ "base64 0.13.0", "borsh", "bs58", - "byte-slice-cast", "byteorder", "libsecp256k1", "near-blake2", diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index d7910ded23c..396b0e8d46e 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -224,33 +224,11 @@ pub struct ExtCostsConfig { pub keccak512_byte: Gas, /// Cost of getting ripemd160 base - #[cfg(feature = "protocol_feature_evm")] pub ripemd160_base: Gas, /// Cost of getting ripemd160 per message block - #[cfg(feature = "protocol_feature_evm")] pub ripemd160_block: Gas, - /// Cost of getting blake2b base - #[cfg(feature = "protocol_feature_evm")] - pub blake2b_base: Gas, - /// Cost of getting blake2b per 128 byte message block. - #[cfg(feature = "protocol_feature_evm")] - pub blake2b_block: Gas, - /// Cost of a single blake2b round. - #[cfg(feature = "protocol_feature_evm")] - pub blake2b_round: Gas, - /// Cost of getting blake2b base - #[cfg(feature = "protocol_feature_evm")] - pub blake2s_base: Gas, - /// Cost of getting blake2b per 128 byte message block. - #[cfg(feature = "protocol_feature_evm")] - pub blake2s_block: Gas, - /// Cost of a single blake2b round. - #[cfg(feature = "protocol_feature_evm")] - pub blake2s_round: Gas, - /// Cost of calling ecrecover - #[cfg(feature = "protocol_feature_evm")] pub ecrecover_base: Gas, /// Cost for calling logging. @@ -383,23 +361,8 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, - #[cfg(feature = "protocol_feature_evm")] ripemd160_base: SAFETY_MULTIPLIER * 15136567500, // 10 x sha256_base - #[cfg(feature = "protocol_feature_evm")] ripemd160_block: SAFETY_MULTIPLIER * 80391170 * 8, // 10 x sha256_byte x 8 bytes - #[cfg(feature = "protocol_feature_evm")] - blake2b_base: SAFETY_MULTIPLIER * 88256037, // same as base. - #[cfg(feature = "protocol_feature_evm")] - blake2b_block: SAFETY_MULTIPLIER * 1029006976, // sha256 per byte x 128 - #[cfg(feature = "protocol_feature_evm")] - blake2b_round: SAFETY_MULTIPLIER * 25227612, // sha256 base / 60 - #[cfg(feature = "protocol_feature_evm")] - blake2s_base: SAFETY_MULTIPLIER * 58837358, // blake2b * (2/3) - #[cfg(feature = "protocol_feature_evm")] - blake2s_block: SAFETY_MULTIPLIER * 686004650, // blake2b * (2/3) - #[cfg(feature = "protocol_feature_evm")] - blake2s_round: SAFETY_MULTIPLIER * 16818408, // blake2b * (2/3) - #[cfg(feature = "protocol_feature_evm")] ecrecover_base: SAFETY_MULTIPLIER * 75682837500, // 50 x sha256_base log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -471,23 +434,8 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, - #[cfg(feature = "protocol_feature_evm")] ripemd160_base: 0, - #[cfg(feature = "protocol_feature_evm")] ripemd160_block: 0, - #[cfg(feature = "protocol_feature_evm")] - blake2b_base: 0, - #[cfg(feature = "protocol_feature_evm")] - blake2b_block: 0, - #[cfg(feature = "protocol_feature_evm")] - blake2b_round: 0, - #[cfg(feature = "protocol_feature_evm")] - blake2s_base: 0, - #[cfg(feature = "protocol_feature_evm")] - blake2s_block: 0, - #[cfg(feature = "protocol_feature_evm")] - blake2s_round: 0, - #[cfg(feature = "protocol_feature_evm")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -560,23 +508,8 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, - #[cfg(feature = "protocol_feature_evm")] ripemd160_base, - #[cfg(feature = "protocol_feature_evm")] ripemd160_block, - #[cfg(feature = "protocol_feature_evm")] - blake2b_base, - #[cfg(feature = "protocol_feature_evm")] - blake2b_block, - #[cfg(feature = "protocol_feature_evm")] - blake2b_round, - #[cfg(feature = "protocol_feature_evm")] - blake2s_base, - #[cfg(feature = "protocol_feature_evm")] - blake2s_block, - #[cfg(feature = "protocol_feature_evm")] - blake2s_round, - #[cfg(feature = "protocol_feature_evm")] ecrecover_base, log_base, log_byte, @@ -702,23 +635,8 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, - #[cfg(feature = "protocol_feature_evm")] ripemd160_base => config.ripemd160_base, - #[cfg(feature = "protocol_feature_evm")] ripemd160_block => config.ripemd160_block, - #[cfg(feature = "protocol_feature_evm")] - blake2b_base => config.blake2b_base, - #[cfg(feature = "protocol_feature_evm")] - blake2b_block => config.blake2b_block, - #[cfg(feature = "protocol_feature_evm")] - blake2b_round => config.blake2b_round, - #[cfg(feature = "protocol_feature_evm")] - blake2s_base => config.blake2s_base, - #[cfg(feature = "protocol_feature_evm")] - blake2s_block => config.blake2s_block, - #[cfg(feature = "protocol_feature_evm")] - blake2s_round => config.blake2s_round, - #[cfg(feature = "protocol_feature_evm")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, @@ -796,8 +714,6 @@ impl ExtCosts { "keccak512_byte", "ripemd160_base", "ripemd160_block", - "blake2b_base", - "blake2b_byte", "ecrecover_base", "log_base", "log_byte", diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 0018f0ff49b..c6bff6cbf26 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -42,7 +42,7 @@ near-rpc-error-macro = { path = "../../tools/rpctypegen/macro" } default = ["jemallocator"] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] protocol_feature_add_account_versions = ["near-primitives-core/protocol_feature_add_account_versions"] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "near-vm-errors/protocol_feature_evm"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"] protocol_feature_block_header_v3 = [] protocol_feature_alt_bn128 = ["near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_tx_size_limit = ["near-primitives-core/protocol_feature_tx_size_limit"] diff --git a/runtime/near-vm-errors/Cargo.toml b/runtime/near-vm-errors/Cargo.toml index c133e2d99aa..e186a7830da 100644 --- a/runtime/near-vm-errors/Cargo.toml +++ b/runtime/near-vm-errors/Cargo.toml @@ -22,7 +22,6 @@ near-rpc-error-macro = { path = "../../tools/rpctypegen/macro", version = "0.1.0 [features] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] -protocol_feature_evm = [] protocol_feature_alt_bn128 = [] [package.metadata.workspaces] diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index babb8a23e44..33b7b050013 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -17,7 +17,6 @@ base64 = "0.13" blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "29a15a", optional = true } borsh = "0.8.1" bs58 = "0.4" -byte-slice-cast = { version = "1.0", optional = true } byteorder = "1.2" libsecp256k1 = { version = "0.3.5", optional = true } num-integer = { version = "0.1", optional = true } @@ -38,7 +37,7 @@ serde_json = {version= "1", features= ["preserve_order"]} [features] default = [] -protocol_feature_evm = ["near-primitives-core/protocol_feature_evm", "near-vm-errors/protocol_feature_evm", "blake2", "ripemd160", "libsecp256k1", "byte-slice-cast", "num-integer"] +protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 0206455dd61..0efe4609553 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -963,7 +963,6 @@ impl<'a> VMLogic<'a> { /// Where `message_blocks` is `max(message_len / 8, 1)`. /// /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks` - #[cfg(feature = "protocol_feature_evm")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { use num_integer::Integer; @@ -980,108 +979,6 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } - /// Hashes the given message using BLAKE2b and returns it into `register_id`. - /// - /// # Errors - /// - /// If `value_len + value_ptr` points outside the memory or the registers use more memory than - /// the limit with `MemoryAccessViolation`. - /// - /// # Cost - /// - /// Where `message_blocks` is `max(message_len / 128, 1)`. - /// - /// `base + write_register_base + write_register_byte * num_bytes + - /// message_blocks * blake2b_block + rounds * message_blocks` - #[cfg(feature = "protocol_feature_evm")] - pub fn blake2b( - &mut self, - rounds: u32, - state_ptr: u64, - message_len: u64, - message_ptr: u64, - t0: u64, - t1: u64, - f0: u64, - f1: u64, - register_id: u64, - ) -> Result<()> { - use blake2::VarBlake2b; - use byte_slice_cast::AsMutByteSlice; - use num_integer::Integer; - - // Change to per block for gas. - let message_blocks = std::cmp::max(message_len.div_ceil(&128), 1); - - self.gas_counter.pay_base(blake2b_base)?; - self.gas_counter.pay_per(blake2b_block, message_blocks)?; - self.gas_counter.pay_per(blake2b_round, (rounds as u64).saturating_mul(message_blocks))?; - - let mut state = [0u64; 8]; - self.memory_get_into(state_ptr, state.as_mut_byte_slice())?; - - let m = self.memory_get_vec(message_ptr, message_len)?; - - let mut hasher = VarBlake2b::with_state(rounds, state, [t0, t1]); - hasher.update_inner(&m); - hasher.compress(f0, f1); - let res = hasher.output(); - - self.internal_write_register(register_id, res.as_slice().to_vec()) - } - - /// Hashes the given message using BLAKE2s and returns it into `register_id`. - /// - /// # Errors - /// - /// If `value_len + value_ptr` points outside the memory or the registers use more memory than - /// the limit with `MemoryAccessViolation`. - /// - /// # Cost - /// - /// Where `message_blocks` is `max(message_len / 128, 1)`. - /// - /// `base + write_register_base + write_register_byte * num_bytes + - /// message_blocks * blake2s_block + rounds * message_blocks` - #[cfg(feature = "protocol_feature_evm")] - pub fn blake2s( - &mut self, - rounds: u32, - state_ptr: u64, - message_len: u64, - message_ptr: u64, - t: u64, - f: u64, - register_id: u64, - ) -> Result<()> { - use blake2::VarBlake2s; - use byte_slice_cast::AsMutByteSlice; - use num_integer::Integer; - - // Change to per block for gas. - let message_blocks = std::cmp::max(message_len.div_ceil(&64), 1); - - self.gas_counter.pay_base(blake2b_base)?; - self.gas_counter.pay_per(blake2b_block, message_blocks)?; - self.gas_counter.pay_per(blake2b_round, (rounds as u64).saturating_mul(message_blocks))?; - - let mut state = [0u32; 8]; - self.memory_get_into(state_ptr, state.as_mut_byte_slice())?; - let m = self.memory_get_vec(message_ptr, message_len)?; - - let t0 = t as u32; - let t1 = (t >> 32) as u32; - let mut hasher = VarBlake2s::with_state(rounds, state, [t0, t1]); - hasher.update_inner(&m); - - let f0 = f as u32; - let f1 = (f >> 32) as u32; - hasher.compress(f0, f1); - let res = hasher.output(); - - self.internal_write_register(register_id, res.as_slice().to_vec()) - } - /// Recovers an ECDSA signer address and returns it into `register_id`. /// /// Returns a bool indicating success or failure as a `u64`. @@ -1094,7 +991,6 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` - #[cfg(feature = "protocol_feature_evm")] pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result { self.gas_counter.pay_base(ecrecover_base)?; diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index a116a42ed72..fcefe4fb1eb 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -531,7 +531,6 @@ fn test_keccak512() { } #[test] -#[cfg(feature = "protocol_feature_evm")] fn test_ripemd160() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); @@ -561,109 +560,6 @@ fn test_ripemd160() { } #[test] -#[cfg(feature = "protocol_feature_evm")] -fn test_blake2b() { - let mut logic_builder = VMLogicBuilder::default(); - let mut logic = logic_builder.build(get_context(vec![], false)); - - let rounds = 12; - let h: [u64; 8] = [ - 0x6a09e667f2bdc948, - 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, - 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, - 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, - 0x5be0cd19137e2179, - ]; - let m = b"abc"; - let t0 = 0; - let t1 = 0; - let f0 = !0; - let f1 = 0; - - logic - .blake2b(rounds, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, t0, t1, f0, f1, 0) - .unwrap(); - - let res = [0u8; 64]; - logic.read_register(0, res.as_ptr() as _).expect("OK"); - - let expected: [u8; 64] = [ - 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, - 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, - 0xa2, 0xd1, 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde, 0x45, - 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a, 0xb9, 0x23, 0x86, 0xed, - 0xd4, 0x0, 0x99, 0x23, - ]; - assert_eq!(res, expected); - - let len = m.len() as u64 + (h.len() as u64 * 8); - assert_costs(map! { - ExtCosts::base: 1, - ExtCosts::read_memory_base: 2, - ExtCosts::read_memory_byte: len, - ExtCosts::write_memory_base: 1, - ExtCosts::write_memory_byte: 64, - ExtCosts::read_register_base: 1, - ExtCosts::read_register_byte: 64, - ExtCosts::write_register_base: 1, - ExtCosts::write_register_byte: 64, - ExtCosts::blake2b_base: 1, - ExtCosts::blake2b_block: 1, - ExtCosts::blake2b_round: 12, - }); -} - -#[test] -#[cfg(feature = "protocol_feature_evm")] -fn test_blake2s() { - let mut logic_builder = VMLogicBuilder::default(); - let mut logic = logic_builder.build(get_context(vec![], false)); - - let rounds = 10; - // These must be u64, even though they are actually u32. - let h: [u32; 8] = [ - 0x6b08e647, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, - 0x5be0cd19, - ]; - let m: &[u8; 3] = b"abc"; - let t: u64 = 0; - // equivalent to !0 for u32. - let f = u32::MAX as u64; - - logic.blake2s(rounds, h.as_ptr() as _, m.len() as u64, m.as_ptr() as _, t, f, 0).unwrap(); - - let res = [0u8; 32]; - logic.read_register(0, res.as_ptr() as _).expect("OK"); - - let expected: [u8; 32] = [ - 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2, 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, - 0x2f, 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29, 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, - 0x59, 0x82, - ]; - assert_eq!(res, expected); - - let len = m.len() as u64 + (h.len() as u64 * 4); - assert_costs(map! { - ExtCosts::base: 1, - ExtCosts::read_memory_base: 2, - ExtCosts::read_memory_byte: len, - ExtCosts::write_memory_base: 1, - ExtCosts::write_memory_byte: 32, - ExtCosts::read_register_base: 1, - ExtCosts::read_register_byte: 32, - ExtCosts::write_register_base: 1, - ExtCosts::write_register_byte: 32, - ExtCosts::blake2b_base: 1, - ExtCosts::blake2b_block: 1, - ExtCosts::blake2b_round: 10, - }); -} - -#[test] -#[cfg(feature = "protocol_feature_evm")] fn test_ecrecover() { let mut logic_builder = VMLogicBuilder::default(); let mut logic = logic_builder.build(get_context(vec![], false)); diff --git a/runtime/near-vm-runner-standalone/Cargo.toml b/runtime/near-vm-runner-standalone/Cargo.toml index 4566418a0ca..b2a72fae1f5 100644 --- a/runtime/near-vm-runner-standalone/Cargo.toml +++ b/runtime/near-vm-runner-standalone/Cargo.toml @@ -39,7 +39,7 @@ near-test-contracts = { path = "../near-test-contracts" } [features] default = [] no_cache = ["near-vm-runner/no_cache"] -protocol_feature_evm = ["near-vm-logic/protocol_feature_evm", "near-vm-runner/protocol_feature_evm"] +protocol_feature_evm = ["near-primitives/protocol_feature_evm"] protocol_feature_alt_bn128 = ["near-vm-logic/protocol_feature_alt_bn128", "near-vm-runner/protocol_feature_alt_bn128"] protocol_feature_block_header_v3 = ["near-primitives/protocol_feature_block_header_v3"] protocol_feature_add_account_versions = ["near-primitives/protocol_feature_add_account_versions"] diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index f1dbdb95c14..e95e5cdd11c 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -221,10 +221,8 @@ wrapped_imports! { sha256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2b<[rounds: u32, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u64, t1: u64, f0: u64, f1: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] blake2s<[rounds: u32, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f: u64, register_id: u64] -> []>, - #["protocol_feature_evm", EVM] ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> [u64]>, + ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index e0238594a1c..10b0dc1054f 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -198,23 +198,8 @@ pub enum Metric { keccak256_10kib_10k, keccak512_10b_10k, keccak512_10kib_10k, - #[cfg(feature = "protocol_feature_evm")] ripemd160_10b_10k, - #[cfg(feature = "protocol_feature_evm")] ripemd160_10kib_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2b_128b_0r_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2b_128kb_0r_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2b_128b_12r_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2s_128b_0r_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2s_128kb_0r_10k, - #[cfg(feature = "protocol_feature_evm")] - blake2s_128b_10r_10k, - #[cfg(feature = "protocol_feature_evm")] ecrecover_10k, #[cfg(feature = "protocol_feature_alt_bn128")] alt_bn128_g1_multiexp_1_1k, @@ -596,15 +581,9 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon keccak256_10kib_10k => keccak256_10kib_10k, keccak512_10b_10k => keccak512_10b_10k, keccak512_10kib_10k => keccak512_10kib_10k, - #["protocol_feature_evm"] ripemd160_10b_10k => ripemd160_10b_10k, - #["protocol_feature_evm"] ripemd160_10kib_10k => ripemd160_10kib_10k, - #["protocol_feature_evm"] blake2b_128b_0r_10k => blake2b_128b_0r_10k, - #["protocol_feature_evm"] blake2b_128kb_0r_10k => blake2b_128kb_0r_10k, - #["protocol_feature_evm"] blake2b_128b_12r_10k => blake2b_128b_12r_10k, - #["protocol_feature_evm"] blake2s_128b_0r_10k => blake2s_128b_0r_10k, - #["protocol_feature_evm"] blake2s_128kb_0r_10k => blake2s_128kb_0r_10k, - #["protocol_feature_evm"] blake2s_128b_10r_10k => blake2s_128b_10r_10k, - #["protocol_feature_evm"] ecrecover_10k => ecrecover_10k, + ripemd160_10b_10k => ripemd160_10b_10k, + ripemd160_10kib_10k => ripemd160_10kib_10k, + ecrecover_10k => ecrecover_10k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_1_1k => alt_bn128_g1_multiexp_1_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_10_1k => alt_bn128_g1_multiexp_10_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_sum_1_1k => alt_bn128_g1_sum_1_1k, @@ -787,23 +766,8 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), - #[cfg(feature = "protocol_feature_evm")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), - #[cfg(feature = "protocol_feature_evm")] ripemd160_block: measured_to_gas(metric, &measured, ripemd160_block), - #[cfg(feature = "protocol_feature_evm")] - blake2b_base: measured_to_gas(metric, &measured, blake2b_base), - #[cfg(feature = "protocol_feature_evm")] - blake2b_block: measured_to_gas(metric, &measured, blake2b_block), - #[cfg(feature = "protocol_feature_evm")] - blake2b_round: measured_to_gas(metric, &measured, blake2b_round), - #[cfg(feature = "protocol_feature_evm")] - blake2s_base: measured_to_gas(metric, &measured, blake2s_base), - #[cfg(feature = "protocol_feature_evm")] - blake2s_block: measured_to_gas(metric, &measured, blake2s_block), - #[cfg(feature = "protocol_feature_evm")] - blake2s_round: measured_to_gas(metric, &measured, blake2s_round), - #[cfg(feature = "protocol_feature_evm")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index 880148a6eab..e9031c5504c 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,20 +65,10 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); - #[cfg(feature = "protocol_feature_evm")] - { - self.extract(ripemd160_10b_10k, ripemd160_base); - self.extract(ripemd160_10kib_10k, ripemd160_block); - - self.extract(blake2b_128b_0r_10k, blake2b_base); - self.extract(blake2b_128kb_0r_10k, blake2b_block); - self.extract(blake2b_128b_12r_10k, blake2b_round); - self.extract(blake2s_128b_0r_10k, blake2s_base); - self.extract(blake2s_128kb_0r_10k, blake2s_block); - self.extract(blake2s_128b_10r_10k, blake2s_round); + self.extract(ripemd160_10b_10k, ripemd160_base); + self.extract(ripemd160_10kib_10k, ripemd160_block); - self.extract(ecrecover_10k, ecrecover_base); - } + self.extract(ecrecover_10k, ecrecover_base); #[cfg(feature = "protocol_feature_alt_bn128")] { diff --git a/runtime/runtime-params-estimator/src/lib.rs b/runtime/runtime-params-estimator/src/lib.rs index 0c816cb58d0..afab35adf66 100644 --- a/runtime/runtime-params-estimator/src/lib.rs +++ b/runtime/runtime-params-estimator/src/lib.rs @@ -1,14 +1,12 @@ /// Lists all cases that we want to measure. pub mod cases; -/// Generates runtime fees from the measurements. -pub mod runtime_fees_generator; -/// Generates external costs from the measurements. -pub mod ext_costs_generator; #[cfg(feature = "protocol_feature_evm")] /// Generates the runtime fees for the EVM. pub mod evm_estimator; -/// Runs a VM (Default: Wasmer) on the given contract and measures the time it takes to do a single operation. -pub mod vm_estimator; +/// Generates external costs from the measurements. +pub mod ext_costs_generator; +/// Generates runtime fees from the measurements. +pub mod runtime_fees_generator; /// Collects and processes stats. Prints them on display, plots them, writes them into a file. pub mod stats; /// Encapsulates the runtime so that it can be run separately from the rest of the node. @@ -16,6 +14,8 @@ pub mod testbed; /// Prepares transactions and feeds them to the testbed in batches. Performs the warm up, takes care /// of nonces. pub mod testbed_runners; +/// Runs a VM (Default: Wasmer) on the given contract and measures the time it takes to do a single operation. +pub mod vm_estimator; use std::path::Path; diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index d77fdf07878..dad04d191a3 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -47,13 +47,7 @@ extern "C" { fn sha256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "protocol_feature_evm")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); - #[cfg(feature = "protocol_feature_evm")] - fn blake2b(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t: u64, f0: u64, f1: u64, register_id: u64); - #[cfg(feature = "protocol_feature_evm")] - fn blake2s(rounds: u32, state_len: u64, state_ptr: u64, message_len: u64, message_ptr: u64, t0: u32, t1: u32, f0: u32, f1: u32, register_id: u64); - #[cfg(feature = "protocol_feature_evm")] fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); // ##################### // # Miscellaneous API # @@ -437,7 +431,6 @@ pub unsafe fn keccak512_10kib_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10b 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_evm")] pub unsafe fn ripemd160_10b_10k() { let buffer = [65u8; 10]; for _ in 0..10_000 { @@ -449,7 +442,6 @@ pub unsafe fn ripemd160_10b_10k() { // so we are okay overcharging it. // Compute ripemd160 on 10kib 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_evm")] pub unsafe fn ripemd160_10kib_10k() { let buffer = [65u8; 10240]; for _ in 0..10_000 { @@ -457,165 +449,11 @@ pub unsafe fn ripemd160_10kib_10k() { } } -// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, -// and `write_register_byte`. However `blake2b` computation is more expensive than register writing -// so we are okay overcharging it. -// Compute blake2b on 10b 10k times. -#[no_mangle] -#[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2b_128b_0r_10k() { - let rounds = 0; - let state = [65u8; 64]; - let buffer = [65u8; 128]; - for _ in 0..10_000 { - blake2b( - rounds, - state.len() as u64, - state.as_ptr() as *const u64 as u64, - buffer.len() as u64, - buffer.as_ptr() as *const u64 as u64, - 0, - !0, - 0, - 0 - ); - } -} - -// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, -// and `write_register_byte`. However `blake2b` computation is more expensive than register writing -// so we are okay overcharging it. -// Compute blake2b on 10kib 10k times. -#[no_mangle] -#[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2b_128kb_0r_10k() { - let rounds = 0; - let state = [65u8; 64]; - let buffer = [65u8; 12800]; - for _ in 0..10_000 { - blake2b( - rounds, - state.len() as u64, - state.as_ptr() as *const u64 as u64, - buffer.len() as u64, - buffer.as_ptr() as *const u64 as u64, - 0, - !0, - 0, - 0 - ); - } -} - -// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, -// and `write_register_byte`. However `blake2b` computation is more expensive than register writing -// so we are okay overcharging it. -// Compute blake2b on 10kib 10k times. -#[no_mangle] -#[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2b_128b_12r_10k() { - let rounds = 12; - let state = [65u8; 64]; - let buffer = [65u8; 128]; - for _ in 0..10_000 { - blake2b( - rounds, - state.len() as u64, - state.as_ptr() as *const u64 as u64, - buffer.len() as u64, - buffer.as_ptr() as *const u64 as u64, - 0, - !0, - 0, - 0 - ); - } -} - -// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, -// and `write_register_byte`. However `blake2b` computation is more expensive than register writing -// so we are okay overcharging it. -// Compute blake2b on 10b 10k times. -#[no_mangle] -#[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2s_128b_0r_10k() { - let rounds = 0; - let state = [65u8; 64]; - let buffer = [65u8; 128]; - for _ in 0..10_000 { - blake2s( - rounds, - state.len() as u64, - state.as_ptr() as *const u64 as u64, - buffer.len() as u64, - buffer.as_ptr() as *const u64 as u64, - 0, - 0, - !0, - 0, - 0 - ); - } -} - -// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, -// and `write_register_byte`. However `blake2b` computation is more expensive than register writing -// so we are okay overcharging it. -// Compute blake2b on 10kib 10k times. -#[no_mangle] -#[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2s_128kb_0r_10k() { - let rounds = 0; - let state = [65u8; 64]; - let buffer = [65u8; 12800]; - for _ in 0..10_000 { - blake2s( - rounds, - state.len() as u64, - state.as_ptr() as *const u64 as u64, - buffer.len() as u64, - buffer.as_ptr() as *const u64 as u64, - 0, - 0, - !0, - 0, - 0 - ); - } -} - -// Function to measure `blake2b_base` and `blake2b_byte`. Also measures `base`, `write_register_base`, -// and `write_register_byte`. However `blake2b` computation is more expensive than register writing -// so we are okay overcharging it. -// Compute blake2b on 10kib 10k times. -#[no_mangle] -#[cfg(feature = "protocol_feature_evm")] -pub unsafe fn blake2s_128b_10r_10k() { - let rounds = 10; - let state = [65u8; 64]; - let buffer = [65u8; 128]; - for _ in 0..10_000 { - blake2s( - rounds, - state.len() as u64, - state.as_ptr() as *const u64 as u64, - buffer.len() as u64, - buffer.as_ptr() as *const u64 as u64, - 0, - 0, - !0, - 0, - 0 - ); - } -} - // Function to measure `ecrecover_base`. Also measures `base`, `write_register_base`, and // `write_register_byte`. However `ecrecover` computation is more expensive than register writing // so we are okay overcharging it. // Compute ecrecover 10k times. #[no_mangle] -#[cfg(feature = "protocol_feature_evm")] pub unsafe fn ecrecover_10k() { let hash = [0u8; 32]; let signature = [0u8; 65]; From 2d1ae301c922abe3d851722639af915e3c4255f2 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Sun, 20 Jun 2021 23:51:04 +0700 Subject: [PATCH 088/134] Remove optional from crypto imports in logic --- Cargo.lock | 1 - runtime/near-vm-logic/Cargo.toml | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc4daf5b2d7..cb17682a6cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3633,7 +3633,6 @@ dependencies = [ "bs58", "byteorder", "libsecp256k1", - "near-blake2", "near-primitives", "near-primitives-core", "near-runtime-utils", diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 33b7b050013..d6a6aa2f635 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -14,13 +14,12 @@ This crate implements the specification of the interface that Near blockchain ex [dependencies] base64 = "0.13" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "29a15a", optional = true } borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" -libsecp256k1 = { version = "0.3.5", optional = true } -num-integer = { version = "0.1", optional = true } -ripemd160 = { version = "0.9.0", optional = true } +libsecp256k1 = "0.3.5" +num-integer = "0.1" +ripemd160 = "0.9.0" serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" sha3 = ">=0.8,<0.10" From 951e7670b98fa639e18f29c9f25a6aae02dd665c Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 00:12:20 +0700 Subject: [PATCH 089/134] Revert from near-blake2 to upstream blake2 --- Cargo.lock | 23 ++++++++++++----------- core/crypto/Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb17682a6cf..73158d6aef2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -540,6 +540,17 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + [[package]] name = "blake2b_simd" version = "0.5.11" @@ -3016,16 +3027,6 @@ dependencies = [ "futures", ] -[[package]] -name = "near-blake2" -version = "0.9.1" -source = "git+https://github.com/near/near-blake2.git?rev=29a15a#29a15a1ffa3bfb7baa54318c89ee6cfebaf4d590" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "near-chain" version = "0.1.0" @@ -3170,6 +3171,7 @@ name = "near-crypto" version = "0.1.0" dependencies = [ "arrayref", + "blake2", "borsh", "bs58", "c2-chacha", @@ -3179,7 +3181,6 @@ dependencies = [ "hex-literal", "lazy_static", "libc", - "near-blake2", "parity-secp256k1", "rand 0.7.3", "rand_core 0.5.1", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index d34891a713b..924c9089dce 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] arrayref = "0.3" -blake2 = { package = "near-blake2", git = "https://github.com/near/near-blake2.git", rev = "29a15a" } +blake2 = "0.9.1" borsh = "0.8.1" bs58 = "0.4" c2-chacha = "0.3" From 9a3f92431ba9c945e5f6bb8e994e53e0b7414743 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 02:19:00 +0700 Subject: [PATCH 090/134] Drop libsecp256k1 crate in favour of near-crypto --- Cargo.lock | 2 +- core/crypto/src/lib.rs | 3 +- core/crypto/src/signature.rs | 78 +++++++++++++++++++++++ runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/logic.rs | 40 +++++++----- runtime/near-vm-logic/tests/test_miscs.rs | 17 ++--- runtime/near-vm-runner/src/imports.rs | 2 +- 7 files changed, 117 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73158d6aef2..d053f68e4d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3633,7 +3633,7 @@ dependencies = [ "borsh", "bs58", "byteorder", - "libsecp256k1", + "near-crypto", "near-primitives", "near-primitives-core", "near-runtime-utils", diff --git a/core/crypto/src/lib.rs b/core/crypto/src/lib.rs index e714ffd5fbd..88ad67e9561 100644 --- a/core/crypto/src/lib.rs +++ b/core/crypto/src/lib.rs @@ -1,7 +1,8 @@ pub use errors::{ParseKeyError, ParseKeyTypeError, ParseSignatureError}; pub use key_file::KeyFile; pub use signature::{ - ED25519PublicKey, KeyType, PublicKey, Secp256K1PublicKey, SecretKey, Signature, + ED25519PublicKey, KeyType, PublicKey, Secp256K1PublicKey, Secp256K1Signature, SecretKey, + Signature, }; pub use signer::{EmptySigner, InMemorySigner, Signer}; diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index e71f0614ff6..af313624214 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -9,6 +9,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; use ed25519_dalek::ed25519::signature::{Signature as _, Signer as _, Verifier as _}; use lazy_static::lazy_static; use rand_core::OsRng; +use secp256k1::Message; use serde::{Deserialize, Serialize}; lazy_static! { @@ -556,6 +557,83 @@ impl<'de> serde::Deserialize<'de> for SecretKey { #[derive(Clone)] pub struct Secp256K1Signature([u8; 65]); +impl Secp256K1Signature { + fn check_v(&self) -> Result { + match self.0[64] { + 27 | 28 => Ok(self.0[64] - 27), + _ => Err(crate::errors::ParseSignatureError::InvalidData { + error_message: "invalid `v` value".to_string(), + }), + } + } + + pub fn check_signature_values(&self) -> bool { + let r = &self.0[0..32]; + let s = &self.0[32..64]; + let v = match self.check_v() { + Ok(v) => v, + Err(_e) => return false, + }; + + let big_one: [u8; 32] = [ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + ]; + if r < &big_one || s < &big_one { + return false; + } + + // 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 / 2 + let secp256k1_half_n: [u8; 32] = [ + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x5d, 0x57, 0x6e, 0x73, 0x57, 0xa4, 0x50, 0x1d, 0xdf, 0xe9, 0x2f, 0x46, + 0x68, 0x1b, 0x20, 0xa0, + ]; + // Reject upper range of s values (ECDSA malleability) + if s > &secp256k1_half_n { + return false; + } + + // 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 + let secp256k1_n: [u8; 32] = [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, + 0xd0, 0x36, 0x41, 0x41, + ]; + r < &secp256k1_n && s < &secp256k1_n && (v == 0 || v == 1) + } + + pub fn recover( + &self, + msg: [u8; 32], + ) -> Result { + let v = self.check_v()?; + + // This can't fail because of the check above. It will fall in range. + let recover_id = secp256k1::RecoveryId::from_i32(i32::from(v)).unwrap(); + + let recoverable_sig = + secp256k1::RecoverableSignature::from_compact(&SECP256K1, &self.0[0..64], recover_id) + .map_err(|err| crate::errors::ParseSignatureError::InvalidData { + error_message: err.to_string(), + })?; + let msg = Message::from(msg); + + let res = SECP256K1 + .recover(&msg, &recoverable_sig) + .map_err(|err| crate::errors::ParseSignatureError::InvalidData { + error_message: err.to_string(), + })? + .serialize_vec(&SECP256K1, false); + + let pk = Secp256K1PublicKey::try_from(&res[0..64]).map_err(|err| { + crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string() } + })?; + + Ok(pk) + } +} + impl From<[u8; 65]> for Secp256K1Signature { fn from(data: [u8; 65]) -> Self { Self(data) diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index d6a6aa2f635..c5230760756 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -17,13 +17,13 @@ base64 = "0.13" borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" -libsecp256k1 = "0.3.5" num-integer = "0.1" ripemd160 = "0.9.0" serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" sha3 = ">=0.8,<0.10" +near-crypto = { path = "../../core/crypto" } near-primitives = { path = "../../core/primitives" } near-primitives-core = { path = "../../core/primitives-core", version = "0.1.0" } near-vm-errors = { path = "../near-vm-errors", version = "3.0.0" } diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 0efe4609553..f37cae487fd 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -5,6 +5,7 @@ use crate::types::{PromiseIndex, PromiseResult, ReceiptIndex, ReturnData}; use crate::utils::split_method_names; use crate::ValuePtr; use byteorder::ByteOrder; +use near_crypto::Secp256K1Signature; use near_primitives::checked_feature; use near_primitives::version::is_implicit_account_creation_enabled; use near_primitives_core::config::ExtCosts::*; @@ -981,6 +982,9 @@ impl<'a> VMLogic<'a> { /// Recovers an ECDSA signer address and returns it into `register_id`. /// + /// Takes in an additional flag to check for malleability of the signature + /// which is generally only ideal for transactions. + /// /// Returns a bool indicating success or failure as a `u64`. /// /// # Errors @@ -991,26 +995,32 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` - pub fn ecrecover(&mut self, hash_ptr: u64, sig_ptr: u64, register_id: u64) -> Result { + pub fn ecrecover( + &mut self, + hash_ptr: u64, + sig_ptr: u64, + malleability_flag: u8, + register_id: u64, + ) -> Result { self.gas_counter.pay_base(ecrecover_base)?; - let r = self.memory_get_vec(hash_ptr, 32)?; - let s = self.memory_get_vec(sig_ptr, 65)?; - let v = s[64]; + let mut signature_bytes = [0u8; 65]; + self.memory_get_into(sig_ptr, &mut signature_bytes)?; + let signature = Secp256K1Signature::from(signature_bytes); - let hash = secp256k1::Message::parse_slice(&r).unwrap(); - let signature = secp256k1::Signature::parse_slice(&s[0..64]).unwrap(); - let bit = match v { - 27 | 28 => v - 27, - _ => return Ok(false as u64), - }; - if let Ok(recovery_id) = secp256k1::RecoveryId::parse(bit) { - if let Ok(public_key) = secp256k1::recover(&hash, &signature, &recovery_id) { - // recover returns a 65-byte key, but addresses come from the raw 64-byte key - self.internal_write_register(register_id, public_key.serialize().to_vec())?; - return Ok(true as u64); + if malleability_flag == 1 { + if !signature.check_signature_values() { + return Ok(false as u64); } } + + let mut hash_bytes = [0u8; 32]; + self.memory_get_into(hash_ptr, &mut hash_bytes)?; + if let Ok(pk) = signature.recover(hash_bytes) { + self.internal_write_register(register_id, pk.as_ref().to_vec())?; + return Ok(true as u64); + }; + return Ok(false as u64); } diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index fcefe4fb1eb..24c0aebc1e9 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -574,18 +574,19 @@ fn test_ecrecover() { 0xbb, 0x01, 0xc1, 0xd8, 0x1d, 0x10, 0xe6, 0x9f, 0x03, 0x84, 0xe6, 0x75, 0xc3, 0x2b, 0x39, 0x64, 0x3b, 0xe8, 0x92, 0x1b, ]; - let signer: [u8; 65] = [ + let signer: [u8; 64] = [ 0x04, 0xb3, 0x68, 0x70, 0xea, 0xab, 0x31, 0xcb, 0xeb, 0x1a, 0x5c, 0x07, 0x46, 0x7b, 0x42, 0x97, 0x40, 0x7c, 0x62, 0x11, 0x7a, 0x31, 0x15, 0x47, 0xc4, 0x30, 0x5e, 0x14, 0x71, 0x52, 0x1b, 0x53, 0x01, 0xc2, 0x59, 0x9d, 0x4e, 0xad, 0xdf, 0xd3, 0x84, 0x9d, 0xf9, 0xd5, 0x99, 0x38, 0xfd, 0x8f, 0x16, 0x56, 0x47, 0x77, 0x32, 0x66, 0x80, 0x66, 0xff, 0xa1, 0x2e, 0xb3, - 0x47, 0xea, 0xb4, 0x7b, 0x9c, + 0x47, 0xea, 0xb4, 0x7b, ]; - logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0).unwrap(); + let b = logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0, 1).unwrap(); + assert_ne!(b, 0); - let result = &vec![0u8; 65]; - logic.read_register(0, result.as_ptr() as _).expect("OK"); + let result = &vec![0u8; 64]; + logic.read_register(1, result.as_ptr() as _).expect("OK"); assert_eq!(result.to_vec(), signer); assert_costs(map! { @@ -593,11 +594,11 @@ fn test_ecrecover() { ExtCosts::read_memory_base: 2, ExtCosts::read_memory_byte: 97, ExtCosts::write_memory_base: 1, - ExtCosts::write_memory_byte: 65, + ExtCosts::write_memory_byte: 64, ExtCosts::read_register_base: 1, - ExtCosts::read_register_byte: 65, + ExtCosts::read_register_byte: 64, ExtCosts::write_register_base: 1, - ExtCosts::write_register_byte: 65, + ExtCosts::write_register_byte: 64, ExtCosts::ecrecover_base: 1, }); } diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index e95e5cdd11c..58fc9659517 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -222,7 +222,7 @@ wrapped_imports! { keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ecrecover<[hash_ptr: u64, sig_ptr: u64, register_id: u64] -> [u64]>, + ecrecover<[hash_ptr: u64, sig_ptr: u64, malleability_flag: u8, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### From 7f3114b1d01877085d83ddbee9042189dc9b645d Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 02:34:12 +0700 Subject: [PATCH 091/134] Improve code quality by using U256 --- Cargo.lock | 1 + core/crypto/Cargo.toml | 1 + core/crypto/src/signature.rs | 41 ++++++++++++++++++------------------ 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d053f68e4d0..4817e402279 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3178,6 +3178,7 @@ dependencies = [ "curve25519-dalek", "derive_more", "ed25519-dalek", + "ethereum-types 0.11.0", "hex-literal", "lazy_static", "libc", diff --git a/core/crypto/Cargo.toml b/core/crypto/Cargo.toml index 924c9089dce..471ad4e6fce 100644 --- a/core/crypto/Cargo.toml +++ b/core/crypto/Cargo.toml @@ -13,6 +13,7 @@ c2-chacha = "0.3" curve25519-dalek = "3" derive_more = "0.99.9" ed25519-dalek = "1" +ethereum-types = "0.11.0" lazy_static = "1.4" libc = "0.2" parity-secp256k1 = "0.7" diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index af313624214..47bfacebc63 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -11,6 +11,7 @@ use lazy_static::lazy_static; use rand_core::OsRng; use secp256k1::Message; use serde::{Deserialize, Serialize}; +use ethereum_types::U256; lazy_static! { pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); @@ -568,39 +569,37 @@ impl Secp256K1Signature { } pub fn check_signature_values(&self) -> bool { - let r = &self.0[0..32]; - let s = &self.0[32..64]; + let mut r_bytes = [0u8; 32]; + r_bytes.copy_from_slice(&self.0[0..32]); + let r = U256::from(r_bytes); + + let mut s_bytes = [0u8; 32]; + s_bytes.copy_from_slice(&self.0[32..64]); + let s = U256::from(s_bytes); + let v = match self.check_v() { Ok(v) => v, Err(_e) => return false, }; - let big_one: [u8; 32] = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - ]; - if r < &big_one || s < &big_one { + let big_one = U256::one(); + if r < big_one || s < big_one { return false; } - // 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 / 2 - let secp256k1_half_n: [u8; 32] = [ - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x5d, 0x57, 0x6e, 0x73, 0x57, 0xa4, 0x50, 0x1d, 0xdf, 0xe9, 0x2f, 0x46, - 0x68, 0x1b, 0x20, 0xa0, - ]; + let secp256k1_n = U256::from([ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, + 0xd0, 0x36, 0x41, 0x41, + ]); + + let secp256k1_half_n = secp256k1_n / U256::from(2); // Reject upper range of s values (ECDSA malleability) - if s > &secp256k1_half_n { + if s > secp256k1_half_n { return false; } - // 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 - let secp256k1_n: [u8; 32] = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, - 0xd0, 0x36, 0x41, 0x41, - ]; - r < &secp256k1_n && s < &secp256k1_n && (v == 0 || v == 1) + r < secp256k1_n && s < secp256k1_n && (v == 0 || v == 1) } pub fn recover( From 434145b5135c644c4e0d239a41618c78b59dfbb0 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 16:18:39 +0700 Subject: [PATCH 092/134] Pass hash_bytes as ref --- core/crypto/src/signature.rs | 10 ++++++---- runtime/near-vm-logic/src/logic.rs | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 47bfacebc63..46f03bdc9f8 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -7,11 +7,11 @@ use std::str::FromStr; use borsh::{BorshDeserialize, BorshSerialize}; use ed25519_dalek::ed25519::signature::{Signature as _, Signer as _, Verifier as _}; +use ethereum_types::U256; use lazy_static::lazy_static; use rand_core::OsRng; use secp256k1::Message; use serde::{Deserialize, Serialize}; -use ethereum_types::U256; lazy_static! { pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); @@ -604,7 +604,7 @@ impl Secp256K1Signature { pub fn recover( &self, - msg: [u8; 32], + msg: impl AsRef<[u8]>, ) -> Result { let v = self.check_v()?; @@ -616,10 +616,12 @@ impl Secp256K1Signature { .map_err(|err| crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string(), })?; - let msg = Message::from(msg); + let msg = &Message::from_slice(msg.as_ref()).map_err(|err| { + crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string() } + })?; let res = SECP256K1 - .recover(&msg, &recoverable_sig) + .recover(msg, &recoverable_sig) .map_err(|err| crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string(), })? diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index f37cae487fd..29e4d2af67a 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1016,7 +1016,7 @@ impl<'a> VMLogic<'a> { let mut hash_bytes = [0u8; 32]; self.memory_get_into(hash_ptr, &mut hash_bytes)?; - if let Ok(pk) = signature.recover(hash_bytes) { + if let Ok(pk) = signature.recover(&hash_bytes) { self.internal_write_register(register_id, pk.as_ref().to_vec())?; return Ok(true as u64); }; From 9c281503ececd4295b166f6b4cbccab1a9b5ab28 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 16:18:39 +0700 Subject: [PATCH 093/134] Revert "Pass hash_bytes as ref" This reverts commit 434145b5135c644c4e0d239a41618c78b59dfbb0. --- core/crypto/src/signature.rs | 10 ++++------ runtime/near-vm-logic/src/logic.rs | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 46f03bdc9f8..47bfacebc63 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -7,11 +7,11 @@ use std::str::FromStr; use borsh::{BorshDeserialize, BorshSerialize}; use ed25519_dalek::ed25519::signature::{Signature as _, Signer as _, Verifier as _}; -use ethereum_types::U256; use lazy_static::lazy_static; use rand_core::OsRng; use secp256k1::Message; use serde::{Deserialize, Serialize}; +use ethereum_types::U256; lazy_static! { pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); @@ -604,7 +604,7 @@ impl Secp256K1Signature { pub fn recover( &self, - msg: impl AsRef<[u8]>, + msg: [u8; 32], ) -> Result { let v = self.check_v()?; @@ -616,12 +616,10 @@ impl Secp256K1Signature { .map_err(|err| crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string(), })?; + let msg = Message::from(msg); - let msg = &Message::from_slice(msg.as_ref()).map_err(|err| { - crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string() } - })?; let res = SECP256K1 - .recover(msg, &recoverable_sig) + .recover(&msg, &recoverable_sig) .map_err(|err| crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string(), })? diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 29e4d2af67a..f37cae487fd 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1016,7 +1016,7 @@ impl<'a> VMLogic<'a> { let mut hash_bytes = [0u8; 32]; self.memory_get_into(hash_ptr, &mut hash_bytes)?; - if let Ok(pk) = signature.recover(&hash_bytes) { + if let Ok(pk) = signature.recover(hash_bytes) { self.internal_write_register(register_id, pk.as_ref().to_vec())?; return Ok(true as u64); }; From 7f1c296404ac8cbf81e1769aff09fc5deb9cc173 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 18:50:52 +0700 Subject: [PATCH 094/134] matklad nit Co-authored-by: Aleksey Kladov --- core/crypto/src/signature.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 47bfacebc63..7e6543763fa 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -582,8 +582,7 @@ impl Secp256K1Signature { Err(_e) => return false, }; - let big_one = U256::one(); - if r < big_one || s < big_one { + if r.is_zero() || s.is_zero() { return false; } From 8c9341fe89506c030d56a02dafe8fae62e6eecbd Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 18:58:47 +0700 Subject: [PATCH 095/134] Fix ecrecover exports arg sig --- core/crypto/src/signature.rs | 2 +- runtime/runtime-params-estimator/test-contract/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 7e6543763fa..60acb34759f 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -7,11 +7,11 @@ use std::str::FromStr; use borsh::{BorshDeserialize, BorshSerialize}; use ed25519_dalek::ed25519::signature::{Signature as _, Signer as _, Verifier as _}; +use ethereum_types::U256; use lazy_static::lazy_static; use rand_core::OsRng; use secp256k1::Message; use serde::{Deserialize, Serialize}; -use ethereum_types::U256; lazy_static! { pub static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index dad04d191a3..ee40e870346 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -48,7 +48,7 @@ extern "C" { fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); - fn ecrecover(hash_ptr: u64, v: u32, r_ptr: u64, s_ptr: u64, register_id: u64); + fn ecrecover(hash_ptr: u64, sig_ptr: u64, malleability_flag: u8, register_id: u64); // ##################### // # Miscellaneous API # // ##################### From 0acaa6700500576bd116b6fb8bfa6c0b47833838 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 19:00:57 +0700 Subject: [PATCH 096/134] Move when malleability check happens --- runtime/near-vm-logic/src/logic.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index f37cae487fd..07beff65817 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1008,14 +1008,15 @@ impl<'a> VMLogic<'a> { self.memory_get_into(sig_ptr, &mut signature_bytes)?; let signature = Secp256K1Signature::from(signature_bytes); + let mut hash_bytes = [0u8; 32]; + self.memory_get_into(hash_ptr, &mut hash_bytes)?; + if malleability_flag == 1 { if !signature.check_signature_values() { return Ok(false as u64); } } - let mut hash_bytes = [0u8; 32]; - self.memory_get_into(hash_ptr, &mut hash_bytes)?; if let Ok(pk) = signature.recover(hash_bytes) { self.internal_write_register(register_id, pk.as_ref().to_vec())?; return Ok(true as u64); From 8bb840b720ddf675c27507c6342bdaae8fe2ba27 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 19:04:32 +0700 Subject: [PATCH 097/134] Remove last check in signature values Co-authored-by: Aleksey Kladov --- core/crypto/src/signature.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 60acb34759f..1475cf57b03 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -598,7 +598,7 @@ impl Secp256K1Signature { return false; } - r < secp256k1_n && s < secp256k1_n && (v == 0 || v == 1) + r < secp256k1_n && s < secp256k1_n } pub fn recover( From bea8361770956e0f8f6f844d56abb94c223b2e74 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 19:08:49 +0700 Subject: [PATCH 098/134] Don't use `v` in a check, now unused --- core/crypto/src/signature.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 1475cf57b03..f0cd14cbc33 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -577,7 +577,7 @@ impl Secp256K1Signature { s_bytes.copy_from_slice(&self.0[32..64]); let s = U256::from(s_bytes); - let v = match self.check_v() { + let _v = match self.check_v() { Ok(v) => v, Err(_e) => return false, }; From 211db82e13b6b72b1d640552c492c2d4966a9ad9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Mon, 21 Jun 2021 19:09:05 +0700 Subject: [PATCH 099/134] Update description of ripemd160 with correct cost --- runtime/near-vm-logic/src/logic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 07beff65817..f3a2db26b46 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -961,7 +961,7 @@ impl<'a> VMLogic<'a> { /// /// # Cost /// - /// Where `message_blocks` is `max(message_len / 8, 1)`. + /// Where `message_blocks` is `(value_len + 9).div_ceil(64)`. /// /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks` pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { From f6d566aa60ac8d358dded6410584a79748360efe Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 15:07:35 -0400 Subject: [PATCH 100/134] Use u32 for malleability_flag --- runtime/near-vm-logic/src/logic.rs | 2 +- runtime/near-vm-runner/src/imports.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index f3a2db26b46..3ba1cb0dd18 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -999,7 +999,7 @@ impl<'a> VMLogic<'a> { &mut self, hash_ptr: u64, sig_ptr: u64, - malleability_flag: u8, + malleability_flag: u32, register_id: u64, ) -> Result { self.gas_counter.pay_base(ecrecover_base)?; diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 58fc9659517..48578ef5209 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -222,7 +222,7 @@ wrapped_imports! { keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ecrecover<[hash_ptr: u64, sig_ptr: u64, malleability_flag: u8, register_id: u64] -> [u64]>, + ecrecover<[hash_ptr: u64, sig_ptr: u64, malleability_flag: u32, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### From 3f08a35fa65f1a24be2fb46f6d72ca1b5c587a3b Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 16:18:09 -0400 Subject: [PATCH 101/134] Introduce protocol_feature_math_extension --- core/primitives-core/Cargo.toml | 1 + core/primitives-core/src/config.rs | 15 +++++++++++++++ core/primitives/Cargo.toml | 3 ++- core/primitives/src/version.rs | 4 ++++ nearcore/Cargo.toml | 3 ++- runtime/near-vm-logic/Cargo.toml | 1 + runtime/near-vm-logic/src/logic.rs | 3 +++ runtime/near-vm-logic/tests/test_miscs.rs | 2 ++ runtime/near-vm-runner/Cargo.toml | 4 ++++ runtime/near-vm-runner/src/imports.rs | 4 ++-- runtime/runtime-params-estimator/Cargo.toml | 7 ++++++- runtime/runtime-params-estimator/src/cases.rs | 12 +++++++++--- .../src/ext_costs_generator.rs | 9 ++++++--- .../test-contract/Cargo.toml | 1 + .../test-contract/src/lib.rs | 5 +++++ 15 files changed, 63 insertions(+), 11 deletions(-) diff --git a/core/primitives-core/Cargo.toml b/core/primitives-core/Cargo.toml index 1694b3d0e35..e6cc9307a1b 100644 --- a/core/primitives-core/Cargo.toml +++ b/core/primitives-core/Cargo.toml @@ -28,3 +28,4 @@ protocol_feature_evm = [] protocol_feature_add_account_versions = [] protocol_feature_alt_bn128 = [] protocol_feature_tx_size_limit = [] +protocol_feature_math_extension = [] diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 396b0e8d46e..c192a93c5d2 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -223,11 +223,14 @@ pub struct ExtCostsConfig { /// Cost of getting sha256 per byte pub keccak512_byte: Gas, + #[cfg(feature = "protocol_feature_math_extension")] /// Cost of getting ripemd160 base pub ripemd160_base: Gas, + #[cfg(feature = "protocol_feature_math_extension")] /// Cost of getting ripemd160 per message block pub ripemd160_block: Gas, + #[cfg(feature = "protocol_feature_math_extension")] /// Cost of calling ecrecover pub ecrecover_base: Gas, @@ -361,8 +364,11 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base: SAFETY_MULTIPLIER * 15136567500, // 10 x sha256_base + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block: SAFETY_MULTIPLIER * 80391170 * 8, // 10 x sha256_byte x 8 bytes + #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base: SAFETY_MULTIPLIER * 75682837500, // 50 x sha256_base log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -434,8 +440,11 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base: 0, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block: 0, + #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -508,8 +517,11 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block, + #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base, log_base, log_byte, @@ -635,8 +647,11 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base => config.ripemd160_base, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block => config.ripemd160_block, + #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index c6bff6cbf26..4ac93c4342d 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -50,7 +50,8 @@ protocol_feature_allow_create_account_on_delete = [] protocol_feature_fix_storage_usage = [] protocol_feature_restore_receipts_after_fix = [] protocol_feature_cap_max_gas_price = [] -nightly_protocol_features = ["nightly_protocol", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "protocol_feature_fix_storage_usage", "protocol_feature_restore_receipts_after_fix", "protocol_feature_cap_max_gas_price"] +protocol_feature_math_extension = ["near-primitives-core/protocol_feature_math_extension"] +nightly_protocol_features = ["nightly_protocol", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "protocol_feature_fix_storage_usage", "protocol_feature_restore_receipts_after_fix", "protocol_feature_cap_max_gas_price", "protocol_feature_math_extension"] nightly_protocol = [] [dev-dependencies] diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index 385ca748fd1..709db564b36 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -107,6 +107,8 @@ pub enum ProtocolFeature { RestoreReceiptsAfterFix, #[cfg(feature = "protocol_feature_cap_max_gas_price")] CapMaxGasPrice, + #[cfg(feature = "protocol_feature_math_extension")] + MathExtension, } /// Current latest stable version of the protocol. @@ -149,6 +151,8 @@ impl ProtocolFeature { ProtocolFeature::RestoreReceiptsAfterFix => 112, #[cfg(feature = "protocol_feature_cap_max_gas_price")] ProtocolFeature::CapMaxGasPrice => 113, + #[cfg(feature = "protocol_feature_math_extension")] + ProtocolFeature::MathExtension => 114, } } } diff --git a/nearcore/Cargo.toml b/nearcore/Cargo.toml index 98d8a605366..d8238abdf34 100644 --- a/nearcore/Cargo.toml +++ b/nearcore/Cargo.toml @@ -68,10 +68,11 @@ protocol_feature_add_account_versions = ["near-primitives/protocol_feature_add_a protocol_feature_tx_size_limit = ["near-primitives/protocol_feature_tx_size_limit", "node-runtime/protocol_feature_tx_size_limit"] protocol_feature_allow_create_account_on_delete = ["node-runtime/protocol_feature_allow_create_account_on_delete"] protocol_feature_fix_storage_usage = ["near-primitives/protocol_feature_fix_storage_usage", "node-runtime/protocol_feature_fix_storage_usage"] -nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "protocol_feature_fix_storage_usage", "protocol_feature_restore_receipts_after_fix", "protocol_feature_cap_max_gas_price"] +nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "protocol_feature_fix_storage_usage", "protocol_feature_restore_receipts_after_fix", "protocol_feature_cap_max_gas_price", "protocol_feature_math_extension"] nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"] protocol_feature_restore_receipts_after_fix = ["near-primitives/protocol_feature_restore_receipts_after_fix", "near-chain/protocol_feature_restore_receipts_after_fix", "node-runtime/protocol_feature_restore_receipts_after_fix"] protocol_feature_cap_max_gas_price = ["near-primitives/protocol_feature_cap_max_gas_price", "near-chain/protocol_feature_cap_max_gas_price"] +protocol_feature_math_extension = ["near-primitives/protocol_feature_math_extension"] # enable this to build neard with wasmer 1.0 runner # now if none of wasmer0_default, wasmer1_default or wasmtime_default is enabled, wasmer0 would be default diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index c5230760756..49992aed1f5 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -39,6 +39,7 @@ default = [] protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] +protocol_feature_math_extension = ["near-primitives/protocol_feature_math_extension"] # Use this feature to enable counting of fees and costs applied. costs_counting = [] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 3ba1cb0dd18..c6cdbf521d4 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -5,6 +5,7 @@ use crate::types::{PromiseIndex, PromiseResult, ReceiptIndex, ReturnData}; use crate::utils::split_method_names; use crate::ValuePtr; use byteorder::ByteOrder; +#[cfg(feature = "protocol_feature_math_extension")] use near_crypto::Secp256K1Signature; use near_primitives::checked_feature; use near_primitives::version::is_implicit_account_creation_enabled; @@ -964,6 +965,7 @@ impl<'a> VMLogic<'a> { /// Where `message_blocks` is `(value_len + 9).div_ceil(64)`. /// /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks` + #[cfg(feature = "protocol_feature_math_extension")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { use num_integer::Integer; @@ -995,6 +997,7 @@ impl<'a> VMLogic<'a> { /// # Cost /// /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` + #[cfg(feature = "protocol_feature_math_extension")] pub fn ecrecover( &mut self, hash_ptr: u64, diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 24c0aebc1e9..32159d25768 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -530,6 +530,7 @@ fn test_keccak512() { }); } +#[cfg(feature = "protocol_feature_math_extension")] #[test] fn test_ripemd160() { let mut logic_builder = VMLogicBuilder::default(); @@ -559,6 +560,7 @@ fn test_ripemd160() { }); } +#[cfg(feature = "protocol_feature_math_extension")] #[test] fn test_ecrecover() { let mut logic_builder = VMLogicBuilder::default(); diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index a6b495a478b..7a4dede4f30 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -65,6 +65,10 @@ protocol_feature_alt_bn128 = [ "near-primitives/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128" ] +protocol_feature_math_extension = [ + "near-vm-logic/protocol_feature_math_extension", + "near-primitives/protocol_feature_math_extension" +] [package.metadata.cargo-udeps.ignore] # `no_cache` feature leads to an unused `cached` crate diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 48578ef5209..2e214f0517a 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -221,8 +221,8 @@ wrapped_imports! { sha256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - ecrecover<[hash_ptr: u64, sig_ptr: u64, malleability_flag: u32, register_id: u64] -> [u64]>, + #["protocol_feature_math_extension", MathExtension] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, + #["protocol_feature_math_extension", MathExtension] ecrecover<[hash_ptr: u64, sig_ptr: u64, malleability_flag: u32, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index a07d54b716c..bd956c3e0ba 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -70,4 +70,9 @@ protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-primitives/protocol_feature_evm", "testlib/protocol_feature_evm"] -sandbox = ["node-runtime/sandbox", "state-viewer/sandbox"] \ No newline at end of file +sandbox = ["node-runtime/sandbox", "state-viewer/sandbox"] +protocol_feature_math_extension = [ + "near-vm-logic/protocol_feature_math_extension", + "near-vm-runner/protocol_feature_math_extension", + "nearcore/protocol_feature_math_extension", +] \ No newline at end of file diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 10b0dc1054f..f683a46405c 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -198,8 +198,11 @@ pub enum Metric { keccak256_10kib_10k, keccak512_10b_10k, keccak512_10kib_10k, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_10b_10k, + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_10kib_10k, + #[cfg(feature = "protocol_feature_math_extension")] ecrecover_10k, #[cfg(feature = "protocol_feature_alt_bn128")] alt_bn128_g1_multiexp_1_1k, @@ -581,9 +584,9 @@ pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeCon keccak256_10kib_10k => keccak256_10kib_10k, keccak512_10b_10k => keccak512_10b_10k, keccak512_10kib_10k => keccak512_10kib_10k, - ripemd160_10b_10k => ripemd160_10b_10k, - ripemd160_10kib_10k => ripemd160_10kib_10k, - ecrecover_10k => ecrecover_10k, + #["protocol_feature_math_extension"] ripemd160_10b_10k => ripemd160_10b_10k, + #["protocol_feature_math_extension"] ripemd160_10kib_10k => ripemd160_10kib_10k, + #["protocol_feature_math_extension"] ecrecover_10k => ecrecover_10k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_1_1k => alt_bn128_g1_multiexp_1_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_multiexp_10_1k => alt_bn128_g1_multiexp_10_1k, #["protocol_feature_alt_bn128"] alt_bn128_g1_sum_1_1k => alt_bn128_g1_sum_1_1k, @@ -766,8 +769,11 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), + #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block: measured_to_gas(metric, &measured, ripemd160_block), + #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), diff --git a/runtime/runtime-params-estimator/src/ext_costs_generator.rs b/runtime/runtime-params-estimator/src/ext_costs_generator.rs index e9031c5504c..bb9ad9aeb2d 100644 --- a/runtime/runtime-params-estimator/src/ext_costs_generator.rs +++ b/runtime/runtime-params-estimator/src/ext_costs_generator.rs @@ -65,10 +65,13 @@ impl ExtCostsGenerator { self.extract(keccak512_10b_10k, keccak512_base); self.extract(keccak512_10kib_10k, keccak512_byte); - self.extract(ripemd160_10b_10k, ripemd160_base); - self.extract(ripemd160_10kib_10k, ripemd160_block); + #[cfg(feature = "protocol_feature_math_extension")] + { + self.extract(ripemd160_10b_10k, ripemd160_base); + self.extract(ripemd160_10kib_10k, ripemd160_block); - self.extract(ecrecover_10k, ecrecover_base); + self.extract(ecrecover_10k, ecrecover_base); + } #[cfg(feature = "protocol_feature_alt_bn128")] { diff --git a/runtime/runtime-params-estimator/test-contract/Cargo.toml b/runtime/runtime-params-estimator/test-contract/Cargo.toml index 5199091d0fb..e3ae9758de3 100644 --- a/runtime/runtime-params-estimator/test-contract/Cargo.toml +++ b/runtime/runtime-params-estimator/test-contract/Cargo.toml @@ -22,5 +22,6 @@ members = [] nightly_protocol_features = ["protocol_feature_alt_bn128", "protocol_feature_evm"] protocol_feature_alt_bn128 = [] protocol_feature_evm = [] +protocol_feature_math_extension = [] payload = [] diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index ee40e870346..9442b2cbc0e 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -47,7 +47,9 @@ extern "C" { fn sha256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak256(value_len: u64, value_ptr: u64, register_id: u64); fn keccak512(value_len: u64, value_ptr: u64, register_id: u64); + #[cfg(feature = "protocol_feature_math_extension")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); + #[cfg(feature = "protocol_feature_math_extension")] fn ecrecover(hash_ptr: u64, sig_ptr: u64, malleability_flag: u8, register_id: u64); // ##################### // # Miscellaneous API # @@ -430,6 +432,7 @@ pub unsafe fn keccak512_10kib_10k() { // and `write_register_byte`. However `ripemd160` computation is more expensive than register writing // so we are okay overcharging it. // Compute ripemd160 on 10b 10k times. +#[cfg(feature = "protocol_feature_math_extension")] #[no_mangle] pub unsafe fn ripemd160_10b_10k() { let buffer = [65u8; 10]; @@ -441,6 +444,7 @@ pub unsafe fn ripemd160_10b_10k() { // and `write_register_byte`. However `ripemd160` computation is more expensive than register writing // so we are okay overcharging it. // Compute ripemd160 on 10kib 10k times. +#[cfg(feature = "protocol_feature_math_extension")] #[no_mangle] pub unsafe fn ripemd160_10kib_10k() { let buffer = [65u8; 10240]; @@ -453,6 +457,7 @@ pub unsafe fn ripemd160_10kib_10k() { // `write_register_byte`. However `ecrecover` computation is more expensive than register writing // so we are okay overcharging it. // Compute ecrecover 10k times. +#[cfg(feature = "protocol_feature_math_extension")] #[no_mangle] pub unsafe fn ecrecover_10k() { let hash = [0u8; 32]; From 4ceab9927161613027b27789100e2a5d29a87112 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 16:48:01 -0400 Subject: [PATCH 102/134] Use our own div_ceil implementation --- Cargo.lock | 1 - runtime/near-vm-logic/Cargo.toml | 1 - runtime/near-vm-logic/src/logic.rs | 23 +++++++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4817e402279..44e10cf4cc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3639,7 +3639,6 @@ dependencies = [ "near-primitives-core", "near-runtime-utils", "near-vm-errors", - "num-integer", "ripemd160", "serde", "serde_json", diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 49992aed1f5..6c85b91f53e 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -17,7 +17,6 @@ base64 = "0.13" borsh = "0.8.1" bs58 = "0.4" byteorder = "1.2" -num-integer = "0.1" ripemd160 = "0.9.0" serde = { version = "1", features = ["derive"] } sha2 = ">=0.8,<0.10" diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index c6cdbf521d4..e56054109c4 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -967,14 +967,16 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks` #[cfg(feature = "protocol_feature_math_extension")] pub fn ripemd160(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result<()> { - use num_integer::Integer; - self.gas_counter.pay_base(ripemd160_base)?; let value = self.get_vec_from_memory_or_register(value_ptr, value_len)?; - let message_blocks = (value_len + 9).div_ceil(&64); + let message_blocks = value + .len() + .checked_add(9) + .and_then(|x| Self::div_ceil(x, 64)) + .ok_or(VMLogicError::HostError(HostError::IntegerOverflow))?; - self.gas_counter.pay_per(ripemd160_block, message_blocks)?; + self.gas_counter.pay_per(ripemd160_block, message_blocks as u64)?; use ripemd160::Digest; @@ -982,6 +984,19 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } + /// Returns x / y rounding up to the nearest integer. If the computation overflows + /// or the denominator is 0 then `None` is returned. + fn div_ceil(x: usize, y: usize) -> Option { + let d = x.checked_div(y)?; + let m = x.checked_rem(y)?; + + if m == 0 { + Some(d) + } else { + d.checked_add(1) + } + } + /// Recovers an ECDSA signer address and returns it into `register_id`. /// /// Takes in an additional flag to check for malleability of the signature From 884d714d19a36e12f99e9a649b98a138976c14fe Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 16:54:25 -0400 Subject: [PATCH 103/134] Include protocol_feature_math_extension in runtime-params-estimator/nightly_protocol_features --- runtime/runtime-params-estimator/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index bd956c3e0ba..481098985cf 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -56,7 +56,7 @@ no_cache = ["node-runtime/no_cache", "near-store/no_cache"] wasmtime = ["near-vm-runner/wasmtime_default"] lightbeam = ["wasmtime", "near-vm-runner/lightbeam"] nightly_protocol = ["near-primitives/nightly_protocol"] -nightly_protocol_features = ["protocol_feature_alt_bn128", "protocol_feature_evm"] +nightly_protocol_features = ["protocol_feature_alt_bn128", "protocol_feature_evm", "protocol_feature_math_extension"] protocol_feature_alt_bn128 = [ "near-vm-logic/protocol_feature_alt_bn128", "near-vm-runner/protocol_feature_alt_bn128", From 402fa8f61717cd3ff1bf0dba52d3113a0e81f5d8 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 20:59:50 +0000 Subject: [PATCH 104/134] Nightly protocol version bump --- core/primitives/src/version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index 709db564b36..97c23994810 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -119,7 +119,7 @@ pub const PROTOCOL_VERSION: ProtocolVersion = 45; /// Current latest nightly version of the protocol. #[cfg(feature = "nightly_protocol")] -pub const PROTOCOL_VERSION: ProtocolVersion = 113; +pub const PROTOCOL_VERSION: ProtocolVersion = 114; impl ProtocolFeature { pub const fn protocol_version(self) -> ProtocolVersion { From aa1b8c5321594be675a28eedab1679759523689b Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 21:20:19 +0000 Subject: [PATCH 105/134] Simplify message_blocks computation --- runtime/near-vm-logic/src/logic.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index e56054109c4..b2fe3b182f8 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -972,9 +972,10 @@ impl<'a> VMLogic<'a> { let message_blocks = value .len() - .checked_add(9) - .and_then(|x| Self::div_ceil(x, 64)) - .ok_or(VMLogicError::HostError(HostError::IntegerOverflow))?; + .checked_add(8) + .ok_or(VMLogicError::HostError(HostError::IntegerOverflow))? + / 64 + + 1; self.gas_counter.pay_per(ripemd160_block, message_blocks as u64)?; From 1ec6416efb9f6b62299aa170524561b4d35cbf4d Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 23 Jun 2021 21:22:25 +0000 Subject: [PATCH 106/134] Remove unused div_ceil function --- runtime/near-vm-logic/src/logic.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index b2fe3b182f8..41487208655 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -985,19 +985,6 @@ impl<'a> VMLogic<'a> { self.internal_write_register(register_id, value_hash.as_slice().to_vec()) } - /// Returns x / y rounding up to the nearest integer. If the computation overflows - /// or the denominator is 0 then `None` is returned. - fn div_ceil(x: usize, y: usize) -> Option { - let d = x.checked_div(y)?; - let m = x.checked_rem(y)?; - - if m == 0 { - Some(d) - } else { - d.checked_add(1) - } - } - /// Recovers an ECDSA signer address and returns it into `register_id`. /// /// Takes in an additional flag to check for malleability of the signature From b572bdcbf2254df20de8f0f8f47762ac97901c0e Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 17:13:51 +0700 Subject: [PATCH 107/134] Ignore first byte of result --- core/crypto/src/signature.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index f0cd14cbc33..01378bfc43a 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -624,7 +624,7 @@ impl Secp256K1Signature { })? .serialize_vec(&SECP256K1, false); - let pk = Secp256K1PublicKey::try_from(&res[0..64]).map_err(|err| { + let pk = Secp256K1PublicKey::try_from(&res[1..65]).map_err(|err| { crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string() } })?; From a7ee788e4174f19c0cf2ab50fe0b425731aa6ddc Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 16:55:40 +0700 Subject: [PATCH 108/134] Remove uneeded return at end of function Co-authored-by: EgorKulikov --- runtime/near-vm-logic/src/logic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 41487208655..6a70dccb2eb 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1028,7 +1028,7 @@ impl<'a> VMLogic<'a> { return Ok(true as u64); }; - return Ok(false as u64); + Ok(false as u64) } /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. From 1f2a3141f83913957822ab45e4f421405519871f Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 17:15:09 +0700 Subject: [PATCH 109/134] Remove check_v and add in option to skip reject upper range --- core/crypto/src/signature.rs | 44 ++++++++++-------------------- runtime/near-vm-logic/src/logic.rs | 10 +++++-- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 01378bfc43a..ea5548574ef 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -559,16 +559,7 @@ impl<'de> serde::Deserialize<'de> for SecretKey { pub struct Secp256K1Signature([u8; 65]); impl Secp256K1Signature { - fn check_v(&self) -> Result { - match self.0[64] { - 27 | 28 => Ok(self.0[64] - 27), - _ => Err(crate::errors::ParseSignatureError::InvalidData { - error_message: "invalid `v` value".to_string(), - }), - } - } - - pub fn check_signature_values(&self) -> bool { + pub fn check_signature_values(&self, reject_upper: bool) -> bool { let mut r_bytes = [0u8; 32]; r_bytes.copy_from_slice(&self.0[0..32]); let r = U256::from(r_bytes); @@ -577,11 +568,6 @@ impl Secp256K1Signature { s_bytes.copy_from_slice(&self.0[32..64]); let s = U256::from(s_bytes); - let _v = match self.check_v() { - Ok(v) => v, - Err(_e) => return false, - }; - if r.is_zero() || s.is_zero() { return false; } @@ -592,10 +578,12 @@ impl Secp256K1Signature { 0xd0, 0x36, 0x41, 0x41, ]); - let secp256k1_half_n = secp256k1_n / U256::from(2); - // Reject upper range of s values (ECDSA malleability) - if s > secp256k1_half_n { - return false; + if reject_upper { + let secp256k1_half_n = secp256k1_n / U256::from(2); + // Reject upper range of s values (ECDSA malleability) + if s > secp256k1_half_n { + return false; + } } r < secp256k1_n && s < secp256k1_n @@ -605,16 +593,14 @@ impl Secp256K1Signature { &self, msg: [u8; 32], ) -> Result { - let v = self.check_v()?; - - // This can't fail because of the check above. It will fall in range. - let recover_id = secp256k1::RecoveryId::from_i32(i32::from(v)).unwrap(); - - let recoverable_sig = - secp256k1::RecoverableSignature::from_compact(&SECP256K1, &self.0[0..64], recover_id) - .map_err(|err| crate::errors::ParseSignatureError::InvalidData { - error_message: err.to_string(), - })?; + let recoverable_sig = secp256k1::RecoverableSignature::from_compact( + &SECP256K1, + &self.0[0..64], + secp256k1::RecoveryId::from_i32(i32::from(signature.0[64])).unwrap(), + ) + .map_err(|err| crate::errors::ParseSignatureError::InvalidData { + error_message: err.to_string(), + })?; let msg = Message::from(msg); let res = SECP256K1 diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 6a70dccb2eb..824113924d2 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -992,6 +992,12 @@ impl<'a> VMLogic<'a> { /// /// Returns a bool indicating success or failure as a `u64`. /// + /// # Malleability Flags + /// + /// 0 - No malleability check. + /// 1 - Check malleability. + /// 2 - Rejecting upper range. + /// /// # Errors /// /// * If `hash_ptr`, `r_ptr`, or `s_ptr` point outside the memory or the registers use more @@ -1017,8 +1023,8 @@ impl<'a> VMLogic<'a> { let mut hash_bytes = [0u8; 32]; self.memory_get_into(hash_ptr, &mut hash_bytes)?; - if malleability_flag == 1 { - if !signature.check_signature_values() { + if (malleability_flag & 1) == 1 { + if !signature.check_signature_values((malleability_flag & 2) == 2) { return Ok(false as u64); } } From 1405c9197f285352315c152409d2d1b4d89abce9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 17:50:19 +0700 Subject: [PATCH 110/134] Use `get_vec_from_memory_or_register` over `memory_get_into` --- runtime/near-vm-logic/src/logic.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 824113924d2..16be03d0cff 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1018,10 +1018,20 @@ impl<'a> VMLogic<'a> { let mut signature_bytes = [0u8; 65]; self.memory_get_into(sig_ptr, &mut signature_bytes)?; - let signature = Secp256K1Signature::from(signature_bytes); - let mut hash_bytes = [0u8; 32]; - self.memory_get_into(hash_ptr, &mut hash_bytes)?; + let signature = { + let vec = self.get_vec_from_memory_or_register(sig_ptr, 65)?; + let mut bytes = [0u8; 65]; + bytes.copy_from_slice(&vec); + Secp256K1Signature::from(bytes) + }; + + let hash = { + let vec = self.get_vec_from_memory_or_register(hash_ptr, 32)?; + let mut bytes = [0u8; 32]; + bytes.copy_from_slice(&vec); + bytes + }; if (malleability_flag & 1) == 1 { if !signature.check_signature_values((malleability_flag & 2) == 2) { @@ -1029,7 +1039,7 @@ impl<'a> VMLogic<'a> { } } - if let Ok(pk) = signature.recover(hash_bytes) { + if let Ok(pk) = signature.recover(hash) { self.internal_write_register(register_id, pk.as_ref().to_vec())?; return Ok(true as u64); }; From 8c3de8a849930f28c1ead3957d2e3f93d9d532f8 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 17:54:23 +0700 Subject: [PATCH 111/134] Remove unused --- runtime/near-vm-logic/src/logic.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 16be03d0cff..4e3496fff0d 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1016,9 +1016,6 @@ impl<'a> VMLogic<'a> { ) -> Result { self.gas_counter.pay_base(ecrecover_base)?; - let mut signature_bytes = [0u8; 65]; - self.memory_get_into(sig_ptr, &mut signature_bytes)?; - let signature = { let vec = self.get_vec_from_memory_or_register(sig_ptr, 65)?; let mut bytes = [0u8; 65]; From 3c4144b2146cd241e4425f126322c65f663112b9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 18:15:05 +0700 Subject: [PATCH 112/134] Separate `v`, change args to `u64` --- runtime/near-vm-errors/Cargo.toml | 1 + runtime/near-vm-errors/src/lib.rs | 4 ++++ runtime/near-vm-logic/Cargo.toml | 2 +- runtime/near-vm-logic/src/logic.rs | 20 +++++++++++++++---- .../test-contract/src/lib.rs | 2 +- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/runtime/near-vm-errors/Cargo.toml b/runtime/near-vm-errors/Cargo.toml index e186a7830da..5c0249372ee 100644 --- a/runtime/near-vm-errors/Cargo.toml +++ b/runtime/near-vm-errors/Cargo.toml @@ -22,6 +22,7 @@ near-rpc-error-macro = { path = "../../tools/rpctypegen/macro", version = "0.1.0 [features] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] +protocol_feature_math_extension = [] protocol_feature_alt_bn128 = [] [package.metadata.workspaces] diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 9311eb01030..fe93cfa38e1 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -212,6 +212,8 @@ pub enum HostError { /// Serialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128SerializationError { msg: String }, + #[cfg(feature = "protocol_feature_math_extension")] + InvalidECRecoverVByte { value: u64 }, } /// Errors specifically from native EVM. @@ -498,6 +500,8 @@ impl std::fmt::Display for HostError { AltBn128DeserializationError { msg } => write!(f, "AltBn128 deserialization error: {}", msg), #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128SerializationError { msg } => write!(f, "AltBn128 serialization error: {}", msg), + #[cfg(feature = "protocol_feature_math_extension")] + InvalidECRecoverVByte { value } => write!(f, "V recovery byte 0 through 3 are valid but was provided {}", value), } } } diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 6c85b91f53e..853dae947d5 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -38,7 +38,7 @@ default = [] protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"] protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"] protocol_feature_allow_create_account_on_delete = [] -protocol_feature_math_extension = ["near-primitives/protocol_feature_math_extension"] +protocol_feature_math_extension = ["near-primitives/protocol_feature_math_extension", "near-vm-errors/protocol_feature_math_extension"] # Use this feature to enable counting of fees and costs applied. costs_counting = [] diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 4e3496fff0d..6b9663da617 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1011,16 +1011,28 @@ impl<'a> VMLogic<'a> { &mut self, hash_ptr: u64, sig_ptr: u64, - malleability_flag: u32, + v: u64, + malleability_flag: u64, register_id: u64, ) -> Result { self.gas_counter.pay_base(ecrecover_base)?; let signature = { - let vec = self.get_vec_from_memory_or_register(sig_ptr, 65)?; + let vec = self.get_vec_from_memory_or_register(sig_ptr, 64)?; let mut bytes = [0u8; 65]; - bytes.copy_from_slice(&vec); - Secp256K1Signature::from(bytes) + bytes[0..64].copy_from_slice(&vec); + + match v { + 0 | 1 | 2 | 3 => { + bytes[65] = v as u8; + Secp256K1Signature::from(bytes) + } + _ => { + return Err(VMLogicError::HostError(HostError::InvalidECRecoverVByte { + value: v as u64, + })) + } + } }; let hash = { diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 9442b2cbc0e..4a2ec29a850 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -50,7 +50,7 @@ extern "C" { #[cfg(feature = "protocol_feature_math_extension")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); #[cfg(feature = "protocol_feature_math_extension")] - fn ecrecover(hash_ptr: u64, sig_ptr: u64, malleability_flag: u8, register_id: u64); + fn ecrecover(hash_ptr: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64); // ##################### // # Miscellaneous API # // ##################### From 395ad5391bba0c2ec3f89ff190dcf638a69780a9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 18:20:37 +0700 Subject: [PATCH 113/134] Remove redundant check --- core/crypto/src/signature.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index ea5548574ef..69dc8225174 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -568,10 +568,6 @@ impl Secp256K1Signature { s_bytes.copy_from_slice(&self.0[32..64]); let s = U256::from(s_bytes); - if r.is_zero() || s.is_zero() { - return false; - } - let secp256k1_n = U256::from([ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, From 20252a1e642f3ed8c5c5cb4447628ab8bd2cecd7 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 21:47:51 +0700 Subject: [PATCH 114/134] 64th byte, not 65 Co-authored-by: Aleksey Kladov --- runtime/near-vm-logic/src/logic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 6b9663da617..916f52b5729 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1024,7 +1024,7 @@ impl<'a> VMLogic<'a> { match v { 0 | 1 | 2 | 3 => { - bytes[65] = v as u8; + bytes[64] = v as u8; Secp256K1Signature::from(bytes) } _ => { From 2e4742ecc1bc7fd4e8cba1f4c310e88caceccbcc Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 21:52:41 +0700 Subject: [PATCH 115/134] Fix test --- runtime/near-vm-logic/tests/test_miscs.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 32159d25768..98fd1616e8b 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -569,22 +569,22 @@ fn test_ecrecover() { // See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/cryptography/ECDSA.test.js use sha3::Digest; let hash = sha3::Keccak256::digest(b"OpenZeppelin"); - let signature: [u8; 65] = [ + let signature: [u8; 64] = [ 0x5d, 0x99, 0xb6, 0xf7, 0xf6, 0xd1, 0xf7, 0x3d, 0x1a, 0x26, 0x49, 0x7f, 0x2b, 0x1c, 0x89, 0xb2, 0x4c, 0x09, 0x93, 0x91, 0x3f, 0x86, 0xe9, 0xa2, 0xd0, 0x2c, 0xd6, 0x98, 0x87, 0xd9, 0xc9, 0x4f, 0x3c, 0x88, 0x03, 0x58, 0x57, 0x9d, 0x81, 0x1b, 0x21, 0xdd, 0x1b, 0x7f, 0xd9, 0xbb, 0x01, 0xc1, 0xd8, 0x1d, 0x10, 0xe6, 0x9f, 0x03, 0x84, 0xe6, 0x75, 0xc3, 0x2b, 0x39, - 0x64, 0x3b, 0xe8, 0x92, 0x1b, + 0x64, 0x3b, 0xe8, 0x92, ]; let signer: [u8; 64] = [ - 0x04, 0xb3, 0x68, 0x70, 0xea, 0xab, 0x31, 0xcb, 0xeb, 0x1a, 0x5c, 0x07, 0x46, 0x7b, 0x42, - 0x97, 0x40, 0x7c, 0x62, 0x11, 0x7a, 0x31, 0x15, 0x47, 0xc4, 0x30, 0x5e, 0x14, 0x71, 0x52, - 0x1b, 0x53, 0x01, 0xc2, 0x59, 0x9d, 0x4e, 0xad, 0xdf, 0xd3, 0x84, 0x9d, 0xf9, 0xd5, 0x99, - 0x38, 0xfd, 0x8f, 0x16, 0x56, 0x47, 0x77, 0x32, 0x66, 0x80, 0x66, 0xff, 0xa1, 0x2e, 0xb3, - 0x47, 0xea, 0xb4, 0x7b, + 0xb3, 0x68, 0x70, 0xea, 0xab, 0x31, 0xcb, 0xeb, 0x1a, 0x5c, 0x07, 0x46, 0x7b, 0x42, 0x97, + 0x40, 0x7c, 0x62, 0x11, 0x7a, 0x31, 0x15, 0x47, 0xc4, 0x30, 0x5e, 0x14, 0x71, 0x52, 0x1b, + 0x53, 0x01, 0xc2, 0x59, 0x9d, 0x4e, 0xad, 0xdf, 0xd3, 0x84, 0x9d, 0xf9, 0xd5, 0x99, 0x38, + 0xfd, 0x8f, 0x16, 0x56, 0x47, 0x77, 0x32, 0x66, 0x80, 0x66, 0xff, 0xa1, 0x2e, 0xb3, 0x47, + 0xea, 0xb4, 0x7b, 0x9c, ]; - let b = logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0, 1).unwrap(); + let b = logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0, 0, 1).unwrap(); assert_ne!(b, 0); let result = &vec![0u8; 64]; @@ -594,7 +594,7 @@ fn test_ecrecover() { assert_costs(map! { ExtCosts::base: 1, ExtCosts::read_memory_base: 2, - ExtCosts::read_memory_byte: 97, + ExtCosts::read_memory_byte: 96, ExtCosts::write_memory_base: 1, ExtCosts::write_memory_byte: 64, ExtCosts::read_register_base: 1, From 88fd6aae84bdd019ff183980fc8e6c0eaa111f53 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 22:03:59 +0700 Subject: [PATCH 116/134] Update doc cost --- runtime/near-vm-logic/src/logic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 916f52b5729..5c47dc640db 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1005,7 +1005,7 @@ impl<'a> VMLogic<'a> { /// /// # Cost /// - /// `base + write_register_base + write_register_byte * 20 + ecrecover_base` + /// `base + write_register_base + write_register_byte * 64 + ecrecover_base` #[cfg(feature = "protocol_feature_math_extension")] pub fn ecrecover( &mut self, From 9d58f32fbbd05226b4aeb1859395f32acf2bae69 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 22:14:13 +0700 Subject: [PATCH 117/134] Fix estimator --- runtime/near-vm-logic/tests/test_miscs.rs | 7 +++++-- .../test-contract/src/lib.rs | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index 98fd1616e8b..ca458a5e00f 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -567,8 +567,11 @@ fn test_ecrecover() { let mut logic = logic_builder.build(get_context(vec![], false)); // See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/cryptography/ECDSA.test.js - use sha3::Digest; - let hash = sha3::Keccak256::digest(b"OpenZeppelin"); + let hash: [u8; 32] = [ + 0x7d, 0xba, 0xf5, 0x58, 0xb0, 0xa1, 0xa5, 0xdc, 0x7a, 0x67, 0x20, 0x21, 0x17, 0xab, 0x14, + 0x3c, 0x1d, 0x86, 0x05, 0xa9, 0x83, 0xe4, 0xa7, 0x43, 0xbc, 0x06, 0xfc, 0xc0, 0x31, 0x62, + 0xdc, 0x0d, + ]; let signature: [u8; 64] = [ 0x5d, 0x99, 0xb6, 0xf7, 0xf6, 0xd1, 0xf7, 0x3d, 0x1a, 0x26, 0x49, 0x7f, 0x2b, 0x1c, 0x89, 0xb2, 0x4c, 0x09, 0x93, 0x91, 0x3f, 0x86, 0xe9, 0xa2, 0xd0, 0x2c, 0xd6, 0x98, 0x87, 0xd9, diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 4a2ec29a850..52b8e529c43 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -460,11 +460,21 @@ pub unsafe fn ripemd160_10kib_10k() { #[cfg(feature = "protocol_feature_math_extension")] #[no_mangle] pub unsafe fn ecrecover_10k() { - let hash = [0u8; 32]; - let signature = [0u8; 65]; - let (r, s, v) = (&signature[0..32], &signature[32..64], 27); + let hash_buffer: [u8; 64] = [ + 0x7d, 0xba, 0xf5, 0x58, 0xb0, 0xa1, 0xa5, 0xdc, 0x7a, 0x67, 0x20, 0x21, 0x17, 0xab, 0x14, + 0x3c, 0x1d, 0x86, 0x05, 0xa9, 0x83, 0xe4, 0xa7, 0x43, 0xbc, 0x06, 0xfc, 0xc0, 0x31, 0x62, + 0xdc, 0x0d, + ]; + let sig_buffer: [u8; 64] = [ + 0x5d, 0x99, 0xb6, 0xf7, 0xf6, 0xd1, 0xf7, 0x3d, 0x1a, 0x26, 0x49, 0x7f, 0x2b, 0x1c, 0x89, + 0xb2, 0x4c, 0x09, 0x93, 0x91, 0x3f, 0x86, 0xe9, 0xa2, 0xd0, 0x2c, 0xd6, 0x98, 0x87, 0xd9, + 0xc9, 0x4f, 0x3c, 0x88, 0x03, 0x58, 0x57, 0x9d, 0x81, 0x1b, 0x21, 0xdd, 0x1b, 0x7f, 0xd9, + 0xbb, 0x01, 0xc1, 0xd8, 0x1d, 0x10, 0xe6, 0x9f, 0x03, 0x84, 0xe6, 0x75, 0xc3, 0x2b, 0x39, + 0x64, 0x3b, 0xe8, 0x92, + ]; + for _ in 0..10_000 { - ecrecover(hash.as_ptr() as _, v, r.as_ptr() as _, s.as_ptr() as _, 0); + ecrecover(hash_buffer.as_ptr() as _, sig_buffer.as_ptr() as _, 0, 0, 0); } } From 2fe75e840427d531f275fa67a294ef65796343dc Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 22:26:09 +0700 Subject: [PATCH 118/134] Small fixes --- core/crypto/src/signature.rs | 2 +- runtime/near-vm-runner/src/imports.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 69dc8225174..74b72af0ed1 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -592,7 +592,7 @@ impl Secp256K1Signature { let recoverable_sig = secp256k1::RecoverableSignature::from_compact( &SECP256K1, &self.0[0..64], - secp256k1::RecoveryId::from_i32(i32::from(signature.0[64])).unwrap(), + secp256k1::RecoveryId::from_i32(i32::from(self.0[64])).unwrap(), ) .map_err(|err| crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string(), diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index 2e214f0517a..fc3129a3ccb 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -222,7 +222,7 @@ wrapped_imports! { keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_math_extension", MathExtension] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_math_extension", MathExtension] ecrecover<[hash_ptr: u64, sig_ptr: u64, malleability_flag: u32, register_id: u64] -> [u64]>, + #["protocol_feature_math_extension", MathExtension] ecrecover<[hash_ptr: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### From fe314312cfba5b93045ffe04025d28266d34c7b3 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 24 Jun 2021 22:58:39 +0700 Subject: [PATCH 119/134] Add missing feature `protocol_feature_math_extension` from neard --- neard/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/neard/Cargo.toml b/neard/Cargo.toml index 024f3c9fb38..9c7ac8a36ab 100644 --- a/neard/Cargo.toml +++ b/neard/Cargo.toml @@ -51,6 +51,7 @@ nightly_protocol_features = ["nearcore/nightly_protocol_features"] nightly_protocol = ["nearcore/nightly_protocol"] protocol_feature_restore_receipts_after_fix = ["nearcore/protocol_feature_restore_receipts_after_fix"] protocol_feature_cap_max_gas_price = ["nearcore/protocol_feature_cap_max_gas_price"] +protocol_feature_math_extension = ["nearcore/protocol_feature_math_extension"] sandbox = ["nearcore/sandbox"] From 7ca7285fc77737051c935ddfd27a983cb1dc2379 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 00:32:03 +0700 Subject: [PATCH 120/134] Add near-primitives to math extension params estimator --- runtime/runtime-params-estimator/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index 481098985cf..9f6fa89eca2 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -72,6 +72,7 @@ protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "testlib/protocol_feature_evm"] sandbox = ["node-runtime/sandbox", "state-viewer/sandbox"] protocol_feature_math_extension = [ + "near-primitives/protocol_feature_math_extension", "near-vm-logic/protocol_feature_math_extension", "near-vm-runner/protocol_feature_math_extension", "nearcore/protocol_feature_math_extension", From d9684df27ba7682dc4aa8e5c05334accbbd7cd8b Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 00:40:55 +0700 Subject: [PATCH 121/134] Fix byte length --- runtime/runtime-params-estimator/test-contract/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 52b8e529c43..870d4db696d 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -460,7 +460,7 @@ pub unsafe fn ripemd160_10kib_10k() { #[cfg(feature = "protocol_feature_math_extension")] #[no_mangle] pub unsafe fn ecrecover_10k() { - let hash_buffer: [u8; 64] = [ + let hash_buffer: [u8; 32] = [ 0x7d, 0xba, 0xf5, 0x58, 0xb0, 0xa1, 0xa5, 0xdc, 0x7a, 0x67, 0x20, 0x21, 0x17, 0xab, 0x14, 0x3c, 0x1d, 0x86, 0x05, 0xa9, 0x83, 0xe4, 0xa7, 0x43, 0xbc, 0x06, 0xfc, 0xc0, 0x31, 0x62, 0xdc, 0x0d, From 1211d9c8d562cd890dbff6ea0da72d94bfd240f3 Mon Sep 17 00:00:00 2001 From: Maksym Zavershynskyi Date: Thu, 24 Jun 2021 11:31:41 -0700 Subject: [PATCH 122/134] Fix Cargo.toml --- nearcore/Cargo.toml | 6 +++++- runtime/runtime/Cargo.toml | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nearcore/Cargo.toml b/nearcore/Cargo.toml index eb10dcbe387..66cf8935999 100644 --- a/nearcore/Cargo.toml +++ b/nearcore/Cargo.toml @@ -73,7 +73,11 @@ nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protoc nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"] protocol_feature_restore_receipts_after_fix = ["near-primitives/protocol_feature_restore_receipts_after_fix", "near-chain/protocol_feature_restore_receipts_after_fix", "node-runtime/protocol_feature_restore_receipts_after_fix"] protocol_feature_cap_max_gas_price = ["near-primitives/protocol_feature_cap_max_gas_price", "near-chain/protocol_feature_cap_max_gas_price"] -protocol_feature_math_extension = ["near-primitives/protocol_feature_math_extension"] +protocol_feature_math_extension = [ + "near-crypto/protocol_feature_math_extension", + "near-primitives/protocol_feature_math_extension", + "near-runtime/protocol_feature_math_extension" +] # enable this to build neard with wasmer 1.0 runner # now if none of wasmer0_default, wasmer1_default or wasmtime_default is enabled, wasmer0 would be default diff --git a/runtime/runtime/Cargo.toml b/runtime/runtime/Cargo.toml index e4e47712519..2e19416a8d2 100644 --- a/runtime/runtime/Cargo.toml +++ b/runtime/runtime/Cargo.toml @@ -56,6 +56,13 @@ protocol_feature_tx_size_limit = [] protocol_feature_allow_create_account_on_delete = ["near-primitives/protocol_feature_allow_create_account_on_delete", "near-vm-logic/protocol_feature_allow_create_account_on_delete"] protocol_feature_fix_storage_usage = ["near-primitives/protocol_feature_fix_storage_usage"] protocol_feature_restore_receipts_after_fix = [] +protocol_feature_math_extension = [ + "near-crypto/protocol_feature_math_extension", + "near-primitives/protocol_feature_math_extension", + "near-vm-logic/protocol_feature_math_extension", + "near-vm-runner/protocol_feature_math_extension", + "near-vm-errors/protocol_feature_math_extension" +] sandbox = [] [dev-dependencies] From 5c722b2490048fd27953375bb06371c59c231d22 Mon Sep 17 00:00:00 2001 From: Maksym Zavershynskyi Date: Thu, 24 Jun 2021 11:37:30 -0700 Subject: [PATCH 123/134] Nit. Typos --- nearcore/Cargo.toml | 3 +-- runtime/runtime/Cargo.toml | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/nearcore/Cargo.toml b/nearcore/Cargo.toml index 66cf8935999..a831232cb90 100644 --- a/nearcore/Cargo.toml +++ b/nearcore/Cargo.toml @@ -74,9 +74,8 @@ nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_pr protocol_feature_restore_receipts_after_fix = ["near-primitives/protocol_feature_restore_receipts_after_fix", "near-chain/protocol_feature_restore_receipts_after_fix", "node-runtime/protocol_feature_restore_receipts_after_fix"] protocol_feature_cap_max_gas_price = ["near-primitives/protocol_feature_cap_max_gas_price", "near-chain/protocol_feature_cap_max_gas_price"] protocol_feature_math_extension = [ - "near-crypto/protocol_feature_math_extension", "near-primitives/protocol_feature_math_extension", - "near-runtime/protocol_feature_math_extension" + "node-runtime/protocol_feature_math_extension" ] # enable this to build neard with wasmer 1.0 runner diff --git a/runtime/runtime/Cargo.toml b/runtime/runtime/Cargo.toml index 2e19416a8d2..6ecd3f70ff0 100644 --- a/runtime/runtime/Cargo.toml +++ b/runtime/runtime/Cargo.toml @@ -57,7 +57,6 @@ protocol_feature_allow_create_account_on_delete = ["near-primitives/protocol_fea protocol_feature_fix_storage_usage = ["near-primitives/protocol_feature_fix_storage_usage"] protocol_feature_restore_receipts_after_fix = [] protocol_feature_math_extension = [ - "near-crypto/protocol_feature_math_extension", "near-primitives/protocol_feature_math_extension", "near-vm-logic/protocol_feature_math_extension", "near-vm-runner/protocol_feature_math_extension", From b17bddb1be147055a6cf0fb95c63fe3d17bead7e Mon Sep 17 00:00:00 2001 From: Maksym Zavershynskyi Date: Thu, 24 Jun 2021 14:05:00 -0700 Subject: [PATCH 124/134] Nit. param estimator is missing feature dependency --- runtime/runtime-params-estimator/Cargo.toml | 1 + .../test-contract/build.sh | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index 9f6fa89eca2..ac752ce51c2 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -76,4 +76,5 @@ protocol_feature_math_extension = [ "near-vm-logic/protocol_feature_math_extension", "near-vm-runner/protocol_feature_math_extension", "nearcore/protocol_feature_math_extension", + "node-runtime/protocol_feature_math_extension" ] \ No newline at end of file diff --git a/runtime/runtime-params-estimator/test-contract/build.sh b/runtime/runtime-params-estimator/test-contract/build.sh index baaebff6d7a..26ecf57d339 100755 --- a/runtime/runtime-params-estimator/test-contract/build.sh +++ b/runtime/runtime-params-estimator/test-contract/build.sh @@ -23,7 +23,7 @@ rustup target add wasm32-unknown-unknown # First, measure the size of the file without payload. rm -rf target -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features protocol_feature_math_extension bare_wasm=$(filesize target/wasm32-unknown-unknown/release/test_contract.wasm) echo ${bare_wasm} @@ -32,17 +32,17 @@ echo ${bare_wasm} # 10KiB dd if=/dev/urandom of=./res/payload bs=$(expr 10240 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,protocol_feature_math_extension cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/stable_small_contract.wasm # 100KiB dd if=/dev/urandom of=./res/payload bs=$(expr 102400 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,protocol_feature_math_extension cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/stable_medium_contract.wasm # 1MiB dd if=/dev/urandom of=./res/payload bs=$(expr 1048576 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,protocol_feature_math_extension cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/stable_large_contract.wasm rm ./res/payload @@ -50,7 +50,7 @@ rm ./res/payload # Compiling nightly rm -rf target -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features nightly_protocol_features +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features nightly_protocol_features,protocol_feature_math_extension bare_wasm=$(filesize target/wasm32-unknown-unknown/release/test_contract.wasm) echo ${bare_wasm} @@ -60,17 +60,17 @@ echo ${bare_wasm} # Note the base is 16057 due to alt_bn128 hardcoded input. # 20KiB dd if=/dev/urandom of=./res/payload bs=$(expr 20480 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features,protocol_feature_math_extension cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/nightly_small_contract.wasm # 100KiB dd if=/dev/urandom of=./res/payload bs=$(expr 102400 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features,protocol_feature_math_extension cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/nightly_medium_contract.wasm # 1MiB dd if=/dev/urandom of=./res/payload bs=$(expr 1048576 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features,protocol_feature_math_extension cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/nightly_large_contract.wasm rm ./res/payload From 47106835c9652afba98ac599fffa8dcf63073d04 Mon Sep 17 00:00:00 2001 From: Maksym Zavershynskyi Date: Thu, 24 Jun 2021 17:05:49 -0700 Subject: [PATCH 125/134] Add feature support for build.sh of test-contract --- .../test-contract/build.sh | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/runtime/runtime-params-estimator/test-contract/build.sh b/runtime/runtime-params-estimator/test-contract/build.sh index 26ecf57d339..22219bb9a6b 100755 --- a/runtime/runtime-params-estimator/test-contract/build.sh +++ b/runtime/runtime-params-estimator/test-contract/build.sh @@ -1,6 +1,14 @@ #!/usr/bin/env bash set -ex +features_with_arg="" +features_with_comma="" + +if [[ ! -z "$1" ]]; then + features_with_arg="--features $1" + features_with_comma=",$1" +fi + function filesize { local file=$1 @@ -23,7 +31,7 @@ rustup target add wasm32-unknown-unknown # First, measure the size of the file without payload. rm -rf target -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release $features_with_arg bare_wasm=$(filesize target/wasm32-unknown-unknown/release/test_contract.wasm) echo ${bare_wasm} @@ -32,17 +40,17 @@ echo ${bare_wasm} # 10KiB dd if=/dev/urandom of=./res/payload bs=$(expr 10240 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "payload$features_with_comma" cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/stable_small_contract.wasm # 100KiB dd if=/dev/urandom of=./res/payload bs=$(expr 102400 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "payload$features_with_comma" cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/stable_medium_contract.wasm # 1MiB dd if=/dev/urandom of=./res/payload bs=$(expr 1048576 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "payload$features_with_comma" cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/stable_large_contract.wasm rm ./res/payload @@ -50,7 +58,7 @@ rm ./res/payload # Compiling nightly rm -rf target -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features nightly_protocol_features,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "nightly_protocol_features$features_with_comma" bare_wasm=$(filesize target/wasm32-unknown-unknown/release/test_contract.wasm) echo ${bare_wasm} @@ -60,17 +68,17 @@ echo ${bare_wasm} # Note the base is 16057 due to alt_bn128 hardcoded input. # 20KiB dd if=/dev/urandom of=./res/payload bs=$(expr 20480 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "payload,nightly_protocol_features$features_with_comma" cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/nightly_small_contract.wasm # 100KiB dd if=/dev/urandom of=./res/payload bs=$(expr 102400 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "payload,nightly_protocol_features$features_with_comma" cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/nightly_medium_contract.wasm # 1MiB dd if=/dev/urandom of=./res/payload bs=$(expr 1048576 - ${bare_wasm}) count=1 -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features payload,nightly_protocol_features,protocol_feature_math_extension +RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release --features "payload,nightly_protocol_features$features_with_comma" cp target/wasm32-unknown-unknown/release/test_contract.wasm ./res/nightly_large_contract.wasm rm ./res/payload From e5f7468abd9ea4c94da78f2101f415a2ab4054f9 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 20:33:02 +0700 Subject: [PATCH 126/134] Add consts for SECP256K1 malleability values --- core/crypto/src/signature.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 74b72af0ed1..b78871a6775 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -555,6 +555,13 @@ impl<'de> serde::Deserialize<'de> for SecretKey { } } +const SECP256K1_N: U256 = + U256([0xbfd25e8cd0364141, 0xbaaedce6af48a03b, 0xfffffffffffffffe, 0xffffffffffffffff]); + +// Half of SECP256K1_N. +const SECP256K1_N_HALF: U256 = + U256([0xdfe92f46681b20a0, 0x5d576e7357a4501d, 0xffffffffffffffff, 0x7fffffffffffffff]); + #[derive(Clone)] pub struct Secp256K1Signature([u8; 65]); @@ -568,21 +575,14 @@ impl Secp256K1Signature { s_bytes.copy_from_slice(&self.0[32..64]); let s = U256::from(s_bytes); - let secp256k1_n = U256::from([ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, - 0xd0, 0x36, 0x41, 0x41, - ]); - if reject_upper { - let secp256k1_half_n = secp256k1_n / U256::from(2); // Reject upper range of s values (ECDSA malleability) - if s > secp256k1_half_n { + if s > SECP256K1_N_HALF { return false; } } - r < secp256k1_n && s < secp256k1_n + r < SECP256K1_N && s < SECP256K1_N } pub fn recover( From 2091bfafcae395ea2395e4c0f65c6dd21a7843a3 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 20:37:58 +0700 Subject: [PATCH 127/134] Remove map err, change to unwrap --- core/crypto/src/signature.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index b78871a6775..5774a170869 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -606,9 +606,8 @@ impl Secp256K1Signature { })? .serialize_vec(&SECP256K1, false); - let pk = Secp256K1PublicKey::try_from(&res[1..65]).map_err(|err| { - crate::errors::ParseSignatureError::InvalidData { error_message: err.to_string() } - })?; + // Can not fail + let pk = Secp256K1PublicKey::try_from(&res[1..65]).unwrap(); Ok(pk) } From bdc906663a678fa86fab7b83848a4bf0e6929def Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 20:39:58 +0700 Subject: [PATCH 128/134] Change v check to something more simple --- runtime/near-vm-logic/src/logic.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 5c47dc640db..56a386fe232 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1022,16 +1022,13 @@ impl<'a> VMLogic<'a> { let mut bytes = [0u8; 65]; bytes[0..64].copy_from_slice(&vec); - match v { - 0 | 1 | 2 | 3 => { - bytes[64] = v as u8; - Secp256K1Signature::from(bytes) - } - _ => { - return Err(VMLogicError::HostError(HostError::InvalidECRecoverVByte { - value: v as u64, - })) - } + if v < 4 { + bytes[64] = v as u8; + Secp256K1Signature::from(bytes) + } else { + return Err(VMLogicError::HostError(HostError::InvalidECRecoverVByte { + value: v as u64, + })) } }; From 5e76c8bf512bb63242279b6df8addd04fd63be30 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 20:44:52 +0700 Subject: [PATCH 129/134] Always do signature check --- runtime/near-vm-logic/src/logic.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 56a386fe232..af2e49ee5d3 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -994,9 +994,8 @@ impl<'a> VMLogic<'a> { /// /// # Malleability Flags /// - /// 0 - No malleability check. - /// 1 - Check malleability. - /// 2 - Rejecting upper range. + /// 0 - No extra checks. + /// 1 - Rejecting upper range. /// /// # Errors /// @@ -1039,10 +1038,8 @@ impl<'a> VMLogic<'a> { bytes }; - if (malleability_flag & 1) == 1 { - if !signature.check_signature_values((malleability_flag & 2) == 2) { - return Ok(false as u64); - } + if !signature.check_signature_values((malleability_flag & 1) == 1) { + return Ok(false as u64); } if let Ok(pk) = signature.recover(hash) { From 38fc3626d696ebacbb9f03c5bb35bfb9412b7feb Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 22:09:08 +0700 Subject: [PATCH 130/134] Check one s bound --- core/crypto/src/signature.rs | 12 ++++++------ runtime/near-vm-logic/src/logic.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index 5774a170869..706490a1024 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -575,14 +575,14 @@ impl Secp256K1Signature { s_bytes.copy_from_slice(&self.0[32..64]); let s = U256::from(s_bytes); - if reject_upper { + let s_check = if reject_upper { // Reject upper range of s values (ECDSA malleability) - if s > SECP256K1_N_HALF { - return false; - } - } + SECP256K1_N_HALF + U256::one() + } else { + SECP256K1_N + }; - r < SECP256K1_N && s < SECP256K1_N + r < SECP256K1_N && s < s_check } pub fn recover( diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index af2e49ee5d3..a89d4dc2116 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1027,7 +1027,7 @@ impl<'a> VMLogic<'a> { } else { return Err(VMLogicError::HostError(HostError::InvalidECRecoverVByte { value: v as u64, - })) + })); } }; From 43aa88bb3c0a641b29086fed674efa0477e9784c Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 23:04:48 +0700 Subject: [PATCH 131/134] Allow for specifying a register --- runtime/near-vm-errors/src/lib.rs | 5 ++-- runtime/near-vm-logic/src/logic.rs | 28 ++++++++++++++++--- runtime/near-vm-logic/tests/test_miscs.rs | 2 +- runtime/near-vm-runner/src/imports.rs | 2 +- runtime/runtime-params-estimator/src/lib.rs | 8 ++---- .../test-contract/src/lib.rs | 4 +-- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index fe93cfa38e1..8bfbf37b216 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -212,8 +212,9 @@ pub enum HostError { /// Serialization error for alt_bn128 functions #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128SerializationError { msg: String }, + /// General errors for ECDSA recover. #[cfg(feature = "protocol_feature_math_extension")] - InvalidECRecoverVByte { value: u64 }, + ECRecoverError { msg: String }, } /// Errors specifically from native EVM. @@ -501,7 +502,7 @@ impl std::fmt::Display for HostError { #[cfg(feature = "protocol_feature_alt_bn128")] AltBn128SerializationError { msg } => write!(f, "AltBn128 serialization error: {}", msg), #[cfg(feature = "protocol_feature_math_extension")] - InvalidECRecoverVByte { value } => write!(f, "V recovery byte 0 through 3 are valid but was provided {}", value), + ECRecoverError { msg } => write!(f, "ECDSA recover error: {}", msg), } } } diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index a89d4dc2116..62e8b981b6d 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1008,7 +1008,9 @@ impl<'a> VMLogic<'a> { #[cfg(feature = "protocol_feature_math_extension")] pub fn ecrecover( &mut self, + hash_len: u64, hash_ptr: u64, + sig_len: u64, sig_ptr: u64, v: u64, malleability_flag: u64, @@ -1017,7 +1019,16 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_base(ecrecover_base)?; let signature = { - let vec = self.get_vec_from_memory_or_register(sig_ptr, 64)?; + let vec = self.get_vec_from_memory_or_register(sig_ptr, sig_len)?; + if vec.len() != 64 { + return Err(VMLogicError::HostError(HostError::ECRecoverError { + msg: format!( + "The length of the signature: {}, exceeds the limit of 64 bytes", + vec.len() + ), + })); + } + let mut bytes = [0u8; 65]; bytes[0..64].copy_from_slice(&vec); @@ -1025,14 +1036,23 @@ impl<'a> VMLogic<'a> { bytes[64] = v as u8; Secp256K1Signature::from(bytes) } else { - return Err(VMLogicError::HostError(HostError::InvalidECRecoverVByte { - value: v as u64, + return Err(VMLogicError::HostError(HostError::ECRecoverError { + msg: format!("V recovery byte 0 through 3 are valid but was provided {}", v), })); } }; let hash = { - let vec = self.get_vec_from_memory_or_register(hash_ptr, 32)?; + let vec = self.get_vec_from_memory_or_register(hash_ptr, hash_len)?; + if vec.len() != 32 { + return Err(VMLogicError::HostError(HostError::ECRecoverError { + msg: format!( + "The length of the hash: {}, exceeds the limit of 32 bytes", + vec.len() + ), + })); + } + let mut bytes = [0u8; 32]; bytes.copy_from_slice(&vec); bytes diff --git a/runtime/near-vm-logic/tests/test_miscs.rs b/runtime/near-vm-logic/tests/test_miscs.rs index ca458a5e00f..aaead836e5f 100644 --- a/runtime/near-vm-logic/tests/test_miscs.rs +++ b/runtime/near-vm-logic/tests/test_miscs.rs @@ -587,7 +587,7 @@ fn test_ecrecover() { 0xea, 0xb4, 0x7b, 0x9c, ]; - let b = logic.ecrecover(hash.as_ptr() as _, signature.as_ptr() as _, 0, 0, 1).unwrap(); + let b = logic.ecrecover(32, hash.as_ptr() as _, 64, signature.as_ptr() as _, 0, 0, 1).unwrap(); assert_ne!(b, 0); let result = &vec![0u8; 64]; diff --git a/runtime/near-vm-runner/src/imports.rs b/runtime/near-vm-runner/src/imports.rs index fc3129a3ccb..5fcdb3083e0 100644 --- a/runtime/near-vm-runner/src/imports.rs +++ b/runtime/near-vm-runner/src/imports.rs @@ -222,7 +222,7 @@ wrapped_imports! { keccak256<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, keccak512<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, #["protocol_feature_math_extension", MathExtension] ripemd160<[value_len: u64, value_ptr: u64, register_id: u64] -> []>, - #["protocol_feature_math_extension", MathExtension] ecrecover<[hash_ptr: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64] -> [u64]>, + #["protocol_feature_math_extension", MathExtension] ecrecover<[hash_len: u64, hash_ptr: u64, sign_len: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64] -> [u64]>, // ##################### // # Miscellaneous API # // ##################### diff --git a/runtime/runtime-params-estimator/src/lib.rs b/runtime/runtime-params-estimator/src/lib.rs index df99f3f3ed4..6dd7e9ce7fd 100644 --- a/runtime/runtime-params-estimator/src/lib.rs +++ b/runtime/runtime-params-estimator/src/lib.rs @@ -8,13 +8,11 @@ pub mod ext_costs_generator; pub mod vm_estimator; // Collects and processes stats. Prints them on display, plots them, writes them into a file. pub mod stats; -/// Encapsulates the runtime so that it can be run separately from the rest of the node. +// Encapsulates the runtime so that it can be run separately from the rest of the node. pub mod testbed; -/// Prepares transactions and feeds them to the testbed in batches. Performs the warm up, takes care -/// of nonces. +// Prepares transactions and feeds them to the testbed in batches. Performs the warm up, takes care +// of nonces. pub mod testbed_runners; -/// Runs a VM (Default: Wasmer) on the given contract and measures the time it takes to do a single operation. -pub mod vm_estimator; use std::path::Path; diff --git a/runtime/runtime-params-estimator/test-contract/src/lib.rs b/runtime/runtime-params-estimator/test-contract/src/lib.rs index 870d4db696d..399aa890f50 100644 --- a/runtime/runtime-params-estimator/test-contract/src/lib.rs +++ b/runtime/runtime-params-estimator/test-contract/src/lib.rs @@ -50,7 +50,7 @@ extern "C" { #[cfg(feature = "protocol_feature_math_extension")] fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64); #[cfg(feature = "protocol_feature_math_extension")] - fn ecrecover(hash_ptr: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64); + fn ecrecover(hash_len: u64, hash_ptr: u64, sig_len: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64); // ##################### // # Miscellaneous API # // ##################### @@ -474,7 +474,7 @@ pub unsafe fn ecrecover_10k() { ]; for _ in 0..10_000 { - ecrecover(hash_buffer.as_ptr() as _, sig_buffer.as_ptr() as _, 0, 0, 0); + ecrecover(32, hash_buffer.as_ptr() as _, 64, sig_buffer.as_ptr() as _, 0, 0, 0); } } From ac53dcbafcc5c0f405eeaf0dccfcdbf5ba19161a Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Fri, 25 Jun 2021 23:47:32 +0700 Subject: [PATCH 132/134] Remove math extension feature from primitives core --- core/primitives-core/Cargo.toml | 1 - core/primitives-core/src/config.rs | 15 --------------- core/primitives/Cargo.toml | 2 +- runtime/near-vm-runner/Cargo.toml | 2 +- runtime/runtime-params-estimator/src/cases.rs | 3 --- 5 files changed, 2 insertions(+), 21 deletions(-) diff --git a/core/primitives-core/Cargo.toml b/core/primitives-core/Cargo.toml index e6cc9307a1b..1694b3d0e35 100644 --- a/core/primitives-core/Cargo.toml +++ b/core/primitives-core/Cargo.toml @@ -28,4 +28,3 @@ protocol_feature_evm = [] protocol_feature_add_account_versions = [] protocol_feature_alt_bn128 = [] protocol_feature_tx_size_limit = [] -protocol_feature_math_extension = [] diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index c192a93c5d2..396b0e8d46e 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -223,14 +223,11 @@ pub struct ExtCostsConfig { /// Cost of getting sha256 per byte pub keccak512_byte: Gas, - #[cfg(feature = "protocol_feature_math_extension")] /// Cost of getting ripemd160 base pub ripemd160_base: Gas, - #[cfg(feature = "protocol_feature_math_extension")] /// Cost of getting ripemd160 per message block pub ripemd160_block: Gas, - #[cfg(feature = "protocol_feature_math_extension")] /// Cost of calling ecrecover pub ecrecover_base: Gas, @@ -364,11 +361,8 @@ impl Default for ExtCostsConfig { keccak256_byte: SAFETY_MULTIPLIER * 7157035, keccak512_base: SAFETY_MULTIPLIER * 1937129412, keccak512_byte: SAFETY_MULTIPLIER * 12216567, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base: SAFETY_MULTIPLIER * 15136567500, // 10 x sha256_base - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block: SAFETY_MULTIPLIER * 80391170 * 8, // 10 x sha256_byte x 8 bytes - #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base: SAFETY_MULTIPLIER * 75682837500, // 50 x sha256_base log_base: SAFETY_MULTIPLIER * 1181104350, log_byte: SAFETY_MULTIPLIER * 4399597, @@ -440,11 +434,8 @@ impl ExtCostsConfig { keccak256_byte: 0, keccak512_base: 0, keccak512_byte: 0, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base: 0, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block: 0, - #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base: 0, log_base: 0, log_byte: 0, @@ -517,11 +508,8 @@ pub enum ExtCosts { keccak256_byte, keccak512_base, keccak512_byte, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block, - #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base, log_base, log_byte, @@ -647,11 +635,8 @@ impl ExtCosts { keccak256_byte => config.keccak256_byte, keccak512_base => config.keccak512_base, keccak512_byte => config.keccak512_byte, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base => config.ripemd160_base, - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block => config.ripemd160_block, - #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base => config.ecrecover_base, log_base => config.log_base, log_byte => config.log_byte, diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 4ac93c4342d..9011a6b22a7 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -50,7 +50,7 @@ protocol_feature_allow_create_account_on_delete = [] protocol_feature_fix_storage_usage = [] protocol_feature_restore_receipts_after_fix = [] protocol_feature_cap_max_gas_price = [] -protocol_feature_math_extension = ["near-primitives-core/protocol_feature_math_extension"] +protocol_feature_math_extension = [] nightly_protocol_features = ["nightly_protocol", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "protocol_feature_fix_storage_usage", "protocol_feature_restore_receipts_after_fix", "protocol_feature_cap_max_gas_price", "protocol_feature_math_extension"] nightly_protocol = [] diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index 3d831a27047..e64223dfd64 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -67,7 +67,7 @@ protocol_feature_alt_bn128 = [ ] protocol_feature_math_extension = [ "near-vm-logic/protocol_feature_math_extension", - "near-primitives/protocol_feature_math_extension" + "near-primitives/protocol_feature_math_extension", ] [package.metadata.cargo-udeps.ignore] diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index fc9639783fa..978263e453f 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -746,11 +746,8 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts keccak256_byte: measured_to_gas(metric, &measured, keccak256_byte), keccak512_base: measured_to_gas(metric, &measured, keccak512_base), keccak512_byte: measured_to_gas(metric, &measured, keccak512_byte), - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_base: measured_to_gas(metric, &measured, ripemd160_base), - #[cfg(feature = "protocol_feature_math_extension")] ripemd160_block: measured_to_gas(metric, &measured, ripemd160_block), - #[cfg(feature = "protocol_feature_math_extension")] ecrecover_base: measured_to_gas(metric, &measured, ecrecover_base), log_base: measured_to_gas(metric, &measured, log_base), log_byte: measured_to_gas(metric, &measured, log_byte), From 2c4a48b0da82ccc9b86d2a300c978c1a2316ff55 Mon Sep 17 00:00:00 2001 From: Maksym Zavershynskyi Date: Fri, 25 Jun 2021 17:55:30 -0700 Subject: [PATCH 133/134] Nit. Convering byte to bool --- runtime/near-vm-logic/src/logic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 62e8b981b6d..1bd8f424cb4 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -1058,7 +1058,7 @@ impl<'a> VMLogic<'a> { bytes }; - if !signature.check_signature_values((malleability_flag & 1) == 1) { + if !signature.check_signature_values(malleability_flag != 0) { return Ok(false as u64); } From b5d1ab7541c804910e3951a7f8b39ee26d5848f6 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Sat, 26 Jun 2021 21:12:55 +0300 Subject: [PATCH 134/134] Add measuring support. --- Cargo.lock | 1 + runtime/near-vm-logic/src/lib.rs | 4 + runtime/near-vm-logic/src/logic.rs | 46 +++++--- runtime/runtime-params-estimator/Cargo.toml | 1 + runtime/runtime-params-estimator/src/cases.rs | 2 +- runtime/runtime-params-estimator/src/lib.rs | 9 +- .../src/math_ops_cost.rs | 101 ++++++++++++++++++ .../src/vm_estimator.rs | 7 +- runtime/runtime/src/lib.rs | 27 ++--- 9 files changed, 163 insertions(+), 35 deletions(-) create mode 100644 runtime/runtime-params-estimator/src/math_ops_cost.rs diff --git a/Cargo.lock b/Cargo.lock index 04d924c95e5..89e1f4268ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4887,6 +4887,7 @@ dependencies = [ "rand 0.7.3", "rand_xorshift 0.2.0", "rayon", + "ripemd160", "rocksdb", "serde_json", "state-viewer", diff --git a/runtime/near-vm-logic/src/lib.rs b/runtime/near-vm-logic/src/lib.rs index 33d11b35798..ec61ee93157 100644 --- a/runtime/near-vm-logic/src/lib.rs +++ b/runtime/near-vm-logic/src/lib.rs @@ -19,3 +19,7 @@ pub use near_vm_errors::{HostError, VMLogicError}; pub use types::ReturnData; pub use gas_counter::with_ext_cost_counter; +#[cfg(feature = "protocol_feature_math_extension")] +pub use logic::ecrecover; +#[cfg(feature = "protocol_feature_math_extension")] +pub use logic::ripemd160; diff --git a/runtime/near-vm-logic/src/logic.rs b/runtime/near-vm-logic/src/logic.rs index 1bd8f424cb4..1eed63c86ed 100644 --- a/runtime/near-vm-logic/src/logic.rs +++ b/runtime/near-vm-logic/src/logic.rs @@ -6,6 +6,8 @@ use crate::utils::split_method_names; use crate::ValuePtr; use byteorder::ByteOrder; #[cfg(feature = "protocol_feature_math_extension")] +use near_crypto::Secp256K1PublicKey; +#[cfg(feature = "protocol_feature_math_extension")] use near_crypto::Secp256K1Signature; use near_primitives::checked_feature; use near_primitives::version::is_implicit_account_creation_enabled; @@ -979,10 +981,8 @@ impl<'a> VMLogic<'a> { self.gas_counter.pay_per(ripemd160_block, message_blocks as u64)?; - use ripemd160::Digest; - - let value_hash = ripemd160::Ripemd160::digest(&value); - self.internal_write_register(register_id, value_hash.as_slice().to_vec()) + let value_hash = ripemd160(&value); + self.internal_write_register(register_id, value_hash) } /// Recovers an ECDSA signer address and returns it into `register_id`. @@ -1018,7 +1018,7 @@ impl<'a> VMLogic<'a> { ) -> Result { self.gas_counter.pay_base(ecrecover_base)?; - let signature = { + let signature_data = { let vec = self.get_vec_from_memory_or_register(sig_ptr, sig_len)?; if vec.len() != 64 { return Err(VMLogicError::HostError(HostError::ECRecoverError { @@ -1034,7 +1034,7 @@ impl<'a> VMLogic<'a> { if v < 4 { bytes[64] = v as u8; - Secp256K1Signature::from(bytes) + bytes } else { return Err(VMLogicError::HostError(HostError::ECRecoverError { msg: format!("V recovery byte 0 through 3 are valid but was provided {}", v), @@ -1058,16 +1058,13 @@ impl<'a> VMLogic<'a> { bytes }; - if !signature.check_signature_values(malleability_flag != 0) { - return Ok(false as u64); + match ecrecover(signature_data, hash, malleability_flag) { + Some(key) => { + self.internal_write_register(register_id, key.as_ref().to_vec())?; + Ok(true as u64) + } + None => Ok(false as u64), } - - if let Ok(pk) = signature.recover(hash) { - self.internal_write_register(register_id, pk.as_ref().to_vec())?; - return Ok(true as u64); - }; - - Ok(false as u64) } /// Called by gas metering injected into Wasm. Counts both towards `burnt_gas` and `used_gas`. @@ -2585,3 +2582,22 @@ impl std::fmt::Debug for VMOutcome { ) } } + +#[cfg(feature = "protocol_feature_math_extension")] +pub fn ecrecover( + signature_data: [u8; 65], + hash_data: [u8; 32], + malleability_flag: u64, +) -> Option { + let signature = Secp256K1Signature::from(signature_data); + if !signature.check_signature_values(malleability_flag != 0) { + return None; + } + signature.recover(hash_data).map_or(None, |result| Some(result)) +} + +#[cfg(feature = "protocol_feature_math_extension")] +pub fn ripemd160(data: &[u8]) -> Vec { + use ripemd160::Digest; + ripemd160::Ripemd160::digest(data).as_slice().to_vec() +} diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index c3d904975f9..b907e283afc 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -46,6 +46,7 @@ once_cell = "1" num-traits = "0.2.12" libc = "0.2.81" wabt = "0.9" +ripemd160 = "0.9.0" [features] default = ["costs_counting"] diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 978263e453f..239623b92d5 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -617,7 +617,7 @@ pub fn run(mut config: Config, only_compile: bool) -> RuntimeConfig { // m.plot(PathBuf::from(&config.state_dump_path).as_path()); } -fn ratio_to_gas(gas_metric: GasMetric, value: Ratio) -> u64 { +pub(crate) fn ratio_to_gas(gas_metric: GasMetric, value: Ratio) -> u64 { let divisor = match gas_metric { // We use factor of 8 to approximately match the price of SHA256 operation between // time-based and icount-based metric as measured on 3.2Ghz Core i5. diff --git a/runtime/runtime-params-estimator/src/lib.rs b/runtime/runtime-params-estimator/src/lib.rs index 6dd7e9ce7fd..1e9a03e8df3 100644 --- a/runtime/runtime-params-estimator/src/lib.rs +++ b/runtime/runtime-params-estimator/src/lib.rs @@ -1,3 +1,7 @@ +use std::path::Path; + +use once_cell::sync::OnceCell; + /// Lists all cases that we want to measure. pub mod cases; // Generates runtime fees from the measurements. @@ -12,12 +16,9 @@ pub mod stats; pub mod testbed; // Prepares transactions and feeds them to the testbed in batches. Performs the warm up, takes care // of nonces. +mod math_ops_cost; pub mod testbed_runners; -use std::path::Path; - -use once_cell::sync::OnceCell; - /// Lazily loads contract's code from a directory in the source tree. pub(crate) struct TestContract { path: &'static str, diff --git a/runtime/runtime-params-estimator/src/math_ops_cost.rs b/runtime/runtime-params-estimator/src/math_ops_cost.rs new file mode 100644 index 00000000000..e1da4444b50 --- /dev/null +++ b/runtime/runtime-params-estimator/src/math_ops_cost.rs @@ -0,0 +1,101 @@ +#[cfg(feature = "protocol_feature_math_extension")] +mod math_ops_cost { + use crate::cases::{ratio_to_gas, ratio_to_gas_signed}; + use crate::testbed_runners::{end_count, start_count, GasMetric}; + use crate::vm_estimator::least_squares_method; + use near_primitives::num_rational::Ratio; + use near_vm_logic::{ecrecover, ripemd160}; + + #[derive(Debug)] + pub struct EvmMathCosts { + ripemd160_base: i64, + ripemd160_per_byte: i64, + ecrecover_base: i64, + } + + #[used] + static mut SINK: i64 = 0; + + fn measure_operation i64>( + gas_metric: GasMetric, + count: usize, + op: F, + ) -> u64 { + let start = start_count(gas_metric); + let result = op(count); + let end = end_count(gas_metric, &start); + // Do this to ensure call to measurer isn't optimized away. + unsafe { + SINK = result; + } + end + } + + fn compute_ripemd160_cost(gas_metric: GasMetric) -> (i64, i64) { + let mut xs = vec![]; + let mut ys = vec![]; + for i in vec![3, 30, 300, 30000] { + xs.push(i as u64); + ys.push(measure_operation(gas_metric, i, |repeat| { + let value = vec![1u8; repeat]; + let digest = ripemd160(&value); + digest.as_slice()[0] as i64 + })); + } + + let (a, b, _err) = least_squares_method(&xs, &ys); + (ratio_to_gas_signed(gas_metric, a), ratio_to_gas_signed(gas_metric, b)) + } + + fn compute_ecrecover_base(gas_metric: GasMetric) -> i64 { + let cost = measure_operation(gas_metric, 1, |_| do_ecrecover()); + ratio_to_gas(gas_metric, Ratio::new(cost, 1)) as i64 + } + + fn do_ecrecover() -> i64 { + let hash: [u8; 32] = [ + 0x7d, 0xba, 0xf5, 0x58, 0xb0, 0xa1, 0xa5, 0xdc, 0x7a, 0x67, 0x20, 0x21, 0x17, 0xab, + 0x14, 0x3c, 0x1d, 0x86, 0x05, 0xa9, 0x83, 0xe4, 0xa7, 0x43, 0xbc, 0x06, 0xfc, 0xc0, + 0x31, 0x62, 0xdc, 0x0d, + ]; + let signature: [u8; 65] = [ + 0x5d, 0x99, 0xb6, 0xf7, 0xf6, 0xd1, 0xf7, 0x3d, 0x1a, 0x26, 0x49, 0x7f, 0x2b, 0x1c, + 0x89, 0xb2, 0x4c, 0x09, 0x93, 0x91, 0x3f, 0x86, 0xe9, 0xa2, 0xd0, 0x2c, 0xd6, 0x98, + 0x87, 0xd9, 0xc9, 0x4f, 0x3c, 0x88, 0x03, 0x58, 0x57, 0x9d, 0x81, 0x1b, 0x21, 0xdd, + 0x1b, 0x7f, 0xd9, 0xbb, 0x01, 0xc1, 0xd8, 0x1d, 0x10, 0xe6, 0x9f, 0x03, 0x84, 0xe6, + 0x75, 0xc3, 0x2b, 0x39, 0x64, 0x3b, 0xe8, 0x92, /* version */ 0, + ]; + let result = ecrecover(signature, hash, 0).unwrap(); + result.as_ref()[0] as i64 + } + + pub fn cost_of_math(gas_metric: GasMetric) -> EvmMathCosts { + #[cfg(debug_assertions)] + println!("WARNING: must run in release mode to provide accurate results!"); + let (ripemd160_base, ripemd160_per_byte) = compute_ripemd160_cost(gas_metric); + let ecrecover_base = compute_ecrecover_base(gas_metric); + EvmMathCosts { ripemd160_base, ripemd160_per_byte, ecrecover_base } + } + + #[test] + fn test_math_cost_time() { + // cargo test --release --features protocol_feature_math_extension \ + // --package runtime-params-estimator \ + // --lib math_ops_cost::math_ops_cost::test_math_cost_time \ + // -- --exact --nocapture + println!("{:?}", cost_of_math(GasMetric::Time)); + } + + #[test] + fn test_math_cost_icount() { + // CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER=./runner.sh cargo test --release \ + // --features protocol_feature_math_extension \ + // --package runtime-params-estimator \ + // --lib math_ops_cost::math_ops_cost::test_math_cost_icount \ + // -- --exact --nocapture + // Where runner.sh is + // /host/nearcore/runtime/runtime-params-estimator/emu-cost/counter_plugin/qemu-x86_64 \ + // -cpu Westmere-v1 -plugin file=/host/nearcore/runtime/runtime-params-estimator/emu-cost/counter_plugin/libcounter.so $@ + println!("{:?}", cost_of_math(GasMetric::ICount)); + } +} diff --git a/runtime/runtime-params-estimator/src/vm_estimator.rs b/runtime/runtime-params-estimator/src/vm_estimator.rs index 00d266d6e38..35cab478cf5 100644 --- a/runtime/runtime-params-estimator/src/vm_estimator.rs +++ b/runtime/runtime-params-estimator/src/vm_estimator.rs @@ -23,7 +23,7 @@ const SIGNER_ACCOUNT_ID: &str = "bob"; const SIGNER_ACCOUNT_PK: [u8; 3] = [0, 1, 2]; const PREDECESSOR_ACCOUNT_ID: &str = "carol"; -fn create_context(input: Vec) -> VMContext { +pub(crate) fn create_context(input: Vec) -> VMContext { VMContext { current_account_id: CURRENT_ACCOUNT_ID.to_owned(), signer_account_id: SIGNER_ACCOUNT_ID.to_owned(), @@ -162,7 +162,10 @@ impl CompiledContractCache for MockCompiledContractCache { } } -fn least_squares_method(xs: &Vec, ys: &Vec) -> (Ratio, Ratio, Vec) { +pub(crate) fn least_squares_method( + xs: &Vec, + ys: &Vec, +) -> (Ratio, Ratio, Vec) { let n = xs.len(); let n128 = n as i128; diff --git a/runtime/runtime/src/lib.rs b/runtime/runtime/src/lib.rs index 81f87dd7b92..bc0baee0c9d 100644 --- a/runtime/runtime/src/lib.rs +++ b/runtime/runtime/src/lib.rs @@ -1,5 +1,7 @@ use std::cmp::max; use std::collections::{HashMap, HashSet}; +use std::rc::Rc; +use std::sync::Arc; use log::debug; @@ -7,7 +9,16 @@ use near_chain_configs::Genesis; pub use near_crypto; use near_crypto::PublicKey; pub use near_primitives; +#[cfg(feature = "sandbox")] +use near_primitives::contract::ContractCode; +pub use near_primitives::runtime::apply_state::ApplyState; +use near_primitives::runtime::fees::RuntimeFeesConfig; use near_primitives::runtime::get_insufficient_storage_stake; +use near_primitives::runtime::migration_data::{MigrationData, MigrationFlags}; +use near_primitives::transaction::ExecutionMetadata; +use near_primitives::version::{ + is_implicit_account_creation_enabled, ProtocolFeature, ProtocolVersion, +}; use near_primitives::{ account::Account, errors::{ActionError, ActionErrorKind, RuntimeError, TxExecutionError}, @@ -50,17 +61,6 @@ use crate::config::{ use crate::genesis::{GenesisStateApplier, StorageComputer}; use crate::verifier::validate_receipt; pub use crate::verifier::{validate_transaction, verify_and_charge_transaction}; -#[cfg(feature = "sandbox")] -use near_primitives::contract::ContractCode; -pub use near_primitives::runtime::apply_state::ApplyState; -use near_primitives::runtime::fees::RuntimeFeesConfig; -use near_primitives::runtime::migration_data::{MigrationData, MigrationFlags}; -use near_primitives::transaction::ExecutionMetadata; -use near_primitives::version::{ - is_implicit_account_creation_enabled, ProtocolFeature, ProtocolVersion, -}; -use std::rc::Rc; -use std::sync::Arc; mod actions; pub mod adapter; @@ -1443,7 +1443,7 @@ impl Runtime { #[cfg(test)] mod tests { - use super::*; + use std::sync::Arc; use near_crypto::{InMemorySigner, KeyType, Signer}; use near_primitives::account::AccessKey; @@ -1459,9 +1459,10 @@ mod tests { use near_store::set_access_key; use near_store::test_utils::create_tries; use near_store::StoreCompiledContractCache; - use std::sync::Arc; use testlib::runtime_utils::{alice_account, bob_account}; + use super::*; + const GAS_PRICE: Balance = 5000; fn to_yocto(near: Balance) -> Balance {