Skip to content

Commit

Permalink
added fri fold precompile to runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
kevjue committed Feb 19, 2024
1 parent 7642b3b commit 542e492
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 0 deletions.
9 changes: 9 additions & 0 deletions core/src/runtime/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::runtime::{Register, Runtime};
use crate::syscall::precompiles::blake3::Blake3CompressInnerChip;
use crate::syscall::precompiles::edwards::EdAddAssignChip;
use crate::syscall::precompiles::edwards::EdDecompressChip;
use crate::syscall::precompiles::fri_fold::FriFoldChip;
use crate::syscall::precompiles::k256::K256DecompressChip;
use crate::syscall::precompiles::keccak256::KeccakPermuteChip;
use crate::syscall::precompiles::sha256::{ShaCompressChip, ShaExtendChip};
Expand Down Expand Up @@ -60,6 +61,9 @@ pub enum SyscallCode {
/// Executes the `BLAKE3_COMPRESS_INNER` precompile.
BLAKE3_COMPRESS_INNER = 112,

/// Executes fri fold precompile.
FRI_FOLD = 113,

WRITE = 999,
}

Expand All @@ -80,6 +84,7 @@ impl SyscallCode {
110 => SyscallCode::ENTER_UNCONSTRAINED,
111 => SyscallCode::EXIT_UNCONSTRAINED,
112 => SyscallCode::BLAKE3_COMPRESS_INNER,
113 => SyscallCode::FRI_FOLD,
999 => SyscallCode::WRITE,
_ => panic!("invalid syscall number: {}", value),
}
Expand Down Expand Up @@ -217,6 +222,10 @@ pub fn default_syscall_map() -> HashMap<SyscallCode, Rc<dyn Syscall>> {
SyscallCode::BLAKE3_COMPRESS_INNER,
Rc::new(Blake3CompressInnerChip::new()),
);
syscall_map.insert(
SyscallCode::BLAKE3_COMPRESS_INNER,
Rc::new(FriFoldChip::new()),
);
syscall_map.insert(
SyscallCode::ENTER_UNCONSTRAINED,
Rc::new(SyscallEnterUnconstrained::new()),
Expand Down
109 changes: 109 additions & 0 deletions core/src/syscall/precompiles/fri_fold/execute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use p3_baby_bear::BabyBear;
use p3_field::{
extension::BinomialExtensionField, AbstractExtensionField, AbstractField, PrimeField32,
};

use crate::{
runtime::{Register, Syscall},
syscall::precompiles::SyscallContext,
};

use super::FriFoldChip;

impl Syscall for FriFoldChip {
fn num_extra_cycles(&self) -> u32 {
8
}

fn execute(&self, rt: &mut SyscallContext) -> u32 {
// TODO: these will have to be be constrained, but can do it later.
// Read `input_mem_ptr` from register a0.
let input_mem_ptr = rt.register_unsafe(Register::X10);
if input_mem_ptr % 4 != 0 {
panic!();
}
// Read `output_mem_ptr` from register a1.
let output_mem_ptr = rt.register_unsafe(Register::X11);
if output_mem_ptr % 4 != 0 {
panic!();
}
let (input_read_records, input_values) = rt.mr_slice(input_mem_ptr, 14);

let x = BabyBear::from_canonical_u32(input_values[0]);
let alpha = BinomialExtensionField::<BabyBear, 4>::from_base_slice(
input_values[1..5]
.iter()
.map(|x| BabyBear::from_canonical_u32(*x))
.collect::<Vec<_>>()
.as_slice(),
);
let z = BinomialExtensionField::<BabyBear, 4>::from_base_slice(
input_values[5..9]
.iter()
.map(|x| BabyBear::from_canonical_u32(*x))
.collect::<Vec<_>>()
.as_slice(),
);
let p_at_z = BinomialExtensionField::<BabyBear, 4>::from_base_slice(
input_values[9..13]
.iter()
.map(|x| BabyBear::from_canonical_u32(*x))
.collect::<Vec<_>>()
.as_slice(),
);
let p_at_x = BabyBear::from_canonical_u32(input_values[13]);

// Read ro[log_height] and alpha_pow[log_height] address
let (output_read_records, output_addresses) = rt.mr_slice(output_mem_ptr, 2);
let ro_address = output_addresses[0];
let alpha_pow_address = output_addresses[1];

let (ro_read_records, ro_values) = rt.mr_slice(ro_address, 4);
let mut ro = BinomialExtensionField::<BabyBear, 4>::from_base_slice(
ro_values
.iter()
.map(|&x| BabyBear::from_canonical_u32(x))
.collect::<Vec<_>>()
.as_slice(),
);

let (alpha_read_records, alpha_values) = rt.mr_slice(alpha_pow_address, 4);
let mut alpha_pow = BinomialExtensionField::<BabyBear, 4>::from_base_slice(
alpha_values
.iter()
.map(|&x| BabyBear::from_canonical_u32(x))
.collect::<Vec<_>>()
.as_slice(),
);

rt.clk += 4;

let quotient = (-p_at_z + p_at_x) / (-z + x);
ro += alpha_pow * quotient;
alpha_pow *= alpha;

let ro_write_records = rt.mw_slice(
ro_address,
ro.as_base_slice()
.iter()
.map(|x: &BabyBear| x.as_canonical_u32())
.collect::<Vec<_>>()
.as_slice(),
);
let alpha_pow_write_records = rt.mw_slice(
alpha_pow_address,
alpha_pow
.as_base_slice()
.iter()
.map(|x: &BabyBear| x.as_canonical_u32())
.collect::<Vec<_>>()
.as_slice(),
);

rt.clk += 4;

// TODO. Push the fri fold event.

input_mem_ptr
}
}
9 changes: 9 additions & 0 deletions core/src/syscall/precompiles/fri_fold/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod execute;

pub struct FriFoldChip {}

impl FriFoldChip {
pub fn new() -> Self {
Self {}
}
}
1 change: 1 addition & 0 deletions core/src/syscall/precompiles/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod blake3;
pub mod edwards;
pub mod fri_fold;
pub mod k256;
pub mod keccak256;
pub mod sha256;
Expand Down
22 changes: 22 additions & 0 deletions zkvm/src/syscalls/fri_fold.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#[cfg(target_os = "zkvm")]
use core::arch::asm;

/// Fri fold operation.
///
/// The result is written to the addresses in the output mem entries.
#[allow(unused_variables)]
#[no_mangle]
pub extern "C" fn syscall_fri_fold(input_mem_ptr: *mut u32, output_mem_ptr: *mut u32) {
#[cfg(target_os = "zkvm")]
unsafe {
asm!(
"ecall",
in("t0") crate::syscalls::FRI_FOLD,
in("a0") input_mem_ptr,
in("a1") output_mem_ptr
);
}

#[cfg(not(target_os = "zkvm"))]
unreachable!()
}
4 changes: 4 additions & 0 deletions zkvm/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ extern "C" {
pub fn syscall_secp256k1_decompress(point: &mut [u8; 64], is_odd: bool);
pub fn syscall_keccak_permute(state: *mut u64);
pub fn syscall_blake3_compress_inner(p: *mut u32, q: *const u32);
pub fn syscall_fri_fold(input_mem_ptr: *mut u32, output_mem_ptr: *mut u32);
pub fn syscall_enter_unconstrained() -> bool;
pub fn syscall_exit_unconstrained();
pub fn sys_alloc_aligned(bytes: usize, align: usize) -> *mut u8;
Expand Down Expand Up @@ -96,5 +97,8 @@ pub const EXIT_UNCONSTRAINED: u32 = 111;
/// Executes `BLAKE3_COMPRESS_INNER`.
pub const BLAKE3_COMPRESS_INNER: u32 = 112;

/// Executes fri fold operation.
pub const FRI_FOLD: u32 = 113;

/// Writes to a file descriptor. Currently only used for `STDOUT/STDERR`.
pub const WRITE: u32 = 999;

0 comments on commit 542e492

Please sign in to comment.