Skip to content

Commit

Permalink
feat(hashing): Improve support for already boxed values
Browse files Browse the repository at this point in the history
  • Loading branch information
Sword-Smith committed Aug 29, 2024
1 parent 792635a commit e242d54
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 2 deletions.
32 changes: 32 additions & 0 deletions src/libraries/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,38 @@ impl Library for VectorLib {

/// Map list-function or method name to the TASM lib snippet type
impl VectorLib {
/// BEFORE: _ *list
/// AFTER: _ list_size_in_memory
pub(crate) fn list_encoding_size_code(
elem_type: &ast_types::DataType,
) -> Vec<LabelledInstruction> {
if let Some(static_size) = elem_type.bfield_codec_static_length() {
triton_asm!(
// _ *list

read_mem 1
pop 1
// _ list_len

push {static_size}
mul
addi 1
// _ list_size

push {ast_types::DataType::MAX_DYN_FIELD_SIZE}
dup 1
lt
// _ list_size (list_size < max_size)

assert

// _ list_size
)
} else {
todo!("Length-reading of list with dynamically-sized elements not yet supported");
}
}

fn rust_vec_to_data_type(
graft: &mut Graft,
path_args: &syn::PathArguments,
Expand Down
7 changes: 5 additions & 2 deletions src/tasm_code_generator/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use tasm_lib::triton_vm::op_stack::OpStackElement;
use tasm_lib::triton_vm::prelude::*;

use crate::ast_types;
use crate::libraries::vector::VectorLib;
use crate::tasm_code_generator::read_n_words_from_memory;
use crate::tasm_code_generator::CompilerState;

Expand All @@ -21,7 +22,7 @@ impl ast_types::DataType {
/// from memory against this value and crash the VM if the indicator
/// is larger or equal.
// TODO: Import this value from `tasm-lib` once available
pub(super) const MAX_DYN_FIELD_SIZE: u64 = 1u64 << 30;
pub(crate) const MAX_DYN_FIELD_SIZE: u64 = 1u64 << 30;

/// BEFORE: _ *value
/// AFTER: _ size_in_memory
Expand All @@ -35,7 +36,9 @@ impl ast_types::DataType {
ast_types::DataType::Struct(struct_type) => struct_type.boxed_encoding_size(),
ast_types::DataType::Enum(_) => todo!(),
ast_types::DataType::Boxed(_) => todo!(),
ast_types::DataType::List(_) => todo!(),
ast_types::DataType::List(elem_type) => {
VectorLib::list_encoding_size_code(elem_type)
}
ast_types::DataType::Tuple(_) => todo!(),
ast_types::DataType::Array(_) => todo!(),
ast_types::DataType::VoidPointer => todo!(),
Expand Down
1 change: 1 addition & 0 deletions src/tests_and_benchmarks/ozk/programs/algebraic_hasher.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod hash_atomic_values;
mod hash_boxed_fields;
mod hash_boxed_values;
mod sample_scalars;
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use tasm_lib::prelude::TasmObject;
use tasm_lib::triton_vm::prelude::*;
use twenty_first::prelude::AlgebraicHasher;

use crate::tests_and_benchmarks::ozk::rust_shadows as tasm;

const SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS: u64 = 84;

#[derive(TasmObject, BFieldCodec)]
struct OneDField {
a: Vec<BFieldElement>,
}

fn one_dynamically_sized_field() {
let test_struct: Box<OneDField> =
OneDField::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap();
let ts_digest: Digest = Tip5::hash(&test_struct.a);

tasm::tasmlib_io_write_to_stdout___digest(ts_digest);

return;
}

#[derive(TasmObject, BFieldCodec)]
struct OneSField {
a: Digest,
}

fn one_statically_sized_field() {
let test_struct: Box<OneSField> =
OneSField::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap();
let ts_digest: Digest = Tip5::hash(&test_struct.a);
tasm::tasmlib_io_write_to_stdout___digest(ts_digest);
return;
}

#[cfg(test)]
mod test {
use rand::random;
use tasm::wrap_main_with_io;
use tasm_lib::triton_vm::prelude::*;
use twenty_first::math::other::random_elements;

use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation;
use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from;
use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase;

use super::*;

#[test]
fn one_dynamically_sized_field_test() {
let test_struct = OneDField {
a: random_elements(2),
};
let non_determinism = init_memory_from(
&test_struct,
BFieldElement::new(SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS),
);
let native_output =
wrap_main_with_io(&one_dynamically_sized_field)(vec![], non_determinism.clone());

let entrypoint = EntrypointLocation::disk(
"algebraic_hasher",
"hash_boxed_fields",
"one_dynamically_sized_field",
);
let vm_output = TritonVMTestCase::new(entrypoint.clone())
.with_non_determinism(non_determinism)
.execute()
.unwrap();
assert_eq!(native_output, vm_output.public_output);
}

#[test]
fn one_statically_sized_field_test() {
let test_struct = OneSField { a: random() };
let non_determinism = init_memory_from(
&test_struct,
BFieldElement::new(SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS),
);
let native_output =
wrap_main_with_io(&one_statically_sized_field)(vec![], non_determinism.clone());

let entrypoint = EntrypointLocation::disk(
"algebraic_hasher",
"hash_boxed_fields",
"one_statically_sized_field",
);
let vm_output = TritonVMTestCase::new(entrypoint.clone())
.with_non_determinism(non_determinism)
.execute()
.unwrap();
assert_eq!(native_output, vm_output.public_output);
}
}

0 comments on commit e242d54

Please sign in to comment.