-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add generic snippet for new claim
- Loading branch information
1 parent
f6c0867
commit 08dfcbc
Showing
2 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
src/models/blockchain/transaction/validity/tasm/new_claim.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
use tasm_lib::{ | ||
data_type::DataType, | ||
prelude::{BasicSnippet, DynMalloc, Library}, | ||
triton_vm::{prelude::LabelledInstruction, triton_asm}, | ||
}; | ||
|
||
/// Generates a new Claim object given the lengths of the input and output. | ||
/// Returns pointers to: | ||
/// - the claim | ||
/// - the output | ||
/// - the input | ||
/// - the program digest. | ||
pub struct NewClaim; | ||
|
||
impl BasicSnippet for NewClaim { | ||
fn inputs(&self) -> Vec<(DataType, String)> { | ||
vec![ | ||
(DataType::U32, "input_length".to_string()), | ||
(DataType::U32, "output_length".to_string()), | ||
] | ||
} | ||
|
||
fn outputs(&self) -> Vec<(DataType, String)> { | ||
vec![ | ||
(DataType::VoidPointer, "*claim".to_string()), | ||
(DataType::VoidPointer, "*output".to_string()), | ||
(DataType::VoidPointer, "*input".to_string()), | ||
(DataType::VoidPointer, "*program_digest".to_string()), | ||
] | ||
} | ||
|
||
fn entrypoint(&self) -> String { | ||
"neptune_transaction_new_claim".to_string() | ||
} | ||
|
||
fn code(&self, library: &mut Library) -> Vec<LabelledInstruction> { | ||
let entrypoint = self.entrypoint(); | ||
|
||
let dyn_malloc = library.import(Box::new(DynMalloc)); | ||
|
||
triton_asm! { | ||
// BEFORE: _ input_length output_length | ||
// AFTER: _ *claim *output *input *program_digest | ||
{entrypoint}: | ||
|
||
call {dyn_malloc} | ||
// _ input_length output_length *claim | ||
|
||
swap 2 | ||
// _ *claim output_length input_length | ||
|
||
dup 1 dup 2 push 1 add | ||
// _ *claim output_length input_length output_length output_size | ||
|
||
dup 4 | ||
// _ *claim output_length input_length output_length output_size *output_si | ||
|
||
write_mem 2 | ||
// _ *claim output_length input_length *output | ||
|
||
dup 0 swap 3 | ||
// _ *claim *output input_length *output output_length | ||
|
||
add | ||
// _ *claim *output input_length *input_si | ||
|
||
dup 1 dup 2 push 1 add | ||
// _ *claim *output input_length *input_si input_length input_size | ||
|
||
dup 2 write_mem 2 | ||
// _ *claim *output input_length *input_si *input | ||
|
||
swap 1 pop 1 | ||
// _ *claim *output input_length *input | ||
|
||
dup 0 swap 2 add | ||
// _ *claim *output *input *program_digest | ||
|
||
return | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use std::collections::HashMap; | ||
|
||
use num_traits::ConstZero; | ||
use rand::{rngs::StdRng, Rng, SeedableRng}; | ||
use tasm_lib::{ | ||
empty_stack, | ||
memory::encode_to_memory, | ||
rust_shadowing_helper_functions, | ||
snippet_bencher::BenchmarkCase, | ||
traits::{ | ||
function::{Function, FunctionInitialState, ShadowedFunction}, | ||
rust_shadow::RustShadow, | ||
}, | ||
triton_vm::{prelude::BFieldElement, proof::Claim}, | ||
twenty_first::bfe, | ||
}; | ||
|
||
use super::NewClaim; | ||
|
||
impl Function for NewClaim { | ||
fn rust_shadow( | ||
&self, | ||
stack: &mut Vec<BFieldElement>, | ||
memory: &mut HashMap<BFieldElement, BFieldElement>, | ||
) { | ||
let output_length = stack.pop().unwrap().value() as usize; | ||
let input_length = stack.pop().unwrap().value() as usize; | ||
|
||
let claim_pointer = | ||
rust_shadowing_helper_functions::dyn_malloc::dynamic_allocator(memory); | ||
|
||
let claim = Claim { | ||
program_digest: Default::default(), | ||
input: vec![BFieldElement::ZERO; input_length], | ||
output: vec![BFieldElement::ZERO; output_length], | ||
}; | ||
|
||
encode_to_memory(memory, claim_pointer, &claim); | ||
|
||
let output_pointer = claim_pointer; | ||
let input_pointer = claim_pointer + bfe!(2) + bfe!(output_length as u64); | ||
let program_digest_pointer = input_pointer + bfe!(2) + bfe!(input_length as u64); | ||
|
||
stack.push(claim_pointer); | ||
stack.push(output_pointer); | ||
stack.push(input_pointer); | ||
stack.push(program_digest_pointer); | ||
} | ||
|
||
fn pseudorandom_initial_state( | ||
&self, | ||
seed: [u8; 32], | ||
bench_case: Option<BenchmarkCase>, | ||
) -> FunctionInitialState { | ||
let mut rng: StdRng = SeedableRng::from_seed(seed); | ||
|
||
let input_length = rng.gen_range(0..10); | ||
let output_length = rng.gen_range(0..10); | ||
|
||
FunctionInitialState { | ||
stack: [ | ||
empty_stack(), | ||
[bfe!(input_length as u64), bfe!(output_length as u64)].to_vec(), | ||
] | ||
.concat(), | ||
memory: HashMap::new(), | ||
} | ||
} | ||
} | ||
|
||
#[test] | ||
fn unit_test() { | ||
ShadowedFunction::new(NewClaim).test() | ||
} | ||
} |