diff --git a/src/command_templates.rs b/src/command_templates.rs index 637d1b3..7fb3ff4 100644 --- a/src/command_templates.rs +++ b/src/command_templates.rs @@ -223,79 +223,3 @@ fn extract_template_vals(input: &str, templates: Vec) -> Result String { - // Convert amount to string in wei format (no decimals) - let uint_str = uint.to_string(); - let uint_length = uint_str.len(); - - // Create result vector with max length - // If less than 18 decimals, then 2 extra for "0.", otherwise one extra for "." - let mut result = vec![ - '0'; - if uint_length > decimal { - uint_length + 1 - } else { - decimal + 2 - } - ]; - let result_length = result.len(); - - // Difference between result and amount array index when copying - // If more than 18, then 1 index diff for ".", otherwise actual diff in length - let mut delta = if uint_length > decimal { - 1 - } else { - result_length - uint_length - }; - - // Boolean to indicate if we found a non-zero digit when scanning from last to first index - let mut found_non_zero_decimal = false; - - let mut actual_result_len = 0; - - // In each iteration we fill one index of result array (starting from end) - for i in (0..result_length).rev() { - // Check if we have reached the index where we need to add decimal point - if i == result_length - decimal - 1 { - // No need to add "." if there was no value in decimal places - if found_non_zero_decimal { - result[i] = '.'; - actual_result_len += 1; - } - // Set delta to 0, as we have already added decimal point (only for amount_length > 18) - delta = 0; - } - // If amountLength < 18 and we have copied everything, fill zeros - else if uint_length <= decimal && i < result_length - uint_length { - result[i] = '0'; - actual_result_len += 1; - } - // If non-zero decimal is found, or decimal point inserted (delta == 0), copy from amount array - else if found_non_zero_decimal || delta == 0 { - result[i] = uint_str.chars().nth(i - delta).unwrap(); - actual_result_len += 1; - } - // If we find non-zero decimal for the first time (trailing zeros are skipped) - else if uint_str.chars().nth(i - delta).unwrap() != '0' { - result[i] = uint_str.chars().nth(i - delta).unwrap(); - actual_result_len += 1; - found_non_zero_decimal = true; - } - } - - // Create final result string with correct length - let compact_result: String = result.into_iter().take(actual_result_len).collect(); - - compact_result -} diff --git a/src/converters.rs b/src/converters.rs index 3f588f5..44dfa98 100644 --- a/src/converters.rs +++ b/src/converters.rs @@ -351,3 +351,79 @@ pub fn u256_to_bytes32_little(x: &U256) -> [u8; 32] { x.to_little_endian(&mut bytes); bytes } + +/// Converts an unsigned integer to a decimal string representation. +/// +/// # Arguments +/// +/// * `uint` - The unsigned integer to convert. +/// * `decimal` - The number of decimal places to use. +/// +/// # Returns +/// +/// A string representation of the decimal value. +pub fn uint_to_decimal_string(uint: u128, decimal: usize) -> String { + // Convert amount to string in wei format (no decimals) + let uint_str = uint.to_string(); + let uint_length = uint_str.len(); + + // Create result vector with max length + // If less than 18 decimals, then 2 extra for "0.", otherwise one extra for "." + let mut result = vec![ + '0'; + if uint_length > decimal { + uint_length + 1 + } else { + decimal + 2 + } + ]; + let result_length = result.len(); + + // Difference between result and amount array index when copying + // If more than 18, then 1 index diff for ".", otherwise actual diff in length + let mut delta = if uint_length > decimal { + 1 + } else { + result_length - uint_length + }; + + // Boolean to indicate if we found a non-zero digit when scanning from last to first index + let mut found_non_zero_decimal = false; + + let mut actual_result_len = 0; + + // In each iteration we fill one index of result array (starting from end) + for i in (0..result_length).rev() { + // Check if we have reached the index where we need to add decimal point + if i == result_length - decimal - 1 { + // No need to add "." if there was no value in decimal places + if found_non_zero_decimal { + result[i] = '.'; + actual_result_len += 1; + } + // Set delta to 0, as we have already added decimal point (only for amount_length > 18) + delta = 0; + } + // If amountLength < 18 and we have copied everything, fill zeros + else if uint_length <= decimal && i < result_length - uint_length { + result[i] = '0'; + actual_result_len += 1; + } + // If non-zero decimal is found, or decimal point inserted (delta == 0), copy from amount array + else if found_non_zero_decimal || delta == 0 { + result[i] = uint_str.chars().nth(i - delta).unwrap(); + actual_result_len += 1; + } + // If we find non-zero decimal for the first time (trailing zeros are skipped) + else if uint_str.chars().nth(i - delta).unwrap() != '0' { + result[i] = uint_str.chars().nth(i - delta).unwrap(); + actual_result_len += 1; + found_non_zero_decimal = true; + } + } + + // Create final result string with correct length + let compact_result: String = result.into_iter().take(actual_result_len).collect(); + + compact_result +} diff --git a/src/cryptos.rs b/src/cryptos.rs index 78d6fea..346255a 100644 --- a/src/cryptos.rs +++ b/src/cryptos.rs @@ -1,11 +1,13 @@ //! Cryptographic functions. +use crate::{field_to_hex, hex_to_field}; use ethers::types::Bytes; use halo2curves::ff::Field; -use hmac_sha256::Hash; use poseidon_rs::{poseidon_bytes, poseidon_fields, Fr, PoseidonError}; use rand_core::RngCore; +use std::collections::hash_map::DefaultHasher; use std::error::Error; +use std::hash::{Hash, Hasher}; use zk_regex_apis::padding::pad_string; use crate::{ @@ -312,7 +314,7 @@ pub fn sha256_pad(mut data: Vec, max_sha_bytes: usize) -> (Vec, usize) { /// /// A vector containing the SHA-256 hash of the message. pub fn partial_sha(msg: &[u8], msg_len: usize) -> Vec { - let mut hasher = Hash::new(); + let mut hasher = hmac_sha256::Hash::new(); hasher.update(&msg[..msg_len]); let result = hasher.cache_state(); result.to_vec() @@ -436,3 +438,49 @@ mod tests { assert_eq!(field_to_hex(&hash_field), expected_hash); } } + +/// Calculates a default hash for the given input string. +/// +/// # Arguments +/// +/// * `input` - The input string to hash. +/// +/// # Returns +/// +/// A string representation of the calculated hash. +pub fn calculate_default_hash(input: &str) -> String { + let mut hasher = DefaultHasher::new(); + input.hash(&mut hasher); + let hash_code = hasher.finish(); + + hash_code.to_string() +} + +/// Calculates the account salt based on the email address and account code. +/// +/// # Arguments +/// +/// * `email_addr` - The email address string. +/// * `account_code` - The account code string. +/// +/// # Returns +/// +/// A string representation of the calculated account salt. +pub fn calculate_account_salt(email_addr: &str, account_code: &str) -> String { + // Pad the email address + let padded_email_addr = PaddedEmailAddr::from_email_addr(email_addr); + + // Convert account code to field element + let account_code = if account_code.starts_with("0x") { + hex_to_field(account_code).unwrap() + } else { + hex_to_field(&format!("0x{}", account_code)).unwrap() + }; + let account_code = AccountCode::from(account_code); + + // Generate account salt + let account_salt = AccountSalt::new(&padded_email_addr, account_code).unwrap(); + + // Convert account salt to hexadecimal representation + field_to_hex(&account_salt.0) +} diff --git a/src/proof.rs b/src/proof.rs index 74e31bf..0efe046 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -7,11 +7,6 @@ use ethers::types::{Bytes, U256}; use ::serde::Deserialize; -use std::collections::hash_map::DefaultHasher; -use std::hash::{Hash, Hasher}; - -use crate::{field_to_hex, hex_to_field, AccountCode, AccountSalt, PaddedEmailAddr}; - /// Represents the response from the prover. #[derive(Debug, Clone, Deserialize)] pub struct ProverRes { @@ -109,49 +104,3 @@ pub async fn generate_proof( Ok((proof, pub_signals)) } - -/// Calculates a default hash for the given input string. -/// -/// # Arguments -/// -/// * `input` - The input string to hash. -/// -/// # Returns -/// -/// A string representation of the calculated hash. -pub fn calculate_default_hash(input: &str) -> String { - let mut hasher = DefaultHasher::new(); - input.hash(&mut hasher); - let hash_code = hasher.finish(); - - hash_code.to_string() -} - -/// Calculates the account salt based on the email address and account code. -/// -/// # Arguments -/// -/// * `email_addr` - The email address string. -/// * `account_code` - The account code string. -/// -/// # Returns -/// -/// A string representation of the calculated account salt. -pub fn calculate_account_salt(email_addr: &str, account_code: &str) -> String { - // Pad the email address - let padded_email_addr = PaddedEmailAddr::from_email_addr(email_addr); - - // Convert account code to field element - let account_code = if account_code.starts_with("0x") { - hex_to_field(account_code).unwrap() - } else { - hex_to_field(&format!("0x{}", account_code)).unwrap() - }; - let account_code = AccountCode::from(account_code); - - // Generate account salt - let account_salt = AccountSalt::new(&padded_email_addr, account_code).unwrap(); - - // Convert account salt to hexadecimal representation - field_to_hex(&account_salt.0) -}