Skip to content

[WIP] Sve implementation #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ harness = false
[features]
default = ["blake3/default", "std", "winter_crypto/default", "winter_math/default", "winter_utils/default"]
std = ["blake3/std", "winter_crypto/std", "winter_math/std", "winter_utils/std"]
sve_backend = []

[dependencies]
blake3 = { version = "1.3", default-features = false }
cfg-if = "1.0.0"
winter_crypto = { version = "0.6", package = "winter-crypto", default-features = false }
winter_math = { version = "0.6", package = "winter-math", default-features = false }
winter_utils = { version = "0.6", package = "winter-utils", default-features = false }
Expand All @@ -38,3 +40,6 @@ winter_utils = { version = "0.6", package = "winter-utils", default-features = f
criterion = { version = "0.5", features = ["html_reports"] }
proptest = "1.1.0"
rand_utils = { version = "0.6", package = "winter-rand-utils" }

[build-dependencies]
cc = "1.0.79"
18 changes: 18 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fn main() {
#[cfg(feature = "sve_backend")]
compile_sve_backend();
}

#[cfg(feature = "sve_backend")]
fn compile_sve_backend() {
println!("cargo:rerun-if-changed=sve/src/sve_inv_sbox.c");
println!("cargo:rerun-if-changed=sve/src/sve_inv_sbox.h");
println!("cargo:rerun-if-changed=sve/src/inv_sbox.h");
println!("cargo:rerun-if-changed=sve/src/inv_sbox.h");

cc::Build::new()
.file("sve/src/sve_inv_sbox.c")
.file("sve/src/inv_sbox.c")
.flag("-march=armv8-a+sve")
.compile("sve");
}
18 changes: 17 additions & 1 deletion src/hash/rpo/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use super::{Digest, ElementHasher, Felt, FieldElement, Hasher, StarkField, ONE, ZERO};
use core::{convert::TryInto, ops::Range};
#[cfg(feature = "sve_backend")]
use winter_math::fields::f64::BaseElement;

mod digest;
pub use digest::RpoDigest;
Expand All @@ -10,6 +12,12 @@ use mds_freq::mds_multiply_freq;
#[cfg(test)]
mod tests;

#[cfg(feature = "sve_backend")]
#[link(name = "sve", kind = "static")]
extern "C" {
fn sve_apply_inv_sbox(state: *mut std::ffi::c_ulong);
}

// CONSTANTS
// ================================================================================================

Expand Down Expand Up @@ -351,7 +359,15 @@ impl Rpo256 {
// apply second half of RPO round
Self::apply_mds(state);
Self::add_constants(state, &ARK2[round]);
Self::apply_inv_sbox(state);
cfg_if::cfg_if! {
if #[cfg(feature = "sve_backend")] {
unsafe {
sve_apply_inv_sbox(std::mem::transmute::<*mut BaseElement, *mut u64>(state.as_mut_ptr()));
}
} else {
Self::apply_inv_sbox(state);
}
}
}

// HELPER FUNCTIONS
Expand Down
46 changes: 44 additions & 2 deletions src/hash/rpo/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,56 @@ fn test_sbox() {
assert_eq!(expected, actual);
}

#[cfg(feature = "sve_backend")]
#[link(name = "sve", kind = "static")]
extern "C" {
fn apply_inv_sbox_c(state: *mut std::ffi::c_ulong);
fn sve_apply_inv_sbox(state: *mut std::ffi::c_ulong);
}

#[test]
fn test_inv_sbox() {
let state = [Felt::new(rand_value()); STATE_WIDTH];
let state: [Felt; STATE_WIDTH] = [
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
Felt::new(rand_value()),
];

let mut expected = state;
expected.iter_mut().for_each(|v| *v = v.exp(INV_ALPHA));

let mut actual = state;

cfg_if::cfg_if! {
if #[cfg(feature = "sve_backend")] {
let mut actual_c: [u64; STATE_WIDTH] = [0; STATE_WIDTH];
for i in 0..STATE_WIDTH {
actual_c[i] = actual[i].inner();
}

let mut actual_c_sve: [u64; STATE_WIDTH] = [0; STATE_WIDTH];
for i in 0..STATE_WIDTH {
actual_c_sve[i] = actual[i].inner();
}
unsafe {
apply_inv_sbox_c(actual_c.as_mut_ptr());
sve_apply_inv_sbox(actual_c_sve.as_mut_ptr());
}

let expected_as_u64_vec: Vec<u64> = expected.iter().map(|s| s.inner()).collect();
assert_eq!(expected_as_u64_vec, actual_c);
assert_eq!(expected_as_u64_vec, actual_c_sve);
}
}

Rpo256::apply_inv_sbox(&mut actual);

assert_eq!(expected, actual);
Expand Down
6 changes: 6 additions & 0 deletions sve/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
UseTab: ForIndentation
IndentWidth: 8
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 120
43 changes: 43 additions & 0 deletions sve/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.PHONY: clean fmt

TARGET=test_sve

CC=cc
CFLAGS=-std=c99 -march=armv8-a+sve -Wall -Wextra -pedantic -g -O0
LN_FLAGS=

BUILD_DIR=./build
SRC_DIR=./src

SOURCE = $(wildcard $(SRC_DIR)/*.c)
HEADERS = $(wildcard $(SRC_DIR)/*.h)
OBJECTS = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SOURCE))

# Gcc/Clang will create these .d files containing dependencies.
DEP = $(OBJECTS:%.o=%.d)

default: $(TARGET)

$(TARGET): $(BUILD_DIR)/$(TARGET)

$(BUILD_DIR)/$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $(LN_FLAGS) $^ -o $@

-include $(DEP)

# The potential dependency on header files is covered
# by calling `-include $(DEP)`.
# The -MMD flags additionaly creates a .d file with
# the same name as the .o file.
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -MMD -c $< -o $@

test: $(TARGET)
$(BUILD_DIR)/$(TARGET)

clean:
rm -rf $(BUILD_DIR)

fmt:
clang-format --style=file -i $(SOURCE) $(HEADERS)
Loading