Skip to content

Commit

Permalink
test(benchmark): add Poseidon2 benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
chokobole committed May 14, 2024
1 parent dae9041 commit add9078
Show file tree
Hide file tree
Showing 18 changed files with 3,142 additions and 807 deletions.
2,793 changes: 2,141 additions & 652 deletions Cargo.Bazel.lock

Large diffs are not rendered by default.

627 changes: 472 additions & 155 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ members = [
"benchmark/fft/bellman",
"benchmark/fft/halo2",
"benchmark/poseidon/arkworks",
"benchmark/poseidon2/horizen",
"benchmark/poseidon2/plonky3",
"tachyon/rs",
"vendors/halo2",
]
2 changes: 2 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ crates_repository(
"//benchmark/fft/bellman:Cargo.toml",
"//benchmark/fft/halo2:Cargo.toml",
"//benchmark/poseidon/arkworks:Cargo.toml",
"//benchmark/poseidon2/horizen:Cargo.toml",
"//benchmark/poseidon2/plonky3:Cargo.toml",
"//tachyon/rs:Cargo.toml",
"//vendors/halo2:Cargo.toml",
],
Expand Down
2 changes: 2 additions & 0 deletions benchmark/poseidon/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ load(
"tachyon_cc_library",
)

package(default_visibility = ["//benchmark/poseidon2:__pkg__"])

tachyon_cc_library(
name = "poseidon_config",
testonly = True,
Expand Down
48 changes: 48 additions & 0 deletions benchmark/poseidon2/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
load(
"//bazel:tachyon_cc.bzl",
"tachyon_cc_binary",
"tachyon_cc_library",
)

tachyon_cc_library(
name = "poseidon2_config",
testonly = True,
srcs = ["poseidon2_config.cc"],
hdrs = ["poseidon2_config.h"],
deps = [
"//tachyon/base/console",
"//tachyon/base/flag:flag_parser",
],
)

tachyon_cc_library(
name = "poseidon2_benchmark_runner",
testonly = True,
hdrs = ["poseidon2_benchmark_runner.h"],
deps = [
":poseidon2_config",
"//benchmark/poseidon:simple_poseidon_benchmark_reporter",
"//tachyon/base:logging",
"//tachyon/base/containers:container_util",
"//tachyon/base/time",
"//tachyon/c/base:type_traits_forward",
"//tachyon/c/math/elliptic_curves/bn/bn254:fr",
"//tachyon/crypto/hashes/sponge/poseidon2",
"//tachyon/crypto/hashes/sponge/poseidon2:poseidon2_horizen_external_matrix",
],
)

tachyon_cc_binary(
name = "poseidon2_benchmark",
testonly = True,
srcs = ["poseidon2_benchmark.cc"],
deps = [
":poseidon2_benchmark_runner",
":poseidon2_config",
"//benchmark/poseidon:simple_poseidon_benchmark_reporter",
"//benchmark/poseidon2/horizen",
"//benchmark/poseidon2/plonky3",
"//tachyon/c/math/elliptic_curves/bn/bn254:g1",
"//tachyon/math/elliptic_curves/bn/bn254:poseidon2",
],
)
Binary file added benchmark/poseidon2/Poseidon2 Benchmark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions benchmark/poseidon2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Poseidon2 Hash Benchmark

```
Run on 13th Gen Intel(R) Core(TM) i9-13900K (32 X 5500 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 2048 KiB (x16)
L3 Unified 36864 KiB (x1)
```

```shell
bazel run -c opt --//:has_openmp --//:has_rtti --//:has_matplotlib //benchmark/poseidon2:poseidon2_benchmark -- -p bn254_fr --vendor horizen --vendor plonky3
```

| Repetition | tachyon | horizen | plonky3 |
| :--------- | -------- | ------- | ------- |
| 0 | 1.2e-05 | 7e-06 | 1e-05 |
| 1 | 1.1e-05 | 4e-06 | 8e-06 |
| 2 | 1.1e-05 | 4e-06 | 8e-06 |
| 3 | 1.1e-05 | 3e-06 | 8e-06 |
| 4 | 1e-05 | 3e-06 | 7e-06 |
| 5 | 1.1e-05 | 3e-06 | 7e-06 |
| 6 | 1e-05 | 3e-06 | 7e-06 |
| 7 | 1e-05 | 3e-06 | 7e-06 |
| 8 | 1.1e-05 | 3e-06 | 7e-06 |
| 9 | 1e-05 | 3e-06 | 7e-06 |
| avg | 1.07e-05 | 3.6e-06 | 7.6e-06 |

![image](/benchmark/poseidon2/Poseidon2%20Benchmark.png)
13 changes: 13 additions & 0 deletions benchmark/poseidon2/horizen/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("@crate_index//:defs.bzl", "aliases", "all_crate_deps")
load("//bazel:tachyon_rust.bzl", "tachyon_rust_static_library")

tachyon_rust_static_library(
name = "horizen",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
proc_macro_deps = all_crate_deps(proc_macro = True),
visibility = ["//benchmark/poseidon2:__pkg__"],
deps = all_crate_deps(normal = True) + [
"//tachyon/rs:tachyon_rs",
],
)
21 changes: 21 additions & 0 deletions benchmark/poseidon2/horizen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "horizen_poseidon2_benchmark"
version = "0.0.1"
authors = ["The Tachyon Authors <tachyon-discuss@kroma.network>"]
edition = "2021"
rust-version = "1.56.1"
description = """
Horizen Poseidon2 Hash Benchmark
"""
license = "MIT OR Apache-2.0"
repository = "https://github.com/kroma-network/tachyon"
readme = "README.md"
categories = ["cryptography"]
keywords = ["tachyon", "benchmark", "horizen"]
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
zkhash = { git = "https://github.com/HorizenLabs/poseidon2.git", rev = "bb476b9" }
tachyon_rs = { path = "../../../tachyon/rs" }
22 changes: 22 additions & 0 deletions benchmark/poseidon2/horizen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use std::time::Instant;
use tachyon_rs::math::elliptic_curves::bn::bn254::Fr as CppFr;
use zkhash::{
fields::bn256::FpBN256,
poseidon2::{poseidon2::Poseidon2, poseidon2_instance_bn256::POSEIDON2_BN256_PARAMS},
};

#[no_mangle]
pub extern "C" fn run_poseidon_horizen(duration: *mut u64) -> *mut CppFr {
let poseidon = Poseidon2::new(&POSEIDON2_BN256_PARAMS);

let t = poseidon.get_t();
let input: Vec<FpBN256> = (0..t).map(|_i| FpBN256::from(0)).collect();

let start = Instant::now();
let state = poseidon.permutation(&input);
unsafe {
duration.write(start.elapsed().as_micros() as u64);
}

Box::into_raw(Box::new(state[1])) as *mut CppFr
}
13 changes: 13 additions & 0 deletions benchmark/poseidon2/plonky3/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("@crate_index//:defs.bzl", "aliases", "all_crate_deps")
load("//bazel:tachyon_rust.bzl", "tachyon_rust_static_library")

tachyon_rust_static_library(
name = "plonky3",
srcs = glob(["src/**/*.rs"]),
aliases = aliases(),
proc_macro_deps = all_crate_deps(proc_macro = True),
visibility = ["//benchmark/poseidon2:__pkg__"],
deps = all_crate_deps(normal = True) + [
"//tachyon/rs:tachyon_rs",
],
)
25 changes: 25 additions & 0 deletions benchmark/poseidon2/plonky3/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "plonky3_poseidon2_benchmark"
version = "0.0.1"
authors = ["The Tachyon Authors <tachyon-discuss@kroma.network>"]
edition = "2021"
description = """
Plonky3 Poseidon2 Hash Benchmark
"""
license = "MIT OR Apache-2.0"
repository = "https://github.com/kroma-network/tachyon"
readme = "README.md"
categories = ["cryptography"]
keywords = ["tachyon", "benchmark", "plonky3"]
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ff = { version = "0.13", features = ["derive", "derive_bits"] }
p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
zkhash = { git = "https://github.com/HorizenLabs/poseidon2.git", rev = "bb476b9" }
tachyon_rs = { path = "../../../tachyon/rs" }
82 changes: 82 additions & 0 deletions benchmark/poseidon2/plonky3/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use ff::PrimeField;
use p3_bn254_fr::{Bn254Fr, DiffusionMatrixBN254, FFBn254Fr};
use p3_field::AbstractField;
use p3_poseidon2::{Poseidon2, Poseidon2ExternalMatrixHL};
use p3_symmetric::Permutation;
use std::time::Instant;
use tachyon_rs::math::elliptic_curves::bn::bn254::Fr as CppFr;
use zkhash::ark_ff::{BigInteger, PrimeField as ark_PrimeField};
use zkhash::fields::bn256::FpBN256 as ark_FpBN256;
use zkhash::poseidon2::poseidon2_instance_bn256::RC3;

fn bn254_from_ark_ff(input: ark_FpBN256) -> Bn254Fr {
let bytes = input.into_bigint().to_bytes_le();

let mut res = <FFBn254Fr as PrimeField>::Repr::default();

for (i, digit) in res.0.as_mut().iter_mut().enumerate() {
*digit = bytes[i];
}

let value = FFBn254Fr::from_repr(res);

if value.is_some().into() {
Bn254Fr {
value: value.unwrap(),
}
} else {
panic!("Invalid field element")
}
}

#[no_mangle]
pub extern "C" fn run_poseidon_plonky3(duration: *mut u64) -> *mut CppFr {
const WIDTH: usize = 3;
const D: u64 = 5;
const ROUNDS_F: usize = 8;
const ROUNDS_P: usize = 56;

// Copy over round constants from zkhash.
let mut round_constants: Vec<[Bn254Fr; WIDTH]> = RC3
.iter()
.map(|vec| {
vec.iter()
.cloned()
.map(bn254_from_ark_ff)
.collect::<Vec<_>>()
.try_into()
.unwrap()
})
.collect();
let internal_start = ROUNDS_F / 2;
let internal_end = (ROUNDS_F / 2) + ROUNDS_P;
let internal_round_constants = round_constants
.drain(internal_start..internal_end)
.map(|vec| vec[0])
.collect::<Vec<_>>();
let external_round_constants = round_constants;

let poseidon =
Poseidon2::<Bn254Fr, Poseidon2ExternalMatrixHL, DiffusionMatrixBN254, WIDTH, D>::new(
ROUNDS_F,
external_round_constants,
Poseidon2ExternalMatrixHL,
ROUNDS_P,
internal_round_constants,
DiffusionMatrixBN254,
);

let mut input = (0..3)
.map(|_i| Bn254Fr::zero())
.collect::<Vec<_>>()
.try_into()
.unwrap();

let start = Instant::now();
poseidon.permute_mut(&mut input);
unsafe {
duration.write(start.elapsed().as_micros() as u64);
}

Box::into_raw(Box::new(input[1])) as *mut CppFr
}
68 changes: 68 additions & 0 deletions benchmark/poseidon2/poseidon2_benchmark.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <iostream>

// clang-format off
#include "benchmark/poseidon/simple_poseidon_benchmark_reporter.h"
#include "benchmark/poseidon2/poseidon2_benchmark_runner.h"
#include "benchmark/poseidon2/poseidon2_config.h"
// clang-format on
#include "tachyon/base/logging.h"
#include "tachyon/c/math/elliptic_curves/bn/bn254/fr.h"
#include "tachyon/c/math/elliptic_curves/bn/bn254/g1.h"
#include "tachyon/crypto/hashes/sponge/poseidon2/poseidon2_config.h"
#include "tachyon/math/elliptic_curves/bn/bn254/fr.h"
#include "tachyon/math/elliptic_curves/bn/bn254/poseidon2.h"

namespace tachyon {

using namespace crypto;

using Field = math::bn254::Fr;

extern "C" tachyon_bn254_fr* run_poseidon_horizen(uint64_t* duration);
extern "C" tachyon_bn254_fr* run_poseidon_plonky3(uint64_t* duration);

int RealMain(int argc, char** argv) {
tachyon::Poseidon2Config config;
if (!config.Parse(argc, argv)) {
return 1;
}

Field::Init();
SimplePoseidonBenchmarkReporter reporter("Poseidon2 Benchmark",
config.repeating_num());
PoseidonBenchmarkRunner<Field> runner(&reporter, &config);

for (const tachyon::Poseidon2Config::Vendor vendor : config.vendors()) {
reporter.AddVendor(tachyon::Poseidon2Config::VendorToString(vendor));
}

crypto::Poseidon2Config<Field> poseidon2_config =
crypto::Poseidon2Config<Field>::CreateCustom(
2, 5, 8, 56, math::bn254::GetPoseidon2InternalDiagonalVector<3>());

Field result = runner.Run(poseidon2_config);
for (const tachyon::Poseidon2Config::Vendor vendor : config.vendors()) {
Field result_vendor;
switch (vendor) {
case tachyon::Poseidon2Config::Vendor::kHorizen:
result_vendor = runner.RunExternal(run_poseidon_horizen);
break;
case tachyon::Poseidon2Config::Vendor::kPlonky3:
result_vendor = runner.RunExternal(run_poseidon_plonky3);
break;
}

if (config.check_results()) {
CHECK_EQ(result, result_vendor) << "Result not matched";
}
}

reporter.AddAverageToLastRow();
reporter.Show();

return 0;
}

} // namespace tachyon

int main(int argc, char** argv) { return tachyon::RealMain(argc, argv); }

0 comments on commit add9078

Please sign in to comment.