-
Notifications
You must be signed in to change notification settings - Fork 82
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
Patch plonky3 to use Powdr accelerated Poseidon2 #2077
base: main
Are you sure you want to change the base?
Changes from all commits
c12b855
ac9ef63
6a475ce
d20ac5b
3a942b9
8717c18
a195792
9e2a884
b863969
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,9 @@ nightly-features = [ | |
"p3-mersenne-31/nightly-features", | ||
"p3-poseidon2/nightly-features", | ||
] | ||
# As a guest in powdr, use accelerated operations. | ||
# Silently ignored if target is not zkvm. | ||
powdr-accel = [] | ||
|
||
[dependencies] | ||
powdr-ast.workspace = true | ||
|
@@ -67,3 +70,12 @@ serde = { version = "1.0", default-features = false, features = [ | |
"alloc", | ||
] } | ||
|
||
[target.'cfg(all(target_os = "zkvm", target_arch = "riscv32"))'.dependencies] | ||
powdr-riscv-runtime = { path = "../riscv-runtime", features = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it would be good if these were also optional and a dependency of the feature There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then the feature would be required to build for powdr target. This way, the feature is just about the accelerated operations, and the target itself "just works". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah yea true, this is still imported by the guest's main or something closer to it which will have the import itself |
||
"std", | ||
"getrandom", | ||
"allow_fake_rand", | ||
] } | ||
indexmap = { version = "1.9.3", features = [ | ||
"std", | ||
] } | ||
leonardoalt marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#[cfg(not(all(feature = "powdr-accel", target_os = "zkvm", target_arch = "riscv32")))] | ||
mod software_impl; | ||
#[cfg(not(all(feature = "powdr-accel", target_os = "zkvm", target_arch = "riscv32")))] | ||
pub use software_impl::*; | ||
|
||
#[cfg(all(feature = "powdr-accel", target_os = "zkvm", target_arch = "riscv32"))] | ||
mod powdr_accel_impl; | ||
#[cfg(all(feature = "powdr-accel", target_os = "zkvm", target_arch = "riscv32"))] | ||
pub use powdr_accel_impl::*; | ||
|
||
use lazy_static::lazy_static; | ||
use p3_goldilocks::Goldilocks; | ||
use p3_poseidon2::poseidon2_round_numbers_128; | ||
|
||
// From: https://github.com/Plonky3/Plonky3/blob/64e79fe28c51ab35b509c68242256f253b61d612/poseidon2/benches/poseidon2.rs#L31 | ||
pub const D: u64 = 7; | ||
pub const WIDTH: usize = 8; | ||
|
||
lazy_static! { | ||
static ref ROUNDS: (usize, usize) = poseidon2_round_numbers_128::<Goldilocks>(WIDTH, D); | ||
pub static ref ROUNDS_F: usize = ROUNDS.0; | ||
pub static ref ROUNDS_P: usize = ROUNDS.1; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use lazy_static::lazy_static; | ||
use p3_field::AbstractField; | ||
use p3_goldilocks::Goldilocks; | ||
use p3_symmetric::CryptographicPermutation; | ||
use powdr_riscv_runtime::{ | ||
goldilocks::Goldilocks as PowdrGoldilocks, | ||
hash::{poseidon2_gl, poseidon2_gl_inplace}, | ||
}; | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub struct Permutation; | ||
|
||
impl p3_symmetric::Permutation<[Goldilocks; 8]> for Permutation { | ||
// Both Goldilocks and PowdrGoldilocks are repr(transparent), and both use | ||
// canonical representation internally, so it is safe to cast between their | ||
// array's references. | ||
// | ||
// TODO: We are relying on implementation detail. So, ideally, we should | ||
// static assert that std::mem::transmute(Goldilocks::one()) == 1u64. | ||
|
||
fn permute(&self, input: [Goldilocks; 8]) -> [Goldilocks; 8] { | ||
let input = unsafe { &*(&input as *const _ as *const [PowdrGoldilocks; 8]) }; | ||
let output = poseidon2_gl(input); | ||
// Let's hope the compiler optimizes this into a no-op. | ||
output.map(|x| Goldilocks::from_canonical_u64(u64::from(x))) | ||
} | ||
|
||
fn permute_mut(&self, data: &mut [Goldilocks; 8]) { | ||
let data = unsafe { &mut *(data as *mut _ as *mut [PowdrGoldilocks; 8]) }; | ||
poseidon2_gl_inplace(data); | ||
} | ||
} | ||
impl CryptographicPermutation<[Goldilocks; 8]> for Permutation {} | ||
|
||
lazy_static! { | ||
pub static ref PERM: Permutation = Permutation; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use crate::poseidon2::{external_constants, internal_constants}; | ||
|
||
use super::{D, ROUNDS_F, ROUNDS_P, WIDTH}; | ||
use lazy_static::lazy_static; | ||
use p3_goldilocks::{DiffusionMatrixGoldilocks, Goldilocks}; | ||
use p3_poseidon2::{Poseidon2, Poseidon2ExternalMatrixGeneral}; | ||
|
||
/// The Poseidon2 permutation type. | ||
pub type Permutation = | ||
Poseidon2<Goldilocks, Poseidon2ExternalMatrixGeneral, DiffusionMatrixGoldilocks, WIDTH, D>; | ||
|
||
lazy_static! { | ||
pub static ref PERM: Permutation = Permutation::new( | ||
*ROUNDS_F, | ||
external_constants(*ROUNDS_F), | ||
Poseidon2ExternalMatrixGeneral, | ||
*ROUNDS_P, | ||
internal_constants(*ROUNDS_P), | ||
DiffusionMatrixGoldilocks, | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "plonky3_verify" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
powdr-riscv-syscalls = { path = "../../../../riscv-syscalls" } | ||
powdr-riscv-runtime = { path = "../../../../riscv-runtime", features = ["std"]} | ||
powdr-plonky3 = { path = "../../../../plonky3", features = ["powdr-accel"]} | ||
|
||
[workspace] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[toolchain] | ||
channel = "nightly-2024-08-01" | ||
targets = ["riscv32im-risc0-zkvm-elf"] | ||
profile = "minimal" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
extern crate powdr_plonky3; | ||
|
||
fn main() { | ||
// This is just a stub to ensure that the `powdr_plonky3` crate is built and linked correctly. | ||
// TODO: perform an actual test. | ||
assert_eq!(true, !false); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
powdr-accel sounds a bit weird, why not just powdr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the thing is accelerated with powdr.
I think a feature named just
powdr
in a library of the powdr project, in a repo named powdr, is confusing.If not
powdr-accel
, maybeguest-in-powdr
or something like it?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, then
powdr-accel
it is