diff --git a/src/driver_client/dclient.rs b/src/driver_client/dclient.rs index f75beca..110e90e 100755 --- a/src/driver_client/dclient.rs +++ b/src/driver_client/dclient.rs @@ -43,6 +43,30 @@ pub trait DriverPrimitive { /// The `result` method returns the output data from the driver primitive, /// optionally with a specific parameter. If there is no output data available, it returns `None`. fn result(&self, param: Option) -> Result>; + + fn get_bin_type(&self) -> BinType { + let params = &self.loaded_binary_parameters(); + let bin_id = params[0]; + match bin_id { + 0 => BinType::MSM, + 1 => BinType::NTT, + 3 => BinType::POSEIDON, + _ => BinType::NONE, + } + } + + fn get_driver_details(&self) -> (BinType, u32) { + let params = &self.loaded_binary_parameters(); + let bin_id = params[0]; + let image_paramters = params[1]; + let bin_id = match bin_id { + 0 => BinType::MSM, + 1 => BinType::NTT, + 3 => BinType::POSEIDON, + _ => BinType::NONE, + }; + (bin_id, image_paramters) + } } /// The [`DriverClient`] is described bunch of addreses on FPGA which called [`DriverConfig`] also diff --git a/src/driver_client/dclient_cfg.rs b/src/driver_client/dclient_cfg.rs index 905ef57..2456090 100644 --- a/src/driver_client/dclient_cfg.rs +++ b/src/driver_client/dclient_cfg.rs @@ -1,6 +1,13 @@ pub enum CardType { C1100, } +#[derive(Debug, PartialEq, Eq)] +pub enum BinType { + MSM = 0, + NTT = 1, + POSEIDON = 3, + NONE, +} /// The [`DriverConfig`] is a struct that defines a set of 64-bit unsigned integer (`u64`) /// representing addreses memory space for different components of a FPGA. diff --git a/src/driver_client/mod.rs b/src/driver_client/mod.rs index 9316a3d..875317d 100755 --- a/src/driver_client/mod.rs +++ b/src/driver_client/mod.rs @@ -1,6 +1,6 @@ -mod dclient; -mod dclient_cfg; -mod dclient_code; +pub mod dclient; +pub mod dclient_cfg; +pub mod dclient_code; pub use dclient::*; pub use dclient_cfg::{CardType, DriverConfig}; diff --git a/src/error.rs b/src/error.rs index b78f2f3..bbfc2a7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -27,6 +27,8 @@ pub enum DriverClientError { LoadFailed { path: String }, #[error("failed open file")] FileError(#[from] io::Error), + #[error("NOT MSM Binary")] + NotMsmBin, #[error("unknown driver client error")] Unknown, } diff --git a/src/ingo_hash/dma_buffer.rs b/src/ingo_hash/dma_buffer.rs new file mode 100644 index 0000000..64d71e9 --- /dev/null +++ b/src/ingo_hash/dma_buffer.rs @@ -0,0 +1,59 @@ +use std::mem; + +#[repr(C, align(4096))] +pub struct Align4K([u8; 4096]); + +#[derive(Debug)] +pub struct DmaBuffer(Vec); + +impl DmaBuffer { + pub fn new(n_bytes: usize) -> Self { + Self(unsafe { aligned_vec::(n_bytes) }) + } + + pub fn extend_from_slice(&mut self, slice: &[u8]) { + self.0.extend_from_slice(slice); + } + + pub fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } + + pub fn as_mut_slice(&mut self) -> &mut [u8] { + self.0.as_mut_slice() + } + + pub fn get(&self) -> &Vec { + &self.0 + } + + pub fn get_mut(&mut self) -> &mut Vec { + &mut self.0 + } + + pub fn set_len(&mut self, num: usize) { + unsafe { self.0.set_len(num) } + } + + pub fn len(&self) -> usize { + self.0.len() + } +} + +pub unsafe fn aligned_vec(n_bytes: usize) -> Vec { + let n_units = (n_bytes / mem::size_of::()) + 1; + + let mut aligned: Vec = Vec::with_capacity(n_units); + + let ptr = aligned.as_mut_ptr(); + let len_units = aligned.len(); + let cap_units = aligned.capacity(); + + mem::forget(aligned); + + Vec::from_raw_parts( + ptr as *mut u8, + len_units * mem::size_of::(), + cap_units * mem::size_of::(), + ) +} diff --git a/src/ingo_hash/mod.rs b/src/ingo_hash/mod.rs index ca8813e..deb9a96 100755 --- a/src/ingo_hash/mod.rs +++ b/src/ingo_hash/mod.rs @@ -1,6 +1,8 @@ -mod hash_hw_code; -mod poseidon_api; -mod utils; +pub mod dma_buffer; +pub mod hash_hw_code; +pub mod poseidon_api; +pub mod utils; +pub use dma_buffer::*; pub use poseidon_api::*; pub use utils::*; diff --git a/src/ingo_hash/poseidon_api.rs b/src/ingo_hash/poseidon_api.rs index 0369466..96ff9b4 100755 --- a/src/ingo_hash/poseidon_api.rs +++ b/src/ingo_hash/poseidon_api.rs @@ -2,7 +2,7 @@ use packed_struct::prelude::PackedStruct; use std::option::Option; use strum::IntoEnumIterator; -use super::{hash_hw_code::*, TreeMode}; +use super::{hash_hw_code::*, DmaBuffer, TreeMode}; use crate::{driver_client::*, error::*, utils::convert_to_32_byte_array}; use csv; @@ -71,6 +71,11 @@ impl PoseidonResult { } } +pub struct PoseidonReadResult<'a> { + pub expected_result: usize, + pub result_store_buffer: &'a mut DmaBuffer, +} + impl DriverPrimitive> for PoseidonClient { diff --git a/src/ingo_hash/poseidon_api_old b/src/ingo_hash/poseidon_api_old new file mode 100644 index 0000000..e26eb4e --- /dev/null +++ b/src/ingo_hash/poseidon_api_old @@ -0,0 +1,311 @@ +use packed_struct::prelude::PackedStruct; +use std::option::Option; +use strum::IntoEnumIterator; + +use super::{hash_hw_code::*, TreeMode, DmaBuffer}; +use crate::{driver_client::*, error::*, utils::convert_to_32_byte_array}; + +use csv; +use num::{bigint::BigUint, Num}; + +pub enum Hash { + Poseidon, +} + +pub struct PoseidonClient { + pub dclient: DriverClient, +} + +#[derive(Clone)] +pub struct PoseidonInitializeParameters { + pub tree_height: u32, + pub tree_mode: TreeMode, + pub instruction_path: String, +} + +pub struct PoseidonResult { + pub hash_byte: [u8; 32], + pub hash_id: u32, + pub layer_id: u32, +} + +impl PoseidonResult { + /// The function parses poseidon hash result + /// + /// # Arguments + /// + /// * `data` - an Vec of size 64 bytes representing a hash (32 bytes) and hash_id (32 bytes). + /// + /// # Example + /// + /// The hash_id contains layer index and and layer height. + pub fn parse_poseidon_hash_results(data: Vec) -> Vec { + let split_data: Vec<&[u8]> = data.chunks(64).collect(); + + let mut results: Vec = Vec::new(); + + for element in split_data { + assert_eq!(element.len(), 64); + + let hash: &[u8; 32] = element[0..32].try_into().unwrap(); + let hash_data: &[u8; 32] = element[32..].try_into().unwrap(); + + let hash_first_4_bytes: [u8; 4] = hash_data[..4].try_into().unwrap(); + + // optimize this its bad + let hash_2_bytes: [u8; 2] = hash_data[3..5].try_into().unwrap(); + let mut hash_last_2_bytes: [u8; 4] = [0; 4]; + hash_last_2_bytes[..hash_2_bytes.len()].copy_from_slice(&hash_2_bytes); + + let hash_id = u32::from_le_bytes(hash_first_4_bytes) & 0x3fffffff; + let layer_id = u32::from_le_bytes(hash_last_2_bytes) >> 6; + + results.push(PoseidonResult { + hash_byte: hash.to_owned(), + hash_id, + layer_id, + }); + } + + results + } +} + + + +pub struct PoseidonReadResult<'a> { + pub expected_result: usize, + pub result_store_buffer: &'a mut DmaBuffer, +} + + + + +impl DriverPrimitive> + for PoseidonClient +{ + fn new(_ptype: Hash, dclient: DriverClient) -> Self { + PoseidonClient { dclient } + } + + fn loaded_binary_parameters(&self) -> Vec { + [ + INGO_POSEIDON_ADDR::ADDR_HIF2CPU_C_IMAGE_ID, + INGO_POSEIDON_ADDR::ADDR_HIF2CPU_C_IMAGE_PARAMTERS, + ] + .map(|offset| { + self.dclient + .ctrl_read_u32(self.dclient.cfg.ctrl_baseaddr, offset) + .map_err(|_| DriverClientError::InvalidPrimitiveParam) + .unwrap() + }) + .into_iter() + .collect::>() + } + + fn initialize(&self, param: PoseidonInitializeParameters) -> Result<()> { + self.dclient.reset()?; + self.set_initialize_mode(true)?; + + self.load_instructions(¶m.instruction_path) + .map_err(|_| DriverClientError::LoadFailed { + path: param.instruction_path, + })?; + self.set_initialize_mode(false)?; + log::debug!("successfully loaded instruction set"); + + self.set_merkle_tree_height(param.tree_height)?; + self.set_tree_start_layer_for_tree(param.tree_mode)?; + log::debug!("set merkle tree height: {:?}", param.tree_height); + Ok(()) + } + + fn start_process(&self, _param: Option) -> Result<()> { + todo!() + } + + fn set_data(&self, input: &[u8]) -> Result<()> { + self.dclient + .dma_write(self.dclient.cfg.dma_baseaddr, DMA_RW::OFFSET, input)?; + + Ok(()) + } + + fn wait_result(&self) -> Result<()> { + todo!() + } + + fn result(&self, expected_result: Option) -> Result>> { + let mut results: Vec = vec![]; + + loop { + let num_of_pending_results = self.get_num_of_pending_results()?; + + if results.len() >= expected_result.unwrap() { + break; + } + + let res = self.get_raw_results(num_of_pending_results)?; + + let mut result = PoseidonResult::parse_poseidon_hash_results(res); + results.append(&mut result); + } + + Ok(Some(results)) + } +} + +impl PoseidonClient { + pub fn get_last_element_sent_to_ring(&self) -> Result { + self.dclient.ctrl_read_u32( + self.dclient.cfg.ctrl_baseaddr, + INGO_POSEIDON_ADDR::ADDR_HIF2CPU_C_LAST_ELEMENT_ID_SENT_TO_RING, + ) + } + + pub fn get_num_of_pending_results(&self) -> Result { + self.dclient.ctrl_read_u32( + self.dclient.cfg.ctrl_baseaddr, + INGO_POSEIDON_ADDR::ADDR_HIF2CPU_C_NOF_RESULTS_PENDING_ON_DMA_FIFO, + ) + } + + fn set_merkle_tree_height(&self, height: u32) -> Result<()> { + self.dclient.ctrl_write_u32( + self.dclient.cfg.ctrl_baseaddr, + INGO_POSEIDON_ADDR::ADDR_CPU2HIF_C_MERKLE_TREE_HEIGHT, + height, + ) + } + + fn set_tree_start_layer_for_tree(&self, tree: TreeMode) -> Result<()> { + let start_height: u32 = TreeMode::value(tree); + + self.dclient.ctrl_write_u32( + self.dclient.cfg.ctrl_baseaddr, + INGO_POSEIDON_ADDR::ADDR_CPU2HIF_C_MERKLE_TREE_START_LAYER, + start_height, + ) + } + + fn set_initialize_mode(&self, enter: bool) -> Result<()> { + let value = if enter { 1 } else { 0 }; + + self.dclient.ctrl_write_u32( + self.dclient.cfg.ctrl_baseaddr, + INGO_POSEIDON_ADDR::ADDR_CPU2HIF_C_INITIALIZATION_MODE, + value, + ) + } + + pub fn get_raw_results(&self, num_of_results: u32) -> Result> { + let mut res = vec![0; (64 * num_of_results).try_into().unwrap()]; + self.dclient + .dma_read(self.dclient.cfg.dma_baseaddr, DMA_RW::OFFSET, &mut res)?; + Ok(res) + } + + pub fn get_last_hash_sent_to_host(&self) -> Result { + self.dclient.ctrl_read_u32( + self.dclient.cfg.ctrl_baseaddr, + INGO_POSEIDON_ADDR::ADDR_HIF2CPU_C_LAST_HASH_ID_SENT_TO_HOST, + ) + } + + fn load_instructions(&self, file_path: &str) -> Result<()> { + let mut reader = csv::Reader::from_path(file_path)?; + + for res in reader.records() { + let result = res?; + + let element_one_str = result.get(result.len() - 1).unwrap(); + let element_two_str = result.get(result.len() - 2).unwrap(); + + // TODO: check type conversation + let first_value_to_send: [u8; 32] = convert_to_32_byte_array( + BigUint::from_str_radix(element_one_str, 10) + .unwrap() + .to_bytes_le() + .as_slice(), + ); + let second_value_to_send: [u8; 32] = convert_to_32_byte_array( + BigUint::from_str_radix(element_two_str, 10) + .unwrap() + .to_bytes_le() + .as_slice(), + ); + + // some sanity tests, + debug_assert!( + BigUint::from_bytes_le(&first_value_to_send).to_string() == element_one_str + ); + debug_assert!( + BigUint::from_bytes_le(&second_value_to_send).to_string() == element_two_str + ); + debug_assert_eq!(first_value_to_send.len(), 32); + debug_assert_eq!(second_value_to_send.len(), 32); + + self.set_data(&first_value_to_send)?; + self.set_data(&second_value_to_send)?; + } + + Ok(()) + } + + pub fn log_api_values(&self) { + log::debug!("=== api values ==="); + for api_val in INGO_POSEIDON_ADDR::iter() { + self.dclient + .ctrl_read_u32(self.dclient.cfg.ctrl_baseaddr, api_val) + .unwrap(); + } + log::debug!("=== api values ==="); + } +} + +#[derive(PackedStruct, Debug)] +#[packed_struct(bit_numbering = "msb0")] +pub struct PoseidonImageParametrs { + #[packed_field(bits = "28..=31", endian = "lsb")] + pub hif2_cpu_c_is_stub: u8, + #[packed_field(bits = "20..=27", endian = "lsb")] + pub hif2_cpu_c_number_of_cores: u8, + #[packed_field(bits = "0..=19", endian = "lsb")] + pub hif2_cpu_c_place_holder: u32, +} + +impl ParametersAPI for PoseidonImageParametrs { + fn parse_image_params(params: u32) -> PoseidonImageParametrs { + let buf = params.to_be_bytes(); + PoseidonImageParametrs::unpack(&buf).unwrap() + } + + fn debug_information(&self) { + log::debug!("Is Stub: {:?}", self.hif2_cpu_c_is_stub); + log::debug!("Number of Cores: {:?}", self.hif2_cpu_c_number_of_cores); + log::debug!("Place Holder: {:?}", self.hif2_cpu_c_place_holder); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use log::info; + use std::env; + + #[test] + fn load_hash_binary_test() { + env_logger::try_init().expect("Invalid logger initialisation"); + let id = env::var("ID").unwrap_or_else(|_| 0.to_string()); + info!("ID: {}", id); + + info!("Create Driver API instance"); + + let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); + let driver: PoseidonClient = PoseidonClient::new(Hash::Poseidon, dclient); + let params = driver.loaded_binary_parameters(); + info!("Driver parameters: [{:?}, {:032b}]", params[0], params[1]); + let params_parce = PoseidonImageParametrs::parse_image_params(params[1]); + params_parce.debug_information(); + } +} diff --git a/src/ingo_msm/mod.rs b/src/ingo_msm/mod.rs index 46136c1..a83d8ce 100755 --- a/src/ingo_msm/mod.rs +++ b/src/ingo_msm/mod.rs @@ -1,5 +1,5 @@ -mod msm_api; -mod msm_cfg; +pub mod msm_api; +pub mod msm_cfg; mod msm_hw_code; pub use msm_api::*; diff --git a/src/ingo_msm/msm_api.rs b/src/ingo_msm/msm_api.rs index 5f39e06..16d68a0 100755 --- a/src/ingo_msm/msm_api.rs +++ b/src/ingo_msm/msm_api.rs @@ -7,15 +7,12 @@ use strum::IntoEnumIterator; pub struct MSMClient { mem_type: PointMemoryType, - // If precompute factor set to 1 is the basic MSM computation without optimization - precompute_factor: u32, msm_cfg: MSMConfig, pub driver_client: DriverClient, } pub struct MSMInit { pub mem_type: PointMemoryType, - pub is_precompute: bool, pub curve: Curve, } @@ -36,19 +33,14 @@ pub struct MSMResult { pub result_label: u32, } -pub const PRECOMPUTE_FACTOR_BASE: u32 = 1; -pub const PRECOMPUTE_FACTOR: u32 = 8; +//pub const PRECOMPUTE_FACTOR_BASE: u32 = 1; +//pub const PRECOMPUTE_FACTOR: u32 = 7; impl DriverPrimitive for MSMClient { /// Creates a new [`MSMClient`]. fn new(init: MSMInit, dclient: DriverClient) -> Self { MSMClient { mem_type: init.mem_type, - precompute_factor: if init.is_precompute { - PRECOMPUTE_FACTOR - } else { - PRECOMPUTE_FACTOR_BASE - }, msm_cfg: MSMConfig::msm_cfg(init.curve, init.mem_type), driver_client: dclient, } @@ -175,7 +167,7 @@ impl DriverPrimitive for MSMClient { } else if data.points.is_some() && data.params.hbm_point_addr.is_none() { log::debug!("Set points and scalars"); let mut payload_size_points = CHUNK_SIZE * self.msm_cfg.point_size.unwrap(); - payload_size_points *= self.precompute_factor as usize; + payload_size_points *= self.get_precompute_factor() as usize; let p_addr = self.msm_cfg.dma_points_addr.unwrap(); let p = data.points.as_ref().unwrap(); @@ -296,6 +288,19 @@ impl MSMClient { ) } + pub fn nof_pending_tasks_in_queue(&self) -> Result { + self.driver_client.ctrl_read_u32( + self.driver_client.cfg.ctrl_baseaddr, + INGO_MSM_ADDR::ADDR_HIF2CPU_C_NOF_PENDING_TASKS_IN_QUEUE, + ) + } + + pub fn get_precompute_factor(&self) -> u8 { + let params = self.loaded_binary_parameters(); + let image_parameters = MSMImageParametrs::parse_image_params(params[1]); + image_parameters.hif2_cpu_c_precompute + } + pub fn load_data_to_hbm(&self, points: &[u8], addr: u64, offset: u64) -> Result<()> { log::debug!("HBM adress: {:#X?}", &addr); self.driver_client.ctrl_write_u32( @@ -328,11 +333,15 @@ impl MSMClient { .unwrap(); } } + + pub fn get_scalar_size(&self) -> usize { + self.msm_cfg.scalar_size + } } -#[derive(PackedStruct, Debug)] -#[packed_struct(bit_numbering = "msb0")] -pub struct MSMImageParametrs { +/* #[derive(PackedStruct, Debug)] +#[packed_struct(bit_numbering = "msb0")] */ +/* pub struct MSMImageParametrs { #[packed_field(bits = "28..=31", endian = "lsb")] pub hif2cpu_c_is_stub: u8, #[packed_field(bits = "20..=27", endian = "lsb")] @@ -345,11 +354,28 @@ pub struct MSMImageParametrs { pub hif2_cpu_c_number_of_segments: u8, #[packed_field(bits = "0..=3", endian = "lsb")] pub hif2_cpu_c_place_holder: u8, +} */ +#[derive(PackedStruct, Debug)] +#[packed_struct(bit_numbering = "msb0")] +pub struct MSMImageParametrs { + #[packed_field(bits = "28..=31", endian = "lsb")] + pub hif2cpu_c_is_stub: u8, + #[packed_field(bits = "24..=27", endian = "lsb")] + pub hif2_cpu_c_curve: u8, + #[packed_field(bits = "20..=23", endian = "lsb")] + pub hif2_cpu_c_number_of_ec_adders: u8, + #[packed_field(bits = "12..=19", endian = "lsb")] + pub hif2_cpu_c_buckets_mem_addr_width: u8, + #[packed_field(bits = "8..=11", endian = "lsb")] + pub hif2_cpu_c_number_of_segments: u8, + #[packed_field(bits = "0..=7", endian = "lsb")] + pub hif2_cpu_c_precompute: u8, } impl ParametersAPI for MSMImageParametrs { fn parse_image_params(params: u32) -> MSMImageParametrs { - let buf = params.reverse_bits().to_be_bytes(); + //let buf = params.reverse_bits().to_be_bytes(); + let buf = params.to_be_bytes(); MSMImageParametrs::unpack(&buf).unwrap() } @@ -374,6 +400,6 @@ impl ParametersAPI for MSMImageParametrs { "Number of segmemts: {:?}", self.hif2_cpu_c_number_of_segments ); - log::debug!("Place Holder: {:?}", self.hif2_cpu_c_place_holder); + log::debug!("PreCompute: {:?}", self.hif2_cpu_c_precompute); } } diff --git a/src/ingo_msm/msm_cfg.rs b/src/ingo_msm/msm_cfg.rs index 13c0d92..e16f6b7 100644 --- a/src/ingo_msm/msm_cfg.rs +++ b/src/ingo_msm/msm_cfg.rs @@ -56,8 +56,10 @@ fn msm_bls377_dma_cfg() -> MSMConfig { result_point_size: 144, point_size: Some(96), scalar_size: 32, - dma_scalars_addr: Some(0x0000020000000000), - dma_points_addr: Some(0x0000010000000000), + dma_scalars_addr: Some(0x0000_0200_0000_0000), + dma_points_addr: Some(0x0000_0100_0000_0000), + // dma_scalars_addr: Some(0x0000_0100_0000_0000), + // dma_points_addr: Some(0x0000_0000_0000_0000), } } diff --git a/src/ingo_msm/msm_hw_code.rs b/src/ingo_msm/msm_hw_code.rs index 6cb139d..650ad59 100755 --- a/src/ingo_msm/msm_hw_code.rs +++ b/src/ingo_msm/msm_hw_code.rs @@ -32,14 +32,14 @@ pub enum INGO_MSM_ADDR { ADDR_AXI2CPU_C_NUMBER_OF_BASES_IN_AXI_HBM_FIFO = 0xec, ADDR_HIF2CPU_E_BUCKET_ACCUMULATION_PHASE_COMPLETED = 0xf0, ADDR_HIF2CPU_E_FINAL_ACCUMULATION_PHASE_COMPLETED = 0xf4, - ADDR_HIF2CPU_C_LAST_TASK_PHASE1_TOTAL_CLOCKS_LO = 0xf8, - ADDR_HIF2CPU_C_LAST_TASK_PHASE1_TOTAL_CLOCKS_HI = 0xfc, - ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BUSY_ECADDER_CLOCKS_LO = 0x100, - ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BUSY_ECADDER_CLOCKS_HI = 0x104, - ADDR_HIF2CPU_C_LAST_TASK_PHASE2_TOTAL_CLOCKS_LO = 0x108, - ADDR_HIF2CPU_C_LAST_TASK_PHASE2_TOTAL_CLOCKS_HI = 0x10c, - ADDR_HIF2CPU_C_LAST_TASK_PHASE2_BUSY_ECADDER_CLOCKS_LO = 0x110, - ADDR_HIF2CPU_C_LAST_TASK_PHASE2_BUSY_ECADDER_CLOCKS_HI = 0x114, + ADDR_HIF2CPU_C_LAST_TASK_PHASE1_TOTAL_CLOCKS = 0xf8, + ADDR_HIF2CPU_C_LAST_TASK_PHASE2_TOTAL_CLOCKS = 0xfc, + ADDR_HIF2CPU_C_LAST_TASK_PHASE3_TOTAL_CLOCKS = 0x100, + ADDR_HIF2CPU_C_LAST_TASK_INTER_ARRIVAL_TIME_IN_CLOCK = 0x104, + ADDR_HIF2CPU_C_LAST_TASK_PHASE1_NOF_EC_ADDITIONS = 0x108, + ADDR_HIF2CPU_C_LAST_TASK_PHASE1_COEFFICIENTS_FIFO_EMPTY_CLOCKS = 0x10c, + ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BASES_FIFO_EMPTY_CLOCKS = 0x110, + /* ADDR_HIF2CPU_C_LAST_TASK_PHASE2_BUSY_ECADDER_CLOCKS_HI = 0x114, ADDR_HIF2CPU_C_LAST_TASK_PHASE3_TOTAL_CLOCKS_LO = 0x118, ADDR_HIF2CPU_C_LAST_TASK_PHASE3_TOTAL_CLOCKS_HI = 0x11c, ADDR_HIF2CPU_C_LAST_TASK_PHASE3_BUSY_ECADDER_CLOCKS_LO = 0x120, @@ -51,7 +51,7 @@ pub enum INGO_MSM_ADDR { ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BASES_FIFO_BUSY_CLOCKS_LO = 0x138, ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BASES_FIFO_BUSY_CLOCKS_HI = 0x13c, ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BASES_FIFO_NOF_EMPTY_LO = 0x140, - ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BASES_FIFO_NOF_EMPTY_HI = 0x144, + ADDR_HIF2CPU_C_LAST_TASK_PHASE1_BASES_FIFO_NOF_EMPTY_HI = 0x144, */ } impl From for u64 { diff --git a/src/utils.rs b/src/utils.rs index 84528d8..7425070 100755 --- a/src/utils.rs +++ b/src/utils.rs @@ -56,6 +56,23 @@ impl AccessFlags { } // ==== read/write ==== +/* +pub fn open_channel(path: &str, mode: AccessFlags) -> std::fs::File { + let mut options = OpenOptions::new(); + if mode == AccessFlags::RdwrMode || mode == AccessFlags::RdMode { + options.read(true); + } + + if mode == AccessFlags::RdwrMode || mode == AccessFlags::WrMode { + options.write(true); + } + + if cfg!(unix) { + options.custom_flags(libc::O_SYNC); + // options.custom_flags(libc::O_RDWR); + } + options.open(path).unwrap() +} */ pub fn open_channel(path: &str, mode: AccessFlags) -> std::fs::File { let mut options = OpenOptions::new(); diff --git a/tests/integration_msm.rs b/tests/integration_msm.rs index 3e08533..af15837 100644 --- a/tests/integration_msm.rs +++ b/tests/integration_msm.rs @@ -1,8 +1,17 @@ -use ingo_blaze::{driver_client::*, ingo_msm::*, utils::*}; +use ark_bls12_377::G1Projective as bls377G1Projective; +use ark_bls12_381::G1Projective as bls381G1Projective; + +use ingo_blaze::{ + driver_client::{dclient_cfg::BinType, *}, + error::DriverClientError, + ingo_msm::*, + utils::*, +}; use num_traits::Pow; use std::{ env, fmt::Display, + io::Error, thread::sleep, time::{Duration, Instant}, }; @@ -12,8 +21,11 @@ pub mod msm; #[test] fn load_msm_binary_test() -> Result<(), Box> { env_logger::try_init().expect("Invalid logger initialisation"); - let id = env::var("ID").unwrap_or_else(|_| 0.to_string()); - let bin_file = env::var("FILENAME").unwrap(); + //let id = env::var("ID").unwrap_or_else(|_| 1.to_string()); + let id = 0.to_string(); + let bin_file = env::var("BIN_FILE").unwrap_or_else(|_| { + "/home/administrator/users/eli/fpga-bin/msm-bls377/msmfeb20.bin".to_string() + }); let msm_size = env::var("MSM_SIZE") .unwrap_or_else(|_| 8192.to_string()) @@ -28,12 +40,14 @@ fn load_msm_binary_test() -> Result<(), Box> { let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: false, - curve: Curve::BLS381, + curve: Curve::BLS377, // BLS381 }, dclient, ); + let precompute_factor: u32 = driver.get_precompute_factor().into(); + println!("precompute_factor = {}", precompute_factor); + log::info!("Start to loading binary file..."); let buf = read_binary_file(&bin_file)?; log::info!("Buffer size: {:?}", buf.len()); @@ -62,7 +76,8 @@ fn load_msm_binary_test() -> Result<(), Box> { driver.task_label()?; let (points, scalars, msm_result, results) = - msm::input_generator_bls12_381(msm_size as usize, PRECOMPUTE_FACTOR_BASE); + //msm::input_generator_bls12_381(msm_size as usize, PRECOMPUTE_FACTOR_BASE); + msm::input_generator_bls12_377(msm_size as usize, precompute_factor); log::info!("Starting to initialize task and set number of elements: "); let msm_params = MSMParams { @@ -82,7 +97,8 @@ fn load_msm_binary_test() -> Result<(), Box> { driver.wait_result()?; let mres = driver.result(None).unwrap().unwrap(); let (is_on_curve, is_eq) = - msm::result_check_bls12_381(mres.result, msm_result, results, msm_size as usize); + //msm::result_check_bls12_381(mres.result, msm_result, results, msm_size as usize); + msm::result_check_bls12_377(mres.result, msm_result, results, msm_size as usize); log::info!("Is point on the {:?} curve {}", Curve::BLS377, is_on_curve); log::info!("Is Result Equal To Expected {}", is_eq); assert!(is_on_curve); @@ -104,8 +120,8 @@ fn msm_bls12_377_test() -> Result<(), Box> { let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { + // PRECOMPUTE_FACTOR_BASE mem_type: PointMemoryType::DMA, - is_precompute: false, curve: Curve::BLS377, }, dclient, @@ -119,7 +135,7 @@ fn msm_bls12_377_test() -> Result<(), Box> { driver.task_label()?; let (points, scalars, msm_result, results) = - msm::input_generator_bls12_377(msm_size as usize, PRECOMPUTE_FACTOR_BASE); + msm::input_generator_bls12_377(msm_size as usize, driver.get_precompute_factor().into()); log::info!("Starting to initialize task and set number of elements: "); let msm_params = MSMParams { @@ -155,15 +171,14 @@ fn msm_bls12_381_test() -> Result<(), Box> { .parse::() .unwrap(); - let (points, scalars, msm_result, results) = - msm::input_generator_bls12_381(msm_size as usize, PRECOMPUTE_FACTOR_BASE); - + /* let (points, scalars, msm_result, results) = + msm::input_generator_bls12_381(msm_size as usize, PRECOMPUTE_FACTOR_BASE); + */ log::info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: false, curve: Curve::BLS381, }, dclient, @@ -186,6 +201,10 @@ fn msm_bls12_381_test() -> Result<(), Box> { driver.initialize(msm_params)?; driver.start_process(None)?; log::info!("Starting to calculate MSM: "); + + let (points, scalars, msm_result, results) = + msm::input_generator_bls12_381(msm_size as usize, driver.get_precompute_factor().into()); + driver.set_data(MSMInput { points: Some(points), scalars, @@ -220,7 +239,6 @@ fn msm_bn254_test() -> Result<(), Box> { let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: false, curve: Curve::BN254, }, dclient, @@ -234,7 +252,7 @@ fn msm_bn254_test() -> Result<(), Box> { driver.task_label()?; let (points, scalars, msm_result, results) = - msm::input_generator_bn254(msm_size as usize, PRECOMPUTE_FACTOR_BASE); + msm::input_generator_bn254(msm_size as usize, driver.get_precompute_factor().into()); log::info!("Starting to initialize task and set number of elements: "); let msm_params = MSMParams { @@ -285,38 +303,29 @@ impl Display for RunResults { fn msm_bls12_377_precompute_test() -> Result<(), Box> { env_logger::try_init().expect("Invalid logger initialisation"); let id = env::var("ID").unwrap_or_else(|_| 0.to_string()); - let low_exp: u32 = 1; - let max_exp: u32 = 1; + let low_exp: u32 = 10; + let max_exp: u32 = 10; let base = 2; - log::debug!("Timer generation start"); - let start_gen = Instant::now(); - let (points, scalars, _, results) = - msm::input_generator_bls12_377(Pow::pow(base, max_exp) as usize, PRECOMPUTE_FACTOR); - let duration_gen = start_gen.elapsed(); - log::debug!("Time elapsed in input generation is: {:?}", duration_gen); + let mut points: Vec = Vec::new(); + let mut scalars: Vec = Vec::new(); + let mut results: Vec = Vec::new(); let mut run_results: Vec = Vec::new(); for iter in low_exp..=max_exp { let msm_size = Pow::pow(base, iter) as usize; log::debug!("MSM size: {}", msm_size); - let mut points_to_run = vec![0; msm_size * 96 * PRECOMPUTE_FACTOR as usize]; - let mut scalars_to_run = vec![0; msm_size * 32]; - - points_to_run.copy_from_slice(&points[0..msm_size * 96 * PRECOMPUTE_FACTOR as usize]); - scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); - log::info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: true, curve: Curve::BLS377, }, dclient, ); driver.driver_client.reset()?; + driver.get_api(); log::info!("Checking MSM core is ready: "); driver.is_msm_engine_ready()?; @@ -337,6 +346,23 @@ fn msm_bls12_377_precompute_test() -> Result<(), Box> { log::debug!("Timer start"); let start_set_data = Instant::now(); let start_full = Instant::now(); + + let precompute_factor = driver.get_precompute_factor().into(); + + if iter == low_exp { + (points, scalars, _, results) = + msm::input_generator_bls12_377(Pow::pow(base, max_exp) as usize, precompute_factor); + } + + //let msm_size = (Pow::pow(base, iter) as u32 * precompute_factor )as usize; + let msm_size = Pow::pow(base, iter) as usize; + log::debug!("MSM size: {}", msm_size); + let mut points_to_run = vec![0; msm_size * 96 * precompute_factor as usize]; + let mut scalars_to_run = vec![0; msm_size * 32]; + + points_to_run.copy_from_slice(&points[0..msm_size * 96 * precompute_factor as usize]); + scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); + driver.set_data(MSMInput { points: Some(points_to_run), scalars: scalars_to_run, @@ -386,30 +412,40 @@ fn msm_bls12_377_precompute_test() -> Result<(), Box> { fn msm_bls12_377_precompute_max_test() -> Result<(), Box> { env_logger::try_init().expect("Invalid logger initialisation"); let id = env::var("ID").unwrap_or_else(|_| 0.to_string()); - let msm_size = 67108864; // 2**26 + let bin_file = env::var("BIN_FILE").unwrap_or_else(|_| { + "/home/administrator/users/eli/fpga-bin/msm-bls377/msmfeb20.bin".to_string() + }); - log::debug!("Timer start to generate test data"); - let start_gen = Instant::now(); - let (points, scalars, msm_result, results) = - msm::input_generator_bls12_377(msm_size as usize, PRECOMPUTE_FACTOR); - let duration_gen = start_gen.elapsed(); - log::debug!("Time elapsed in generate test data is: {:?}", duration_gen); + let msm_size = 1024; //67108864; //8388608; // 1048576; //67108864; //67108864; // 2**26 log::info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: true, curve: Curve::BLS377, }, dclient, ); + + if driver.get_bin_type() != BinType::MSM { + return Err(Box::new(DriverClientError::NotMsmBin)); + } + driver.driver_client.reset()?; - let params = driver.loaded_binary_parameters(); - let params_parce = MSMImageParametrs::parse_image_params(params[1]); - params_parce.debug_information(); + log::info!("Start to loading binary file..."); + let buf = read_binary_file(&bin_file)?; + log::info!("Buffer size: {:?}", buf.len()); + + log::info!("Loading Binary File..."); + driver.driver_client.setup_before_load_binary()?; + let ret = driver.driver_client.load_binary(buf.as_slice()); + log::info!("Load binary return HBICAP code: {:?}", ret); + driver.driver_client.unblock_firewalls()?; + + driver.driver_client.firewalls_status(); + log::info!("Checking MSM core is ready: "); driver.is_msm_engine_ready()?; driver.task_label()?; @@ -421,7 +457,14 @@ fn msm_bls12_377_precompute_max_test() -> Result<(), Box> hbm_point_addr: None, }; driver.initialize(msm_params)?; + + println!("is_msm_engine_ready = {}", driver.is_msm_engine_ready()?); driver.start_process(None)?; + //driver.start_process(Some(1))?; + println!( + "nof_pending_tasks_in_queue = {}", + driver.nof_pending_tasks_in_queue()? + ); driver.driver_client.firewalls_status(); driver.task_label()?; @@ -431,13 +474,25 @@ fn msm_bls12_377_precompute_max_test() -> Result<(), Box> log::debug!("Timer start"); let start_set_data = Instant::now(); let start_full = Instant::now(); + + let precompute_factor: u32 = driver.get_precompute_factor().into(); + let scalar_size = driver.get_scalar_size() * 8; + println!("precompute_factor = {}", precompute_factor); + + log::debug!("Timer start to generate test data"); + let start_gen = Instant::now(); + let (points, scalars, msm_result, results) = + msm::input_generator_bls12_377(msm_size as usize, precompute_factor); + let duration_gen = start_gen.elapsed(); + log::debug!("Time elapsed in generate test data is: {:?}", duration_gen); + driver.set_data(MSMInput { points: Some(points), scalars, params: msm_params, })?; let dur_set = start_set_data.elapsed(); - + println!("is_msm_engine_ready = {}", driver.is_msm_engine_ready()?); let start_wait = Instant::now(); driver.driver_client.firewalls_status(); log::info!("Waiting MSM result: "); @@ -474,35 +529,30 @@ fn msm_bls12_381_precompute_test() -> Result<(), Box> { let max_exp: u32 = 18; let base = 2; - log::debug!("Timer generation start"); - let start_gen = Instant::now(); - let (points, scalars, _, results) = - msm::input_generator_bls12_381(Pow::pow(base, max_exp) as usize, PRECOMPUTE_FACTOR); - let duration_gen = start_gen.elapsed(); - log::debug!("Time elapsed in input generation is: {:?}", duration_gen); + let mut points: Vec = Vec::new(); + let mut scalars: Vec = Vec::new(); + let mut results: Vec = Vec::new(); let mut run_results: Vec = Vec::new(); for iter in low_exp..=max_exp { let msm_size = Pow::pow(base, iter) as usize; log::debug!("MSM size: {}", msm_size); - let mut points_to_run = vec![0; msm_size * 96 * PRECOMPUTE_FACTOR as usize]; - let mut scalars_to_run = vec![0; msm_size * 32]; - - points_to_run.copy_from_slice(&points[0..msm_size * 96 * PRECOMPUTE_FACTOR as usize]); - scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); - log::info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: true, + curve: Curve::BLS381, }, dclient, ); driver.driver_client.reset()?; + if driver.get_bin_type() != BinType::MSM { + return Err(Box::new(DriverClientError::NotMsmBin)); + } + log::info!("Checking MSM core is ready: "); driver.is_msm_engine_ready()?; driver.task_label()?; @@ -518,6 +568,17 @@ fn msm_bls12_381_precompute_test() -> Result<(), Box> { driver.driver_client.firewalls_status(); + let precompute_factor = driver.get_precompute_factor().into(); + if iter == low_exp { + (points, scalars, _, results) = + msm::input_generator_bls12_381(Pow::pow(base, max_exp) as usize, precompute_factor); + } + let mut points_to_run = vec![0; msm_size * 96 * precompute_factor as usize]; + let mut scalars_to_run = vec![0; msm_size * 32]; + + points_to_run.copy_from_slice(&points[0..msm_size * 96 * precompute_factor as usize]); + scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); + log::info!("Starting to calculate MSM: "); log::debug!("Timer start"); let start_set_data = Instant::now(); @@ -573,23 +634,20 @@ fn msm_bls12_381_precompute_max_test() -> Result<(), Box> let id = env::var("ID").unwrap_or_else(|_| 0.to_string()); let msm_size = 67108864; // 2**26 - log::debug!("Timer start to generate test data"); - let start_gen = Instant::now(); - let (points, scalars, msm_result, results) = - msm::input_generator_bls12_381(msm_size as usize, PRECOMPUTE_FACTOR); - let duration_gen = start_gen.elapsed(); - log::debug!("Time elapsed in generate test data is: {:?}", duration_gen); - log::info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: true, curve: Curve::BLS381, }, dclient, ); + + if driver.get_bin_type() != BinType::MSM { + return Err(Box::new(DriverClientError::NotMsmBin)); + } + driver.driver_client.reset()?; let params = driver.loaded_binary_parameters(); @@ -612,6 +670,15 @@ fn msm_bls12_381_precompute_max_test() -> Result<(), Box> driver.task_label()?; driver.nof_elements()?; + let precompute_factor = driver.get_precompute_factor().into(); + + log::debug!("Timer start to generate test data"); + let start_gen = Instant::now(); + let (points, scalars, msm_result, results) = + msm::input_generator_bls12_381(msm_size as usize, precompute_factor); + let duration_gen = start_gen.elapsed(); + log::debug!("Time elapsed in generate test data is: {:?}", duration_gen); + log::info!("Starting to calculate MSM: "); log::debug!("Timer start"); let start_set_data = Instant::now(); diff --git a/tests/integration_msm_hbm.rs b/tests/integration_msm_hbm.rs index 844b4a6..3f3c3f1 100644 --- a/tests/integration_msm_hbm.rs +++ b/tests/integration_msm_hbm.rs @@ -1,4 +1,8 @@ +use ark_bls12_377::G1Projective as bls377G1Projective; +use ark_bls12_381::G1Projective as bls381G1Projective; + use crate::msm::RunResults; + use ingo_blaze::{driver_client::*, ingo_msm::*}; use num_traits::Pow; use std::{ @@ -17,13 +21,17 @@ fn hbm_msm_bls12_381_precomp_test() -> Result<(), Box> { let max_exp: u32 = 1; let base = 2; - log::debug!("Timer generation start"); - let start_gen = Instant::now(); - let (points, scalars, _, results) = - msm::input_generator_bls12_381(Pow::pow(base, max_exp) as usize, PRECOMPUTE_FACTOR); - let duration_gen = start_gen.elapsed(); - log::debug!("Time elapsed in input generation is: {:?}", duration_gen); - + let mut points: Vec = Vec::new(); + let mut scalars: Vec = Vec::new(); + let mut results: Vec = Vec::new(); + + /* log::debug!("Timer generation start"); + let start_gen = Instant::now(); + let (points, scalars, _, results) = + msm::input_generator_bls12_381(Pow::pow(base, max_exp) as usize, PRECOMPUTE_FACTOR); + let duration_gen = start_gen.elapsed(); + log::debug!("Time elapsed in input generation is: {:?}", duration_gen); + */ let mut run_results: Vec = Vec::new(); for iter in low_exp..=max_exp { let msm_size = Pow::pow(base, iter) as usize; @@ -39,7 +47,6 @@ fn hbm_msm_bls12_381_precomp_test() -> Result<(), Box> { let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::DMA, - is_precompute: true, curve: Curve::BLS381, }, dclient, @@ -74,6 +81,22 @@ fn hbm_msm_bls12_381_precomp_test() -> Result<(), Box> { log::debug!("Timer start"); let start_set_data = Instant::now(); let start_full = Instant::now(); + + if iter == low_exp { + (points, scalars, _, results) = msm::input_generator_bls12_381( + Pow::pow(base, max_exp) as usize, + driver.get_precompute_factor().into(), + ); + } + + let msm_size = Pow::pow(base, iter) as usize; + log::debug!("MSM size: {}", msm_size); + let mut points_to_run = vec![0; msm_size * 8 * 96]; + let mut scalars_to_run = vec![0; msm_size * 32]; + + points_to_run.copy_from_slice(&points[0..msm_size * 8 * 96]); + scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); + driver.set_data(MSMInput { points: None, scalars: scalars_to_run, @@ -125,29 +148,37 @@ fn hbm_msm_bls12_377_precomp_test() -> Result<(), Box> { let max_exp: u32 = 1; let base = 2; - log::debug!("Timer generation start"); + let mut points: Vec = Vec::new(); + let mut scalars: Vec = Vec::new(); + let mut results: Vec = Vec::new(); + /* log::debug!("Timer generation start"); let start_gen = Instant::now(); let (points, scalars, _, results) = msm::input_generator_bls12_377(Pow::pow(base, max_exp) as usize, PRECOMPUTE_FACTOR); let duration_gen = start_gen.elapsed(); - log::debug!("Time elapsed in input generation is: {:?}", duration_gen); + log::debug!("Time elapsed in input generation is: {:?}", duration_gen); */ let mut run_results: Vec = Vec::new(); for iter in low_exp..=max_exp { let msm_size = Pow::pow(base, iter) as usize; + /* if iter == low_exp { + (points, scalars, _, results) = + msm::input_generator_bls12_377(Pow::pow(base, max_exp) as usize, PRECOMPUTE_FACTOR); + } + + log::debug!("MSM size: {}", msm_size); let mut points_to_run = vec![0; msm_size * 8 * 96]; let mut scalars_to_run = vec![0; msm_size * 32]; points_to_run.copy_from_slice(&points[0..msm_size * 8 * 96]); - scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); + scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); */ log::info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); let driver = MSMClient::new( MSMInit { mem_type: PointMemoryType::HBM, - is_precompute: true, curve: Curve::BLS377, }, dclient, @@ -183,6 +214,22 @@ fn hbm_msm_bls12_377_precomp_test() -> Result<(), Box> { log::debug!("Timer start"); let start_set_data = Instant::now(); let start_full = Instant::now(); + + if iter == low_exp { + (points, scalars, _, results) = msm::input_generator_bls12_377( + Pow::pow(base, max_exp) as usize, + driver.get_precompute_factor().into(), + ); + } + + let msm_size = Pow::pow(base, iter) as usize; + log::debug!("MSM size: {}", msm_size); + let mut points_to_run = vec![0; msm_size * 8 * 96]; + let mut scalars_to_run = vec![0; msm_size * 32]; + + points_to_run.copy_from_slice(&points[0..msm_size * 8 * 96]); + scalars_to_run.copy_from_slice(&scalars[0..msm_size * 32]); + driver.set_data(MSMInput { points: None, scalars: scalars_to_run, diff --git a/tests/integration_ntt.rs b/tests/integration_ntt.rs index 2d42e09..2c514e7 100644 --- a/tests/integration_ntt.rs +++ b/tests/integration_ntt.rs @@ -1,3 +1,5 @@ +extern crate ingo_blaze; + use ingo_blaze::{driver_client::*, ingo_ntt::*, utils}; use log::info; use std::{env, error::Error, fs::File, io::Read}; @@ -7,12 +9,19 @@ fn ntt_test_correctness() -> Result<(), Box> { env_logger::try_init().expect("Invalid logger initialisation"); let id = env::var("ID").unwrap_or_else(|_| 0.to_string()); - let input_fname = env::var("INFNAME").unwrap(); + //let input_fname = env::var("INFNAME").unwrap(); + let input_fname = env::var("INFNAME").unwrap_or_else(|_| { + "/home/administrator/ekaterina/blaze/tests/test_data/in_bin_00.dat".to_string() + }); + let mut in_f = File::open(input_fname).expect("no file found"); let mut in_vec: Vec = Default::default(); in_f.read_to_end(&mut in_vec)?; - let output_fname = env::var("OUTFNAME").unwrap(); + //let output_fname = env::var("OUTFNAME").unwrap(); + let output_fname = env::var("OUTFNAME").unwrap_or_else(|_| { + "/home/administrator/ekaterina/blaze/tests/test_data/ref_bin_00.dat".to_string() + }); let mut out_f = File::open(output_fname).expect("no file found"); let mut out_vec: Vec = Default::default(); out_f.read_to_end(&mut out_vec)?; @@ -22,15 +31,16 @@ fn ntt_test_correctness() -> Result<(), Box> { info!("Create Driver API instance"); let dclient = DriverClient::new(&id, DriverConfig::driver_client_cfg(CardType::C1100)); - if std::env::var("BIN").is_ok() { - let bin_fname = std::env::var("BIN").unwrap(); - info!("Start reading binary"); - let bin = utils::read_binary_file(&bin_fname)?; - info!("Start setup FPGA"); - dclient.setup_before_load_binary()?; - info!("Start loading driver"); - dclient.load_binary(&bin)?; - } + //if std::env::var("BIN").is_ok() { + //let bin_fname = std::env::var("BIN").unwrap(); + let bin_fname = "/home/administrator/eli/fpga-bin/ntt/user.bin"; + info!("Start reading binary"); + let bin = utils::read_binary_file(&bin_fname)?; + info!("Start setup FPGA"); + dclient.setup_before_load_binary()?; + info!("Start loading driver"); + dclient.load_binary(&bin)?; + //} let driver = NTTClient::new(NTT::Ntt, dclient); log::info!("Starting set NTT data"); diff --git a/tests/integration_poseidon.rs b/tests/integration_poseidon.rs index d3f5723..45ffa74 100755 --- a/tests/integration_poseidon.rs +++ b/tests/integration_poseidon.rs @@ -8,8 +8,8 @@ use dotenv::dotenv; use ingo_blaze::{ driver_client::*, ingo_hash::{ - num_of_elements_in_base_layer, Hash, PoseidonClient, PoseidonInitializeParameters, - PoseidonResult, TreeMode, + num_of_elements_in_base_layer, Align4K, DmaBuffer, Hash, PoseidonClient, + PoseidonInitializeParameters, PoseidonReadResult, PoseidonResult, TreeMode, }, }; use log::info; @@ -17,7 +17,8 @@ use num::{BigUint, Num}; fn get_instruction_path() -> String { dotenv().ok(); - std::env::var("INSTRUCTION_PATH").expect("INSTRUCTION_PATH must be set.") + //std::env::var("INSTRUCTION_PATH").expect("INSTRUCTION_PATH must be set.") // TBD ENV + return "/home/administrator/users/ido/hw-poseidon/programs/PoseidonFullWPRC.csv".to_string(); } const TREE_HEIGHT_4_NUM_OF_NODES: usize = 585; @@ -57,7 +58,86 @@ fn test_sanity_check() { } #[test] -fn test_build_small_tree_par() { +fn test_build_small_tree_parllel() { + rayon::scope_fifo(|scope| { + let instruction_path = get_instruction_path(); + + env_logger::try_init().expect("Invalid logger initialization"); + + let dclient = DriverClient::new(&"0", DriverConfig::driver_client_cfg(CardType::C1100)); + let poseidon: Arc = Arc::new(PoseidonClient::new(Hash::Poseidon, dclient)); + + let tree_height = 7; + let (input_size, results_size) = get_hash_input_outputs(tree_height); + + let params = PoseidonInitializeParameters { + tree_height, + tree_mode: TreeMode::TreeC, + instruction_path, + }; + + let nof_elements = num_of_elements_in_base_layer(params.tree_height); + + poseidon.initialize(params); + + poseidon.loaded_binary_parameters(); + + let scalar: Vec = BigUint::from_str_radix(TEST_SCALAR, 10) + .unwrap() + .to_bytes_le(); + + let mut input_buffer = DmaBuffer::new::(input_size * 32); + let mut output_buffer = DmaBuffer::new::(results_size * 64); + + for _ in 0..(results_size * 64) { + output_buffer.get_mut().push(0); + } + + for _ in 0..nof_elements { + for _ in 0..11 { + input_buffer.extend_from_slice(scalar.as_slice()); + } + } + + let poseidon_c = poseidon.clone(); + + scope.spawn_fifo(move |_s| { + assert_eq!((input_buffer.get_mut().as_mut_ptr() as u64) % 4096, 0); + + poseidon_c.set_data(input_buffer.as_slice()); + + poseidon_c.log_api_values(); + log::debug!("done writing"); + }); + + scope.spawn_fifo(move |_s| { + assert_eq!((output_buffer.get_mut().as_mut_ptr() as u64) % 4096, 0); + + let result = poseidon + .result(Some(TREE_HEIGHT_4_NUM_OF_NODES)) // compare to old poseidon/dist branch + .unwrap() + .unwrap(); + + /* let result = poseidon + .result(Some(PoseidonReadResult { + expected_result: output_buffer.len() / 64, + result_store_buffer: &mut output_buffer, + })) + .unwrap() + .unwrap(); */ + + poseidon.log_api_values(); + + assert_eq!(result.len(), output_buffer.len() / 64); + + log::debug!("result {:?}", result.len()); + log::debug!("done"); + }); + }); +} + +#[test] +/* fn test_build_small_tree_par() { let instruction_path = get_instruction_path(); env_logger::try_init().expect("Invalid logger initialization"); @@ -118,7 +198,7 @@ fn test_build_small_tree_par() { }); }); } - + */ #[test] fn test_build_small_tree() { let instruction_path = get_instruction_path(); @@ -167,3 +247,18 @@ fn test_build_small_tree() { log::debug!("{:?}", result.len()); log::debug!("done"); } + +fn get_hash_input_outputs(tree_size: u32) -> (usize, usize) { + let nof_elements = 11 * (u64::pow(8, tree_size)); + + let mut nof_results = 0; + for layer in 0..tree_size + 1 { + let results_in_layer = u64::pow(8, tree_size - layer); + nof_results += results_in_layer; + } + + ( + nof_elements.try_into().unwrap(), + nof_results.try_into().unwrap(), + ) +} diff --git a/tests/msm/mod.rs b/tests/msm/mod.rs index 516df77..95e5f1c 100755 --- a/tests/msm/mod.rs +++ b/tests/msm/mod.rs @@ -14,11 +14,10 @@ use ark_std::UniformRand; use ::std::ops::{Add, Mul}; use std::{fmt::Display, time::Duration}; -const SCALAR_SIZE_BLS377: u32 = 32; -const SCALAR_SIZE_BLS381: u32 = 32; -const SCALAR_SIZE_BN254: u32 = 32; - const LARGE_PARAM: usize = 256; +const SCALAR_SIZE_BLS377: usize = 256; +const SCALAR_SIZE_BLS381: usize = 256; +const SCALAR_SIZE_BN254: usize = 256; fn get_large_param(nof_elements: usize) -> (bool, usize, usize, usize) { if nof_elements > LARGE_PARAM { @@ -120,11 +119,13 @@ pub fn precompute_base_bls12_377(base: bls377G1Affine, precompute_factor: u32) - bases.extend_from_slice(&x_bytes); bases.extend_from_slice(&y_bytes); let two = num_bigint::BigUint::from(2u32); + + let scalar_size_bls377 = (SCALAR_SIZE_BLS377 as f32 / precompute_factor as f32).ceil() as u32; + for i in 1..precompute_factor { current_point = base; - let coeff = bls377Fr::from(two.pow(SCALAR_SIZE_BLS377 * i)); + let coeff = bls377Fr::from(two.pow(scalar_size_bls377 * i)); current_point = current_point.mul(coeff).into_affine(); - let x_bytes = current_point.x.into_repr().to_bytes_le(); let y_bytes = current_point.y.into_repr().to_bytes_le(); bases.extend_from_slice(&x_bytes); @@ -167,6 +168,7 @@ pub fn result_check_bls12_377( ) } else { log::debug!("Expected MSM result: {:}\n", msm_res.into_affine()); + //println!("{} {}",point.to_string(), msm_res.into_affine().to_string()); ( point.is_on_curve(), point.to_string() == msm_res.into_affine().to_string(), @@ -240,11 +242,13 @@ pub fn precompute_base_bn254(base: bn254G1Affine, precompute_factor: u32) -> Vec bases.extend_from_slice(&x_bytes); bases.extend_from_slice(&y_bytes); let two = num_bigint::BigUint::from(2u32); + + let scalar_size_bn254 = (SCALAR_SIZE_BN254 as f32 / precompute_factor as f32).ceil() as u32; + for i in 1..precompute_factor { current_point = base; - let coeff = bn254Fr::from(two.pow(SCALAR_SIZE_BN254 * i)); + let coeff = bn254Fr::from(two.pow(scalar_size_bn254 * i)); current_point = current_point.mul(coeff).into_affine(); - let x_bytes = current_point.x.into_repr().to_bytes_le(); let y_bytes = current_point.y.into_repr().to_bytes_le(); bases.extend_from_slice(&x_bytes); @@ -365,11 +369,13 @@ pub fn precompute_base_bls12_381(base: bls381G1Affine, precompute_factor: u32) - bases.extend_from_slice(&x_bytes); bases.extend_from_slice(&y_bytes); let two = num_bigint::BigUint::from(2u32); + + let scalar_size_bls381 = (SCALAR_SIZE_BLS381 as f32 / precompute_factor as f32).ceil() as u32; + for i in 1..precompute_factor { current_point = base; - let coeff = bls381Fr::from(two.pow(SCALAR_SIZE_BLS381 * i)); + let coeff = bls381Fr::from(two.pow(scalar_size_bls381 * i)); current_point = current_point.mul(coeff).into_affine(); - let x_bytes = current_point.x.into_repr().to_bytes_le(); let y_bytes = current_point.y.into_repr().to_bytes_le(); bases.extend_from_slice(&x_bytes);