Skip to content

Commit add9078

Browse files
committed
test(benchmark): add Poseidon2 benchmark
1 parent dae9041 commit add9078

18 files changed

+3142
-807
lines changed

Cargo.Bazel.lock

Lines changed: 2141 additions & 652 deletions
Large diffs are not rendered by default.

Cargo.lock

Lines changed: 472 additions & 155 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ members = [
77
"benchmark/fft/bellman",
88
"benchmark/fft/halo2",
99
"benchmark/poseidon/arkworks",
10+
"benchmark/poseidon2/horizen",
11+
"benchmark/poseidon2/plonky3",
1012
"tachyon/rs",
1113
"vendors/halo2",
1214
]

WORKSPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ crates_repository(
5555
"//benchmark/fft/bellman:Cargo.toml",
5656
"//benchmark/fft/halo2:Cargo.toml",
5757
"//benchmark/poseidon/arkworks:Cargo.toml",
58+
"//benchmark/poseidon2/horizen:Cargo.toml",
59+
"//benchmark/poseidon2/plonky3:Cargo.toml",
5860
"//tachyon/rs:Cargo.toml",
5961
"//vendors/halo2:Cargo.toml",
6062
],

benchmark/poseidon/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ load(
44
"tachyon_cc_library",
55
)
66

7+
package(default_visibility = ["//benchmark/poseidon2:__pkg__"])
8+
79
tachyon_cc_library(
810
name = "poseidon_config",
911
testonly = True,

benchmark/poseidon2/BUILD.bazel

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
load(
2+
"//bazel:tachyon_cc.bzl",
3+
"tachyon_cc_binary",
4+
"tachyon_cc_library",
5+
)
6+
7+
tachyon_cc_library(
8+
name = "poseidon2_config",
9+
testonly = True,
10+
srcs = ["poseidon2_config.cc"],
11+
hdrs = ["poseidon2_config.h"],
12+
deps = [
13+
"//tachyon/base/console",
14+
"//tachyon/base/flag:flag_parser",
15+
],
16+
)
17+
18+
tachyon_cc_library(
19+
name = "poseidon2_benchmark_runner",
20+
testonly = True,
21+
hdrs = ["poseidon2_benchmark_runner.h"],
22+
deps = [
23+
":poseidon2_config",
24+
"//benchmark/poseidon:simple_poseidon_benchmark_reporter",
25+
"//tachyon/base:logging",
26+
"//tachyon/base/containers:container_util",
27+
"//tachyon/base/time",
28+
"//tachyon/c/base:type_traits_forward",
29+
"//tachyon/c/math/elliptic_curves/bn/bn254:fr",
30+
"//tachyon/crypto/hashes/sponge/poseidon2",
31+
"//tachyon/crypto/hashes/sponge/poseidon2:poseidon2_horizen_external_matrix",
32+
],
33+
)
34+
35+
tachyon_cc_binary(
36+
name = "poseidon2_benchmark",
37+
testonly = True,
38+
srcs = ["poseidon2_benchmark.cc"],
39+
deps = [
40+
":poseidon2_benchmark_runner",
41+
":poseidon2_config",
42+
"//benchmark/poseidon:simple_poseidon_benchmark_reporter",
43+
"//benchmark/poseidon2/horizen",
44+
"//benchmark/poseidon2/plonky3",
45+
"//tachyon/c/math/elliptic_curves/bn/bn254:g1",
46+
"//tachyon/math/elliptic_curves/bn/bn254:poseidon2",
47+
],
48+
)
18.6 KB
Loading

benchmark/poseidon2/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Poseidon2 Hash Benchmark
2+
3+
```
4+
Run on 13th Gen Intel(R) Core(TM) i9-13900K (32 X 5500 MHz CPU s)
5+
CPU Caches:
6+
L1 Data 48 KiB (x16)
7+
L1 Instruction 32 KiB (x16)
8+
L2 Unified 2048 KiB (x16)
9+
L3 Unified 36864 KiB (x1)
10+
```
11+
12+
```shell
13+
bazel run -c opt --//:has_openmp --//:has_rtti --//:has_matplotlib //benchmark/poseidon2:poseidon2_benchmark -- -p bn254_fr --vendor horizen --vendor plonky3
14+
```
15+
16+
| Repetition | tachyon | horizen | plonky3 |
17+
| :--------- | -------- | ------- | ------- |
18+
| 0 | 1.2e-05 | 7e-06 | 1e-05 |
19+
| 1 | 1.1e-05 | 4e-06 | 8e-06 |
20+
| 2 | 1.1e-05 | 4e-06 | 8e-06 |
21+
| 3 | 1.1e-05 | 3e-06 | 8e-06 |
22+
| 4 | 1e-05 | 3e-06 | 7e-06 |
23+
| 5 | 1.1e-05 | 3e-06 | 7e-06 |
24+
| 6 | 1e-05 | 3e-06 | 7e-06 |
25+
| 7 | 1e-05 | 3e-06 | 7e-06 |
26+
| 8 | 1.1e-05 | 3e-06 | 7e-06 |
27+
| 9 | 1e-05 | 3e-06 | 7e-06 |
28+
| avg | 1.07e-05 | 3.6e-06 | 7.6e-06 |
29+
30+
![image](/benchmark/poseidon2/Poseidon2%20Benchmark.png)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
load("@crate_index//:defs.bzl", "aliases", "all_crate_deps")
2+
load("//bazel:tachyon_rust.bzl", "tachyon_rust_static_library")
3+
4+
tachyon_rust_static_library(
5+
name = "horizen",
6+
srcs = glob(["src/**/*.rs"]),
7+
aliases = aliases(),
8+
proc_macro_deps = all_crate_deps(proc_macro = True),
9+
visibility = ["//benchmark/poseidon2:__pkg__"],
10+
deps = all_crate_deps(normal = True) + [
11+
"//tachyon/rs:tachyon_rs",
12+
],
13+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "horizen_poseidon2_benchmark"
3+
version = "0.0.1"
4+
authors = ["The Tachyon Authors <tachyon-discuss@kroma.network>"]
5+
edition = "2021"
6+
rust-version = "1.56.1"
7+
description = """
8+
Horizen Poseidon2 Hash Benchmark
9+
"""
10+
license = "MIT OR Apache-2.0"
11+
repository = "https://github.com/kroma-network/tachyon"
12+
readme = "README.md"
13+
categories = ["cryptography"]
14+
keywords = ["tachyon", "benchmark", "horizen"]
15+
publish = false
16+
17+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
18+
19+
[dependencies]
20+
zkhash = { git = "https://github.com/HorizenLabs/poseidon2.git", rev = "bb476b9" }
21+
tachyon_rs = { path = "../../../tachyon/rs" }
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::time::Instant;
2+
use tachyon_rs::math::elliptic_curves::bn::bn254::Fr as CppFr;
3+
use zkhash::{
4+
fields::bn256::FpBN256,
5+
poseidon2::{poseidon2::Poseidon2, poseidon2_instance_bn256::POSEIDON2_BN256_PARAMS},
6+
};
7+
8+
#[no_mangle]
9+
pub extern "C" fn run_poseidon_horizen(duration: *mut u64) -> *mut CppFr {
10+
let poseidon = Poseidon2::new(&POSEIDON2_BN256_PARAMS);
11+
12+
let t = poseidon.get_t();
13+
let input: Vec<FpBN256> = (0..t).map(|_i| FpBN256::from(0)).collect();
14+
15+
let start = Instant::now();
16+
let state = poseidon.permutation(&input);
17+
unsafe {
18+
duration.write(start.elapsed().as_micros() as u64);
19+
}
20+
21+
Box::into_raw(Box::new(state[1])) as *mut CppFr
22+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
load("@crate_index//:defs.bzl", "aliases", "all_crate_deps")
2+
load("//bazel:tachyon_rust.bzl", "tachyon_rust_static_library")
3+
4+
tachyon_rust_static_library(
5+
name = "plonky3",
6+
srcs = glob(["src/**/*.rs"]),
7+
aliases = aliases(),
8+
proc_macro_deps = all_crate_deps(proc_macro = True),
9+
visibility = ["//benchmark/poseidon2:__pkg__"],
10+
deps = all_crate_deps(normal = True) + [
11+
"//tachyon/rs:tachyon_rs",
12+
],
13+
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "plonky3_poseidon2_benchmark"
3+
version = "0.0.1"
4+
authors = ["The Tachyon Authors <tachyon-discuss@kroma.network>"]
5+
edition = "2021"
6+
description = """
7+
Plonky3 Poseidon2 Hash Benchmark
8+
"""
9+
license = "MIT OR Apache-2.0"
10+
repository = "https://github.com/kroma-network/tachyon"
11+
readme = "README.md"
12+
categories = ["cryptography"]
13+
keywords = ["tachyon", "benchmark", "plonky3"]
14+
publish = false
15+
16+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
17+
18+
[dependencies]
19+
ff = { version = "0.13", features = ["derive", "derive_bits"] }
20+
p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
21+
p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
22+
p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
23+
p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "54069b1" }
24+
zkhash = { git = "https://github.com/HorizenLabs/poseidon2.git", rev = "bb476b9" }
25+
tachyon_rs = { path = "../../../tachyon/rs" }
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use ff::PrimeField;
2+
use p3_bn254_fr::{Bn254Fr, DiffusionMatrixBN254, FFBn254Fr};
3+
use p3_field::AbstractField;
4+
use p3_poseidon2::{Poseidon2, Poseidon2ExternalMatrixHL};
5+
use p3_symmetric::Permutation;
6+
use std::time::Instant;
7+
use tachyon_rs::math::elliptic_curves::bn::bn254::Fr as CppFr;
8+
use zkhash::ark_ff::{BigInteger, PrimeField as ark_PrimeField};
9+
use zkhash::fields::bn256::FpBN256 as ark_FpBN256;
10+
use zkhash::poseidon2::poseidon2_instance_bn256::RC3;
11+
12+
fn bn254_from_ark_ff(input: ark_FpBN256) -> Bn254Fr {
13+
let bytes = input.into_bigint().to_bytes_le();
14+
15+
let mut res = <FFBn254Fr as PrimeField>::Repr::default();
16+
17+
for (i, digit) in res.0.as_mut().iter_mut().enumerate() {
18+
*digit = bytes[i];
19+
}
20+
21+
let value = FFBn254Fr::from_repr(res);
22+
23+
if value.is_some().into() {
24+
Bn254Fr {
25+
value: value.unwrap(),
26+
}
27+
} else {
28+
panic!("Invalid field element")
29+
}
30+
}
31+
32+
#[no_mangle]
33+
pub extern "C" fn run_poseidon_plonky3(duration: *mut u64) -> *mut CppFr {
34+
const WIDTH: usize = 3;
35+
const D: u64 = 5;
36+
const ROUNDS_F: usize = 8;
37+
const ROUNDS_P: usize = 56;
38+
39+
// Copy over round constants from zkhash.
40+
let mut round_constants: Vec<[Bn254Fr; WIDTH]> = RC3
41+
.iter()
42+
.map(|vec| {
43+
vec.iter()
44+
.cloned()
45+
.map(bn254_from_ark_ff)
46+
.collect::<Vec<_>>()
47+
.try_into()
48+
.unwrap()
49+
})
50+
.collect();
51+
let internal_start = ROUNDS_F / 2;
52+
let internal_end = (ROUNDS_F / 2) + ROUNDS_P;
53+
let internal_round_constants = round_constants
54+
.drain(internal_start..internal_end)
55+
.map(|vec| vec[0])
56+
.collect::<Vec<_>>();
57+
let external_round_constants = round_constants;
58+
59+
let poseidon =
60+
Poseidon2::<Bn254Fr, Poseidon2ExternalMatrixHL, DiffusionMatrixBN254, WIDTH, D>::new(
61+
ROUNDS_F,
62+
external_round_constants,
63+
Poseidon2ExternalMatrixHL,
64+
ROUNDS_P,
65+
internal_round_constants,
66+
DiffusionMatrixBN254,
67+
);
68+
69+
let mut input = (0..3)
70+
.map(|_i| Bn254Fr::zero())
71+
.collect::<Vec<_>>()
72+
.try_into()
73+
.unwrap();
74+
75+
let start = Instant::now();
76+
poseidon.permute_mut(&mut input);
77+
unsafe {
78+
duration.write(start.elapsed().as_micros() as u64);
79+
}
80+
81+
Box::into_raw(Box::new(input[1])) as *mut CppFr
82+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <iostream>
2+
3+
// clang-format off
4+
#include "benchmark/poseidon/simple_poseidon_benchmark_reporter.h"
5+
#include "benchmark/poseidon2/poseidon2_benchmark_runner.h"
6+
#include "benchmark/poseidon2/poseidon2_config.h"
7+
// clang-format on
8+
#include "tachyon/base/logging.h"
9+
#include "tachyon/c/math/elliptic_curves/bn/bn254/fr.h"
10+
#include "tachyon/c/math/elliptic_curves/bn/bn254/g1.h"
11+
#include "tachyon/crypto/hashes/sponge/poseidon2/poseidon2_config.h"
12+
#include "tachyon/math/elliptic_curves/bn/bn254/fr.h"
13+
#include "tachyon/math/elliptic_curves/bn/bn254/poseidon2.h"
14+
15+
namespace tachyon {
16+
17+
using namespace crypto;
18+
19+
using Field = math::bn254::Fr;
20+
21+
extern "C" tachyon_bn254_fr* run_poseidon_horizen(uint64_t* duration);
22+
extern "C" tachyon_bn254_fr* run_poseidon_plonky3(uint64_t* duration);
23+
24+
int RealMain(int argc, char** argv) {
25+
tachyon::Poseidon2Config config;
26+
if (!config.Parse(argc, argv)) {
27+
return 1;
28+
}
29+
30+
Field::Init();
31+
SimplePoseidonBenchmarkReporter reporter("Poseidon2 Benchmark",
32+
config.repeating_num());
33+
PoseidonBenchmarkRunner<Field> runner(&reporter, &config);
34+
35+
for (const tachyon::Poseidon2Config::Vendor vendor : config.vendors()) {
36+
reporter.AddVendor(tachyon::Poseidon2Config::VendorToString(vendor));
37+
}
38+
39+
crypto::Poseidon2Config<Field> poseidon2_config =
40+
crypto::Poseidon2Config<Field>::CreateCustom(
41+
2, 5, 8, 56, math::bn254::GetPoseidon2InternalDiagonalVector<3>());
42+
43+
Field result = runner.Run(poseidon2_config);
44+
for (const tachyon::Poseidon2Config::Vendor vendor : config.vendors()) {
45+
Field result_vendor;
46+
switch (vendor) {
47+
case tachyon::Poseidon2Config::Vendor::kHorizen:
48+
result_vendor = runner.RunExternal(run_poseidon_horizen);
49+
break;
50+
case tachyon::Poseidon2Config::Vendor::kPlonky3:
51+
result_vendor = runner.RunExternal(run_poseidon_plonky3);
52+
break;
53+
}
54+
55+
if (config.check_results()) {
56+
CHECK_EQ(result, result_vendor) << "Result not matched";
57+
}
58+
}
59+
60+
reporter.AddAverageToLastRow();
61+
reporter.Show();
62+
63+
return 0;
64+
}
65+
66+
} // namespace tachyon
67+
68+
int main(int argc, char** argv) { return tachyon::RealMain(argc, argv); }

0 commit comments

Comments
 (0)