Skip to content

Commit

Permalink
Chore(precompiles): Include blake2 compression only (#528)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuajbouw committed Jun 8, 2022
1 parent 80fa35c commit 7035858
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 14 deletions.
11 changes: 0 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions engine-precompiles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ autobenches = false
aurora-engine-types = { path = "../engine-types", default-features = false }
aurora-engine-sdk = { path = "../engine-sdk", default-features = false }
base64 = { version = "0.13.0", default-features = false, features = ["alloc"] }
aurora-blake2 = { git = "https://github.com/aurora-is-near/aurora-blake2.git", version = "0.9.1", default-features = false }
borsh = { version = "0.8.2", default-features = false }
bn = { package = "aurora-bn", git = "https://github.com/aurora-is-near/aurora-bn.git", default-features = false }
evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", rev = "37448b6cacd98b06282cff5a559684505c29bd2b", default-features = false }
Expand All @@ -36,7 +35,7 @@ serde_json = "1"
rand = "0.7.3"

[features]
std = ["aurora-engine-types/std", "aurora-engine-sdk/std", "borsh/std", "aurora-blake2/std", "bn/std", "evm/std", "evm-core/std", "libsecp256k1/std", "ripemd160/std", "sha2/std", "sha3/std", "ethabi/std"]
std = ["aurora-engine-types/std", "aurora-engine-sdk/std", "borsh/std", "bn/std", "evm/std", "evm-core/std", "libsecp256k1/std", "ripemd160/std", "sha2/std", "sha3/std", "ethabi/std"]
contract = []
log = []
error_refund = []
113 changes: 112 additions & 1 deletion engine-precompiles/src/blake2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use evm::{Context, ExitError};
use crate::prelude::types::EthGas;
use crate::prelude::{mem, types::Address, Borrowed};
use crate::{EvmPrecompileResult, Precompile, PrecompileOutput};
use aurora_engine_types::Vec;

/// Blake2 costs.
mod costs {
Expand All @@ -15,6 +16,116 @@ mod costs {
/// Blake2 constants.
mod consts {
pub(super) const INPUT_LENGTH: usize = 213;

/// The precomputed SIGMA.
///
/// See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693#section-2.7) specification for more details.
pub(super) const SIGMA: [[usize; 16]; 10] = [
[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],
];

/// The initialization vector.
///
/// See [RFC 7693](https://tools.ietf.org/html/rfc7693#section-2.6) specification for more details.
pub(super) const IV: [u64; 8] = [
0x6a09e667f3bcc908,
0xbb67ae8584caa73b,
0x3c6ef372fe94f82b,
0xa54ff53a5f1d36f1,
0x510e527fade682d1,
0x9b05688c2b3e6c1f,
0x1f83d9abfb41bd6b,
0x5be0cd19137e2179,
];

// G rotation constants.

/// G rotation 1.
pub(super) const R1: u32 = 32;

/// G rotation 2.
pub(super) const R2: u32 = 24;

/// G rotation 3.
pub(super) const R3: u32 = 16;

/// G rotation 4.
pub(super) const R4: u32 = 63;
}

/// The G primitive function which mixes two input worlds, "x" and "y", into
/// four words indexed by "a", "b", "c", and "d" in the working vector v[0..15].
///
/// See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693#section-3.1) specification for more
/// details.
fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) {
v[a] = v[a].wrapping_add(v[b]).wrapping_add(x);
v[d] = (v[d] ^ v[a]).rotate_right(consts::R1);
v[c] = v[c].wrapping_add(v[d]);
v[b] = (v[b] ^ v[c]).rotate_right(consts::R2);
v[a] = v[a].wrapping_add(v[b]).wrapping_add(y);
v[d] = (v[d] ^ v[a]).rotate_right(consts::R3);
v[c] = v[c].wrapping_add(v[d]);
v[b] = (v[b] ^ v[c]).rotate_right(consts::R4);
}

/// 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.
///
/// See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693#section-3.2) specification for more
/// details.
fn f(mut h: [u64; 8], m: [u64; 16], t: [u64; 2], f: bool, rounds: u32) -> Vec<u8> {
// Initialize the work vector.
let mut v = [0u64; 16];
v[0..8].copy_from_slice(&h); // First half from state.
v[8..16].copy_from_slice(&consts::IV); // Second half from IV.

v[12] ^= t[0]; // Low word of the offset.
v[13] ^= t[1]; // High word.

if f {
// last block flag?
v[14] = !v[14] // Invert all bits.
}

for i in 0..rounds {
// Typically twelve rounds for blake2b.
// Message word selection permutation for this round.
let s = &consts::SIGMA[i as usize % 10];
g(&mut v, 0, 4, 8, 12, m[s[0]], m[s[1]]);
g(&mut v, 1, 5, 9, 13, m[s[2]], m[s[3]]);
g(&mut v, 2, 6, 10, 14, m[s[4]], m[s[5]]);
g(&mut v, 3, 7, 11, 15, m[s[6]], m[s[7]]);

g(&mut v, 0, 5, 10, 15, m[s[8]], m[s[9]]);
g(&mut v, 1, 6, 11, 12, m[s[10]], m[s[11]]);
g(&mut v, 2, 7, 8, 13, m[s[12]], m[s[13]]);
g(&mut v, 3, 4, 9, 14, m[s[14]], m[s[15]]);
}

for i in 0..8 {
// XOR the two halves.
h[i] ^= v[i] ^ v[i + 8];
}

let mut result = Vec::with_capacity(64);
for value in h {
result.extend_from_slice(&value.to_le_bytes());
}

result
}

pub(super) struct Blake2F;
Expand Down Expand Up @@ -94,7 +205,7 @@ impl Precompile for Blake2F {
}
let finished = input[212] != 0;

let output = aurora_blake2::blake2b_f(rounds, h, m, t, finished).to_vec();
let output = f(h, m, t, finished, rounds);
Ok(PrecompileOutput::without_logs(cost, output).into())
}
}
Expand Down

0 comments on commit 7035858

Please sign in to comment.