From d1797372db75ee29b411764132f3ec9f78569ae2 Mon Sep 17 00:00:00 2001 From: malik672 Date: Sat, 31 Jan 2026 05:54:57 +0100 Subject: [PATCH 1/5] rm unncesscary assert --- crates/precompile/src/blake2.rs | 43 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 91b12fcd25..6621267499 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -33,32 +33,39 @@ pub fn run(input: &[u8], gas_limit: u64) -> PrecompileResult { }; // Parse state vector h (8 × u64) - let mut h = [0u64; 8]; - input[4..68] - .chunks_exact(8) - .enumerate() - .for_each(|(i, chunk)| { - h[i] = u64::from_le_bytes(chunk.try_into().unwrap()); - }); + // SAFETY: input.len() == INPUT_LENGTH guarantees input[4..68] has 64 bytes + let mut h = unsafe { + core::array::from_fn(|i| { + let ptr = input.as_ptr().add(4 + i * 8) as *const u64; + u64::from_le(ptr.read_unaligned()) + }) + }; // Parse message block m (16 × u64) - let mut m = [0u64; 16]; - input[68..196] - .chunks_exact(8) - .enumerate() - .for_each(|(i, chunk)| { - m[i] = u64::from_le_bytes(chunk.try_into().unwrap()); - }); + let m = unsafe { + core::array::from_fn(|i| { + let ptr = input.as_ptr().add(68 + i * 8) as *const u64; + u64::from_le(ptr.read_unaligned()) + }) + }; // Parse offset counters - let t_0 = u64::from_le_bytes(input[196..204].try_into().unwrap()); - let t_1 = u64::from_le_bytes(input[204..212].try_into().unwrap()); + // SAFETY: input.len() == INPUT_LENGTH guarantees these ranges exist + let t_0 = unsafe { + let ptr = input.as_ptr().add(196) as *const u64; + u64::from_le(ptr.read_unaligned()) + }; + let t_1 = unsafe { + let ptr = input.as_ptr().add(204) as *const u64; + u64::from_le(ptr.read_unaligned()) + }; crypto().blake2_compress(rounds, &mut h, m, [t_0, t_1], f); let mut out = [0u8; 64]; - for (i, h) in (0..64).step_by(8).zip(h.iter()) { - out[i..i + 8].copy_from_slice(&h.to_le_bytes()); + for (i, &h_val) in h.iter().enumerate() { + let offset = i * 8; + out[offset..offset + 8].copy_from_slice(&h_val.to_le_bytes()); } Ok(PrecompileOutput::new(gas_used, out.into())) From 24c047360023ce2608f20d3fbb0b97c6b60574d1 Mon Sep 17 00:00:00 2001 From: malik672 Date: Sat, 31 Jan 2026 17:06:16 +0100 Subject: [PATCH 2/5] inline never removes 500 cycles per godbolt --- crates/precompile/src/blake2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 6621267499..cf3f918757 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -172,7 +172,7 @@ pub mod algo { } } - #[inline(always)] + #[inline(never)] fn round(v: &mut [u64; 16], m: &[u64; 16], r: usize) { // Message word selection permutation for this round. let s = &SIGMA[r % 10]; From 0fdb8e98f3a0800d54352ec84312e7858b9d1066 Mon Sep 17 00:00:00 2001 From: malik672 Date: Sat, 31 Jan 2026 17:16:04 +0100 Subject: [PATCH 3/5] revert inline never removes 500 cycles per godbolt --- crates/precompile/src/blake2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index cf3f918757..6621267499 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -172,7 +172,7 @@ pub mod algo { } } - #[inline(never)] + #[inline(always)] fn round(v: &mut [u64; 16], m: &[u64; 16], r: usize) { // Message word selection permutation for this round. let s = &SIGMA[r % 10]; From b76420e16ac954027069aa36d3bfc83462f8262a Mon Sep 17 00:00:00 2001 From: malik672 Date: Sat, 31 Jan 2026 18:36:11 +0100 Subject: [PATCH 4/5] godbolt 2000 --- crates/precompile/src/blake2.rs | 179 +++++++++++++++++++++++++------- 1 file changed, 143 insertions(+), 36 deletions(-) diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 6621267499..16f5635c3d 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -99,30 +99,30 @@ pub mod algo { 0x5be0cd19137e2179, ]; - #[inline(always)] - #[allow(clippy::many_single_char_names)] - /// G function: - fn g(v: &mut [u64; 16], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { - let mut va = v[a]; - let mut vb = v[b]; - let mut vc = v[c]; - let mut vd = v[d]; - - va = va.wrapping_add(vb).wrapping_add(x); - vd = (vd ^ va).rotate_right(32); - vc = vc.wrapping_add(vd); - vb = (vb ^ vc).rotate_right(24); - - va = va.wrapping_add(vb).wrapping_add(y); - vd = (vd ^ va).rotate_right(16); - vc = vc.wrapping_add(vd); - vb = (vb ^ vc).rotate_right(63); - - v[a] = va; - v[b] = vb; - v[c] = vc; - v[d] = vd; - } + // #[inline(always)] + // #[allow(clippy::many_single_char_names)] + // /// G function: + // fn g(v: &mut [u64; 16], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + // let mut va = v[a]; + // let mut vb = v[b]; + // let mut vc = v[c]; + // let mut vd = v[d]; + + // va = va.wrapping_add(vb).wrapping_add(x); + // vd = (vd ^ va).rotate_right(32); + // vc = vc.wrapping_add(vd); + // vb = (vb ^ vc).rotate_right(24); + + // va = va.wrapping_add(vb).wrapping_add(y); + // vd = (vd ^ va).rotate_right(16); + // vc = vc.wrapping_add(vd); + // vb = (vb ^ vc).rotate_right(63); + + // v[a] = va; + // v[b] = vb; + // v[c] = vc; + // v[d] = vd; + // } /// Compression function F takes as an argument the state vector "h", /// message block vector "m" (last block is padded with zeros to full @@ -173,20 +173,127 @@ pub mod algo { } #[inline(always)] + #[allow(clippy::many_single_char_names)] fn round(v: &mut [u64; 16], m: &[u64; 16], r: usize) { - // Message word selection permutation for this round. let s = &SIGMA[r % 10]; - // g1 - g(v, 0, 4, 8, 12, m[s[0]], m[s[1]]); - g(v, 1, 5, 9, 13, m[s[2]], m[s[3]]); - g(v, 2, 6, 10, 14, m[s[4]], m[s[5]]); - g(v, 3, 7, 11, 15, m[s[6]], m[s[7]]); - - // g2 - g(v, 0, 5, 10, 15, m[s[8]], m[s[9]]); - g(v, 1, 6, 11, 12, m[s[10]], m[s[11]]); - g(v, 2, 7, 8, 13, m[s[12]], m[s[13]]); - g(v, 3, 4, 9, 14, m[s[14]], m[s[15]]); + + // Load v elements into local variables to help register allocation + let mut v0 = v[0]; + let mut v1 = v[1]; + let mut v2 = v[2]; + let mut v3 = v[3]; + let mut v4 = v[4]; + let mut v5 = v[5]; + let mut v6 = v[6]; + let mut v7 = v[7]; + let mut v8 = v[8]; + let mut v9 = v[9]; + let mut v10 = v[10]; + let mut v11 = v[11]; + let mut v12 = v[12]; + let mut v13 = v[13]; + let mut v14 = v[14]; + let mut v15 = v[15]; + + // G function inlined - column round + // g(0, 4, 8, 12) + v0 = v0.wrapping_add(v4).wrapping_add(m[s[0]]); + v12 = (v12 ^ v0).rotate_right(32); + v8 = v8.wrapping_add(v12); + v4 = (v4 ^ v8).rotate_right(24); + v0 = v0.wrapping_add(v4).wrapping_add(m[s[1]]); + v12 = (v12 ^ v0).rotate_right(16); + v8 = v8.wrapping_add(v12); + v4 = (v4 ^ v8).rotate_right(63); + + // g(1, 5, 9, 13) + v1 = v1.wrapping_add(v5).wrapping_add(m[s[2]]); + v13 = (v13 ^ v1).rotate_right(32); + v9 = v9.wrapping_add(v13); + v5 = (v5 ^ v9).rotate_right(24); + v1 = v1.wrapping_add(v5).wrapping_add(m[s[3]]); + v13 = (v13 ^ v1).rotate_right(16); + v9 = v9.wrapping_add(v13); + v5 = (v5 ^ v9).rotate_right(63); + + // g(2, 6, 10, 14) + v2 = v2.wrapping_add(v6).wrapping_add(m[s[4]]); + v14 = (v14 ^ v2).rotate_right(32); + v10 = v10.wrapping_add(v14); + v6 = (v6 ^ v10).rotate_right(24); + v2 = v2.wrapping_add(v6).wrapping_add(m[s[5]]); + v14 = (v14 ^ v2).rotate_right(16); + v10 = v10.wrapping_add(v14); + v6 = (v6 ^ v10).rotate_right(63); + + // g(3, 7, 11, 15) + v3 = v3.wrapping_add(v7).wrapping_add(m[s[6]]); + v15 = (v15 ^ v3).rotate_right(32); + v11 = v11.wrapping_add(v15); + v7 = (v7 ^ v11).rotate_right(24); + v3 = v3.wrapping_add(v7).wrapping_add(m[s[7]]); + v15 = (v15 ^ v3).rotate_right(16); + v11 = v11.wrapping_add(v15); + v7 = (v7 ^ v11).rotate_right(63); + + // Diagonal round + // g(0, 5, 10, 15) + v0 = v0.wrapping_add(v5).wrapping_add(m[s[8]]); + v15 = (v15 ^ v0).rotate_right(32); + v10 = v10.wrapping_add(v15); + v5 = (v5 ^ v10).rotate_right(24); + v0 = v0.wrapping_add(v5).wrapping_add(m[s[9]]); + v15 = (v15 ^ v0).rotate_right(16); + v10 = v10.wrapping_add(v15); + v5 = (v5 ^ v10).rotate_right(63); + + // g(1, 6, 11, 12) + v1 = v1.wrapping_add(v6).wrapping_add(m[s[10]]); + v12 = (v12 ^ v1).rotate_right(32); + v11 = v11.wrapping_add(v12); + v6 = (v6 ^ v11).rotate_right(24); + v1 = v1.wrapping_add(v6).wrapping_add(m[s[11]]); + v12 = (v12 ^ v1).rotate_right(16); + v11 = v11.wrapping_add(v12); + v6 = (v6 ^ v11).rotate_right(63); + + // g(2, 7, 8, 13) + v2 = v2.wrapping_add(v7).wrapping_add(m[s[12]]); + v13 = (v13 ^ v2).rotate_right(32); + v8 = v8.wrapping_add(v13); + v7 = (v7 ^ v8).rotate_right(24); + v2 = v2.wrapping_add(v7).wrapping_add(m[s[13]]); + v13 = (v13 ^ v2).rotate_right(16); + v8 = v8.wrapping_add(v13); + v7 = (v7 ^ v8).rotate_right(63); + + // g(3, 4, 9, 14) + v3 = v3.wrapping_add(v4).wrapping_add(m[s[14]]); + v14 = (v14 ^ v3).rotate_right(32); + v9 = v9.wrapping_add(v14); + v4 = (v4 ^ v9).rotate_right(24); + v3 = v3.wrapping_add(v4).wrapping_add(m[s[15]]); + v14 = (v14 ^ v3).rotate_right(16); + v9 = v9.wrapping_add(v14); + v4 = (v4 ^ v9).rotate_right(63); + + // Write back all values + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + v[4] = v4; + v[5] = v5; + v[6] = v6; + v[7] = v7; + v[8] = v8; + v[9] = v9; + v[10] = v10; + v[11] = v11; + v[12] = v12; + v[13] = v13; + v[14] = v14; + v[15] = v15; } } From 6c2d50f69e691a5482701c897faf8e566142f27a Mon Sep 17 00:00:00 2001 From: malik672 Date: Sat, 31 Jan 2026 18:51:01 +0100 Subject: [PATCH 5/5] revert godbolt 2000 --- crates/precompile/src/blake2.rs | 179 +++++++------------------------- 1 file changed, 36 insertions(+), 143 deletions(-) diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 16f5635c3d..6621267499 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -99,30 +99,30 @@ pub mod algo { 0x5be0cd19137e2179, ]; - // #[inline(always)] - // #[allow(clippy::many_single_char_names)] - // /// G function: - // fn g(v: &mut [u64; 16], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { - // let mut va = v[a]; - // let mut vb = v[b]; - // let mut vc = v[c]; - // let mut vd = v[d]; - - // va = va.wrapping_add(vb).wrapping_add(x); - // vd = (vd ^ va).rotate_right(32); - // vc = vc.wrapping_add(vd); - // vb = (vb ^ vc).rotate_right(24); - - // va = va.wrapping_add(vb).wrapping_add(y); - // vd = (vd ^ va).rotate_right(16); - // vc = vc.wrapping_add(vd); - // vb = (vb ^ vc).rotate_right(63); - - // v[a] = va; - // v[b] = vb; - // v[c] = vc; - // v[d] = vd; - // } + #[inline(always)] + #[allow(clippy::many_single_char_names)] + /// G function: + fn g(v: &mut [u64; 16], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + let mut va = v[a]; + let mut vb = v[b]; + let mut vc = v[c]; + let mut vd = v[d]; + + va = va.wrapping_add(vb).wrapping_add(x); + vd = (vd ^ va).rotate_right(32); + vc = vc.wrapping_add(vd); + vb = (vb ^ vc).rotate_right(24); + + va = va.wrapping_add(vb).wrapping_add(y); + vd = (vd ^ va).rotate_right(16); + vc = vc.wrapping_add(vd); + vb = (vb ^ vc).rotate_right(63); + + v[a] = va; + v[b] = vb; + v[c] = vc; + v[d] = vd; + } /// Compression function F takes as an argument the state vector "h", /// message block vector "m" (last block is padded with zeros to full @@ -173,127 +173,20 @@ pub mod algo { } #[inline(always)] - #[allow(clippy::many_single_char_names)] fn round(v: &mut [u64; 16], m: &[u64; 16], r: usize) { + // Message word selection permutation for this round. let s = &SIGMA[r % 10]; - - // Load v elements into local variables to help register allocation - let mut v0 = v[0]; - let mut v1 = v[1]; - let mut v2 = v[2]; - let mut v3 = v[3]; - let mut v4 = v[4]; - let mut v5 = v[5]; - let mut v6 = v[6]; - let mut v7 = v[7]; - let mut v8 = v[8]; - let mut v9 = v[9]; - let mut v10 = v[10]; - let mut v11 = v[11]; - let mut v12 = v[12]; - let mut v13 = v[13]; - let mut v14 = v[14]; - let mut v15 = v[15]; - - // G function inlined - column round - // g(0, 4, 8, 12) - v0 = v0.wrapping_add(v4).wrapping_add(m[s[0]]); - v12 = (v12 ^ v0).rotate_right(32); - v8 = v8.wrapping_add(v12); - v4 = (v4 ^ v8).rotate_right(24); - v0 = v0.wrapping_add(v4).wrapping_add(m[s[1]]); - v12 = (v12 ^ v0).rotate_right(16); - v8 = v8.wrapping_add(v12); - v4 = (v4 ^ v8).rotate_right(63); - - // g(1, 5, 9, 13) - v1 = v1.wrapping_add(v5).wrapping_add(m[s[2]]); - v13 = (v13 ^ v1).rotate_right(32); - v9 = v9.wrapping_add(v13); - v5 = (v5 ^ v9).rotate_right(24); - v1 = v1.wrapping_add(v5).wrapping_add(m[s[3]]); - v13 = (v13 ^ v1).rotate_right(16); - v9 = v9.wrapping_add(v13); - v5 = (v5 ^ v9).rotate_right(63); - - // g(2, 6, 10, 14) - v2 = v2.wrapping_add(v6).wrapping_add(m[s[4]]); - v14 = (v14 ^ v2).rotate_right(32); - v10 = v10.wrapping_add(v14); - v6 = (v6 ^ v10).rotate_right(24); - v2 = v2.wrapping_add(v6).wrapping_add(m[s[5]]); - v14 = (v14 ^ v2).rotate_right(16); - v10 = v10.wrapping_add(v14); - v6 = (v6 ^ v10).rotate_right(63); - - // g(3, 7, 11, 15) - v3 = v3.wrapping_add(v7).wrapping_add(m[s[6]]); - v15 = (v15 ^ v3).rotate_right(32); - v11 = v11.wrapping_add(v15); - v7 = (v7 ^ v11).rotate_right(24); - v3 = v3.wrapping_add(v7).wrapping_add(m[s[7]]); - v15 = (v15 ^ v3).rotate_right(16); - v11 = v11.wrapping_add(v15); - v7 = (v7 ^ v11).rotate_right(63); - - // Diagonal round - // g(0, 5, 10, 15) - v0 = v0.wrapping_add(v5).wrapping_add(m[s[8]]); - v15 = (v15 ^ v0).rotate_right(32); - v10 = v10.wrapping_add(v15); - v5 = (v5 ^ v10).rotate_right(24); - v0 = v0.wrapping_add(v5).wrapping_add(m[s[9]]); - v15 = (v15 ^ v0).rotate_right(16); - v10 = v10.wrapping_add(v15); - v5 = (v5 ^ v10).rotate_right(63); - - // g(1, 6, 11, 12) - v1 = v1.wrapping_add(v6).wrapping_add(m[s[10]]); - v12 = (v12 ^ v1).rotate_right(32); - v11 = v11.wrapping_add(v12); - v6 = (v6 ^ v11).rotate_right(24); - v1 = v1.wrapping_add(v6).wrapping_add(m[s[11]]); - v12 = (v12 ^ v1).rotate_right(16); - v11 = v11.wrapping_add(v12); - v6 = (v6 ^ v11).rotate_right(63); - - // g(2, 7, 8, 13) - v2 = v2.wrapping_add(v7).wrapping_add(m[s[12]]); - v13 = (v13 ^ v2).rotate_right(32); - v8 = v8.wrapping_add(v13); - v7 = (v7 ^ v8).rotate_right(24); - v2 = v2.wrapping_add(v7).wrapping_add(m[s[13]]); - v13 = (v13 ^ v2).rotate_right(16); - v8 = v8.wrapping_add(v13); - v7 = (v7 ^ v8).rotate_right(63); - - // g(3, 4, 9, 14) - v3 = v3.wrapping_add(v4).wrapping_add(m[s[14]]); - v14 = (v14 ^ v3).rotate_right(32); - v9 = v9.wrapping_add(v14); - v4 = (v4 ^ v9).rotate_right(24); - v3 = v3.wrapping_add(v4).wrapping_add(m[s[15]]); - v14 = (v14 ^ v3).rotate_right(16); - v9 = v9.wrapping_add(v14); - v4 = (v4 ^ v9).rotate_right(63); - - // Write back all values - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - v[4] = v4; - v[5] = v5; - v[6] = v6; - v[7] = v7; - v[8] = v8; - v[9] = v9; - v[10] = v10; - v[11] = v11; - v[12] = v12; - v[13] = v13; - v[14] = v14; - v[15] = v15; + // g1 + g(v, 0, 4, 8, 12, m[s[0]], m[s[1]]); + g(v, 1, 5, 9, 13, m[s[2]], m[s[3]]); + g(v, 2, 6, 10, 14, m[s[4]], m[s[5]]); + g(v, 3, 7, 11, 15, m[s[6]], m[s[7]]); + + // g2 + g(v, 0, 5, 10, 15, m[s[8]], m[s[9]]); + g(v, 1, 6, 11, 12, m[s[10]], m[s[11]]); + g(v, 2, 7, 8, 13, m[s[12]], m[s[13]]); + g(v, 3, 4, 9, 14, m[s[14]], m[s[15]]); } }