Skip to content

Commit

Permalink
Implement sys_rand, add the corresponding integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
Golovanov399 committed Jan 26, 2025
1 parent 4a8dc46 commit 9dd7730
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 4 deletions.
8 changes: 4 additions & 4 deletions crates/toolchain/openvm/src/pal_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/// operations in the same way: there is no operating system and even the standard library should be
/// directly handled with intrinsics.
use openvm_platform::{fileno::*, memory::sys_alloc_aligned, rust_rt::terminate, WORD_SIZE};
use openvm_rv32im_guest::raw_print_str_from_bytes;
use openvm_rv32im_guest::{hint_buffer_u32, hint_random, raw_print_str_from_bytes};

const DIGEST_WORDS: usize = 8;

Expand Down Expand Up @@ -71,9 +71,9 @@ pub unsafe extern "C" fn sys_sha_buffer(
///
/// `recv_buf` must be aligned and dereferenceable.
#[no_mangle]
pub unsafe extern "C" fn sys_rand(_recv_buf: *mut u32, _words: usize) {
crate::io::println("sys_rand is unimplemented");
terminate::<{ exit_code::UNIMP }>();
pub unsafe extern "C" fn sys_rand(recv_buf: *mut u32, words: usize) {
hint_random(words);
hint_buffer_u32!(recv_buf, words);
}

/// # Safety
Expand Down
1 change: 1 addition & 0 deletions extensions/native/tests/programs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
openvm = { path = "../../../../crates/toolchain/openvm" }
openvm-native-guest-macro = { path = "../../guest-macro", default-features = false }
openvm-platform = { path = "../../../../crates/toolchain/platform", default-features = false }

[features]
default = []
Expand Down
18 changes: 18 additions & 0 deletions extensions/native/tests/programs/src/bin/hashmap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![cfg_attr(not(feature = "std"), no_main)]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

use std::collections::HashMap;

openvm::entry!(main);

fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
map.insert(2, 8);
assert!(map.get(&1) == Some(&2));
assert!(map.get(&2) == Some(&8));
assert!(map.get(&3) == None);
openvm::io::println(format!("{:?}", map.get(&1).unwrap()));
}
25 changes: 25 additions & 0 deletions extensions/native/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,29 @@ mod tests {
air_test(Rv32WithKernelsConfig::default(), exe);
Ok(())
}

#[test]
fn test_hashmap() -> Result<()> {
let sdk = Sdk;

let elf = sdk.build(
GuestOptions::default().with_features(["std"]),
get_programs_dir!(),
&Some(TargetFilter {
kind: "bin".to_string(),
name: "hashmap".to_string(),
}),
)?;
let exe = VmExe::from_elf(
elf.clone(),
Transpiler::<BabyBear>::default()
.with_extension(Rv32ITranspilerExtension)
.with_extension(Rv32MTranspilerExtension)
.with_extension(Rv32IoTranspilerExtension)
.with_extension(LongFormTranspilerExtension),
)?;

air_test(Rv32WithKernelsConfig::default(), exe);
Ok(())
}
}
32 changes: 32 additions & 0 deletions extensions/rv32im/circuit/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ impl<F: PrimeField32> VmExtension<F> for Rv32I {
phantom::Rv32HintInputSubEx,
PhantomDiscriminant(Rv32Phantom::HintInput as u16),
)?;
builder.add_phantom_sub_executor(
phantom::Rv32HintRandomSubEx::new(),
PhantomDiscriminant(Rv32Phantom::HintRandom as u16),
)?;
builder.add_phantom_sub_executor(
phantom::Rv32PrintStrSubEx,
PhantomDiscriminant(Rv32Phantom::PrintStr as u16),
Expand Down Expand Up @@ -471,10 +475,19 @@ mod phantom {
};
use openvm_instructions::PhantomDiscriminant;
use openvm_stark_backend::p3_field::{Field, PrimeField32};
use rand::{rngs::OsRng, Rng};

use crate::adapters::unsafe_read_rv32_register;

pub struct Rv32HintInputSubEx;
pub struct Rv32HintRandomSubEx {
rng: OsRng,
}
impl Rv32HintRandomSubEx {
pub fn new() -> Self {
Self { rng: OsRng }
}
}
pub struct Rv32PrintStrSubEx;

impl<F: Field> PhantomSubExecutor<F> for Rv32HintInputSubEx {
Expand Down Expand Up @@ -508,6 +521,25 @@ mod phantom {
}
}

impl<F: PrimeField32> PhantomSubExecutor<F> for Rv32HintRandomSubEx {
fn phantom_execute(
&mut self,
_: &MemoryController<F>,
streams: &mut Streams<F>,
_: PhantomDiscriminant,
len: F,
_: F,
_: u16,
) -> eyre::Result<()> {
let len = len.as_canonical_u32() as usize;
streams.hint_stream.clear();
streams.hint_stream.extend(
std::iter::repeat_with(|| F::from_canonical_u8(self.rng.gen::<u8>())).take(len),
);
Ok(())
}
}

impl<F: PrimeField32> PhantomSubExecutor<F> for Rv32PrintStrSubEx {
fn phantom_execute(
&mut self,
Expand Down
12 changes: 12 additions & 0 deletions extensions/rv32im/guest/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ pub fn hint_input() {
);
}

/// Reset the hint stream with `len` random `u32`s
#[inline(always)]
pub fn hint_random(len: usize) {
openvm_platform::custom_insn_i!(
opcode = SYSTEM_OPCODE,
funct3 = PHANTOM_FUNCT3,
rd = In len,
rs1 = Const "x0",
imm = Const PhantomImm::HintRandom as u16
);
}

/// Store rs1 to [[rd] + imm]_2.
#[macro_export]
macro_rules! reveal {
Expand Down
1 change: 1 addition & 0 deletions extensions/rv32im/guest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ pub const CSRRW_FUNCT3: u8 = 0b001;
#[repr(u16)]
pub enum PhantomImm {
HintInput = 0,
HintRandom,
PrintStr,
}
2 changes: 2 additions & 0 deletions extensions/rv32im/transpiler/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ pub enum Rv32HintStoreOpcode {
pub enum Rv32Phantom {
/// Prepare the next input vector for hinting, but prepend it with a 4-byte decomposition of its length instead of one field element.
HintInput = 0x20,
/// Prepare given amount of random numbers for hinting.
HintRandom,
/// Peek string from memory and print it to stdout.
PrintStr,
}
6 changes: 6 additions & 0 deletions extensions/rv32im/transpiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ impl<F: PrimeField32> TranspilerExtension<F> for Rv32ITranspilerExtension {
F::ZERO,
0,
),
PhantomImm::HintRandom => Instruction::phantom(
PhantomDiscriminant(Rv32Phantom::HintRandom as u16),
F::from_canonical_usize(RV32_REGISTER_NUM_LIMBS * dec_insn.rd),
F::ZERO,
0,
),
PhantomImm::PrintStr => Instruction::phantom(
PhantomDiscriminant(Rv32Phantom::PrintStr as u16),
F::from_canonical_usize(RV32_REGISTER_NUM_LIMBS * dec_insn.rd),
Expand Down

0 comments on commit 9dd7730

Please sign in to comment.