This repository provides a comprehensive framework for measuring and verifying the performance and security properties of cryptographic assembly implementations, with a focus on CryptOpt-generated code.
This project combines:
For each algorithm, we test:
# Install build tools
sudo apt-get install clang nasm build-essential
# Install OPAM and BINSEC (for formal verification)
bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
opam init
opam install binsec
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Build all assembly implementations
cargo build
# Build with formal verification enabled
CARGO_BINSEC_VALIDATE=1 cargo build
# Build with statistical testing enabled
CARGO_DUDECT_VALIDATE=1 cargo build
# Make helper scripts executable
chmod +x setup_benchmark_environment.sh
chmod +x verify_benchmark_environment.sh || true
chmod +x restore_system_defaults.sh || true
# Configure reproducible environment (CPU governor, boost, optional SMT/ASLR, core pinning)
./setup_benchmark_environment.sh
# Verify current settings
./verify_benchmark_environment.sh
Optional: move IRQs off the benchmark core (reduces interrupt noise)
./move_irqs_off_core.sh
# Verify that the benchmark core is not in the affinity lists
grep -H . /proc/irq/*/smp_affinity_list | head -n 20
Notes:
This creates run_benchmark_pinned.sh which pins the benchmark to a dedicated CPU core to reduce noise.
cargo run --release <curve_name> <operation> [repeat_count]
# example
cargo run --release curve25519 mul 5
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release <curve_name> <operation> [repeat_count]
# example
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release curve25519 mul 5
In enhanced mode, each function is measured with a three-step warm-up matching the paper:
./restore_system_defaults.sh
curve25519, curve25519_dalek, p448, poly1305, secp256k1_dettman, secp256k1_rust_ec, bls12, fiat_c_curve25519, fiat_c_secp256k1_dettman, fiat_c_poly1305, fiat_c_p448, openssl_curve25519, openssl_p448mul, square (note: not all combinations are implemented)# Curve25519 multiply, 5 runs, enhanced mode with pinning
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release curve25519 mul 5
# P-448 square, 3 runs (if implemented for that variant)
cargo run --release p448 square 3
# OpenSSL fe51 multiply (5-way comparison path where available)
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release openssl_curve25519 mul 5
For additional details on methodology and warm-up, see ENHANCED_BENCHMARKING_METHODOLOGY.md.
# Verify all CryptOpt implementations
./verify_cryptopt_binsec.sh
# Enable verification during build
CARGO_BINSEC_VALIDATE=1 cargo build
# Run statistical constant-time tests
CARGO_DUDECT_VALIDATE=1 cargo build
# Results are shown during build
We use multiple timing approaches:
RDTSC-based Measurement
Statistical Analysis
CryptOpt-style Measurement
{
"function": "curve25519_mul_CryptOpt",
"cycles": {
"median": 45678,
"mean": 45890,
"std_dev": 234,
"min": 45123,
"max": 46789
},
"measurements": 1000
}
| Function | CFI | MAI | Status |
|----------|-----|-----|--------|
| curve25519_mul | 1/1 | 72/72 | ⚠ UNKNOWN (all checks pass) |
The framework automatically compares:
rust-assembly-measure/
├── src/
│ ├── main.rs # Main benchmark runner
│ ├── lib.rs # Core measurement library
│ ├── precise_timing.rs # RDTSC timing implementation
│ ├── cryptopt_timing.rs # CryptOpt-style measurements
│ ├── rust/ # Rust implementation assemblies
│ │ ├── curve25519/
│ │ │ ├── cryptopt/ # CryptOpt-generated
│ │ │ ├── llc/ # LLVM-generated
│ │ │ └── llc-nasm/ # NASM-ported
│ │ └── ...
│ └── c/ # C implementation assemblies
├── verify_cryptopt_binsec.sh # BINSEC verification script
├── build.rs # Build script with validations
├── dudect_integration.rs # Dudect statistical testing
└── binsec_integration.rs # BINSEC formal verification
// In your code
let config = TimingConfig {
warmup_iterations: 1000,
measurement_iterations: 10000,
outlier_threshold: 3.0, // Standard deviations
};
src/[rust|c]/algorithm_name/build.rs to compile new assembliessrc/lib.rssrc/main.rsCARGO_BINSEC_VALIDATE=1: Enable formal verification during buildCARGO_BINSEC_STRICT=1: Fail build if verification failsCARGO_DUDECT_VALIDATE=1: Enable statistical testing during buildCARGO_DUDECT_MEASUREMENTS=N: Set number of dudect measurementslogs/stub/: BINSEC verification logstarget/: Compiled binaries and librariesdudect-measurements/: Statistical test resultsThis is expected behavior. UNKNOWN with all checks passing means:
ud2 terminationsudo nice -n -20 cargo run --releaseeval $(opam env)find src -name "*.asm"When adding new implementations:
This project is licensed under the MIT License - see the LICENSE file for details.
59 commits
Assembly
76.5%
Rust
13.9%
Perl
4.7%
C
2.2%
Shell
1.4%
Python
1.3%
This repository provides a comprehensive framework for measuring and verifying the performance and security properties of cryptographic assembly implementations, with a focus on CryptOpt-generated code.
This project combines:
For each algorithm, we test:
# Install build tools
sudo apt-get install clang nasm build-essential
# Install OPAM and BINSEC (for formal verification)
bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
opam init
opam install binsec
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Build all assembly implementations
cargo build
# Build with formal verification enabled
CARGO_BINSEC_VALIDATE=1 cargo build
# Build with statistical testing enabled
CARGO_DUDECT_VALIDATE=1 cargo build
# Make helper scripts executable
chmod +x setup_benchmark_environment.sh
chmod +x verify_benchmark_environment.sh || true
chmod +x restore_system_defaults.sh || true
# Configure reproducible environment (CPU governor, boost, optional SMT/ASLR, core pinning)
./setup_benchmark_environment.sh
# Verify current settings
./verify_benchmark_environment.sh
Optional: move IRQs off the benchmark core (reduces interrupt noise)
./move_irqs_off_core.sh
# Verify that the benchmark core is not in the affinity lists
grep -H . /proc/irq/*/smp_affinity_list | head -n 20
Notes:
This creates run_benchmark_pinned.sh which pins the benchmark to a dedicated CPU core to reduce noise.
cargo run --release <curve_name> <operation> [repeat_count]
# example
cargo run --release curve25519 mul 5
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release <curve_name> <operation> [repeat_count]
# example
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release curve25519 mul 5
In enhanced mode, each function is measured with a three-step warm-up matching the paper:
./restore_system_defaults.sh
curve25519, curve25519_dalek, p448, poly1305, secp256k1_dettman, secp256k1_rust_ec, bls12, fiat_c_curve25519, fiat_c_secp256k1_dettman, fiat_c_poly1305, fiat_c_p448, openssl_curve25519, openssl_p448mul, square (note: not all combinations are implemented)# Curve25519 multiply, 5 runs, enhanced mode with pinning
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release curve25519 mul 5
# P-448 square, 3 runs (if implemented for that variant)
cargo run --release p448 square 3
# OpenSSL fe51 multiply (5-way comparison path where available)
ENHANCED_MEASUREMENT=1 ./run_benchmark_pinned.sh cargo run --release openssl_curve25519 mul 5
For additional details on methodology and warm-up, see ENHANCED_BENCHMARKING_METHODOLOGY.md.
# Verify all CryptOpt implementations
./verify_cryptopt_binsec.sh
# Enable verification during build
CARGO_BINSEC_VALIDATE=1 cargo build
# Run statistical constant-time tests
CARGO_DUDECT_VALIDATE=1 cargo build
# Results are shown during build
We use multiple timing approaches:
RDTSC-based Measurement
Statistical Analysis
CryptOpt-style Measurement
{
"function": "curve25519_mul_CryptOpt",
"cycles": {
"median": 45678,
"mean": 45890,
"std_dev": 234,
"min": 45123,
"max": 46789
},
"measurements": 1000
}
| Function | CFI | MAI | Status |
|----------|-----|-----|--------|
| curve25519_mul | 1/1 | 72/72 | ⚠ UNKNOWN (all checks pass) |
The framework automatically compares:
rust-assembly-measure/
├── src/
│ ├── main.rs # Main benchmark runner
│ ├── lib.rs # Core measurement library
│ ├── precise_timing.rs # RDTSC timing implementation
│ ├── cryptopt_timing.rs # CryptOpt-style measurements
│ ├── rust/ # Rust implementation assemblies
│ │ ├── curve25519/
│ │ │ ├── cryptopt/ # CryptOpt-generated
│ │ │ ├── llc/ # LLVM-generated
│ │ │ └── llc-nasm/ # NASM-ported
│ │ └── ...
│ └── c/ # C implementation assemblies
├── verify_cryptopt_binsec.sh # BINSEC verification script
├── build.rs # Build script with validations
├── dudect_integration.rs # Dudect statistical testing
└── binsec_integration.rs # BINSEC formal verification
// In your code
let config = TimingConfig {
warmup_iterations: 1000,
measurement_iterations: 10000,
outlier_threshold: 3.0, // Standard deviations
};
src/[rust|c]/algorithm_name/build.rs to compile new assembliessrc/lib.rssrc/main.rsCARGO_BINSEC_VALIDATE=1: Enable formal verification during buildCARGO_BINSEC_STRICT=1: Fail build if verification failsCARGO_DUDECT_VALIDATE=1: Enable statistical testing during buildCARGO_DUDECT_MEASUREMENTS=N: Set number of dudect measurementslogs/stub/: BINSEC verification logstarget/: Compiled binaries and librariesdudect-measurements/: Statistical test resultsThis is expected behavior. UNKNOWN with all checks passing means:
ud2 terminationsudo nice -n -20 cargo run --releaseeval $(opam env)find src -name "*.asm"When adding new implementations:
This project is licensed under the MIT License - see the LICENSE file for details.
59 commits
Assembly
76.5%
Rust
13.9%
Perl
4.7%
C
2.2%
Shell
1.4%
Python
1.3%