Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Rescue Prime Optimized #930

Merged
merged 25 commits into from
Nov 11, 2024
Merged

Add Rescue Prime Optimized #930

merged 25 commits into from
Nov 11, 2024

Conversation

jotabulacios
Copy link
Contributor

@jotabulacios jotabulacios commented Oct 16, 2024

Add Rescue Prime Optimized

Description

This PR adds the Rescue Prime Optimized hash function.
The implementation offers three types of MDS transformations: Matrix Multiplication, Karatsuba, and NTT

Example:

let rescue = RescuePrimeOptimized::new(SecurityLevel::Sec128, MdsMethod::Ntt).unwrap();
let input = b"Hello there";
let hash_output = rescue.hash(input);

In this case 128 is the security level, the other available level is 160
To use other MdsMethod simply change MatrixMultiplication for Karatsuba or Ntt

Type of change

  • New feature

@jotabulacios jotabulacios marked this pull request as ready for review October 16, 2024 18:40
@jotabulacios jotabulacios requested a review from a team as a code owner October 16, 2024 18:40
@codecov-commenter
Copy link

codecov-commenter commented Oct 16, 2024

Codecov Report

Attention: Patch coverage is 92.80156% with 37 lines in your changes missing coverage. Please review.

Project coverage is 71.97%. Comparing base (8dfddac) to head (ea8267d).

Files with missing lines Patch % Lines
crypto/src/hash/rescue_prime/utils.rs 58.82% 28 Missing ⚠️
...to/src/hash/rescue_prime/rescue_prime_optimized.rs 98.07% 8 Missing ⚠️
crypto/src/hash/rescue_prime/parameters.rs 96.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #930      +/-   ##
==========================================
+ Coverage   71.62%   71.97%   +0.35%     
==========================================
  Files         149      152       +3     
  Lines       32560    33074     +514     
==========================================
+ Hits        23321    23805     +484     
- Misses       9239     9269      +30     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Ntt,
Karatsuba,
}
#[warn(dead_code)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need this annotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved, it wasn’t necessary. I added it while trying to fix some Clippy issues, but it turned out to be incorrect


fn get_mds_vector(m: usize) -> Vec<Fp> {
match m {
12 => vec![7, 23, 8, 26, 13, 10, 9, 7, 6, 22, 21, 8]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be an array instead of a vec

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, the mds_vector is now an array of Fp and is also precomputed

.into_iter()
.map(Fp::from)
.collect(),
_ => panic!("Unsupported state size"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this function shouldn't panic. It can return a Result indicating the error case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function isn't used anymore, but I acknowledged your comment about avoiding panics

let m = self.m;
let round_constants = &self.round_constants;
for j in 0..m {
state[j] += round_constants[round * 2 * m + j];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of indexing, this can be improved by using get_mut and an iterator

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the implementation as suggested

Comment on lines +4 to +17
pub fn bytes_to_field_elements(input: &[u8]) -> Vec<Fp> {
input
.chunks(7)
.map(|chunk| {
let mut buf = [0u8; 8];
buf[..chunk.len()].copy_from_slice(chunk);
if chunk.len() < 7 {
buf[chunk.len()] = 1;
}
let value = u64::from_le_bytes(buf);
Fp::from(value)
})
.collect()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function just for rescue_prime or a function that can be used elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently it 's only use in rescue_prime. Maybe later it can be added to fields

@@ -0,0 +1,816 @@
use crate::alloc::vec::Vec;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better not to have a giant mod.rs file.
Instead, it's better to have a separate file with each struct or enum.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restructured the files as suggested. Now is more maintainable and clear

Copy link
Collaborator

@ilitteri ilitteri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general rule, we won't want to panic anywhere. As this is a library meant for users, we must provide them Results of the operations to let them decide what to do with the errors in such cases. Commonly, panics can happen in places where unwraps, expects, as conversions, and slice indexing (and obviously when we explicitly use the panic macro). Unless it is planned for another PR to handle these cases I'd suggest doing it asap.

Unwraps and expects can be avoided returning Results. As conversions can be avoided mostly by using .into(), and .try_into() (we will prefer the first one as we'd not have to handle the error). Finally, slice indexing can be avoided using .get() and handling the Option.

To improve the code's readability we'd want to define descriptive constants for hardcoded structures.

crypto/src/hash/rescue_prime/mod.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/mod.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/mod.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/utils.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/mod.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/mod.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/mod.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/parameters.rs Outdated Show resolved Hide resolved
crypto/src/hash/rescue_prime/utils.rs Show resolved Hide resolved
@@ -0,0 +1,816 @@
use crate::alloc::vec::Vec;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Collaborator

@ilitteri ilitteri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is looking good! Left some comments

crypto/src/hash/rescue_prime/rescue_prime_optimized.rs Outdated Show resolved Hide resolved
Comment on lines 56 to 59
let (m, capacity) = match security_level {
SecurityLevel::Sec128 => (12, 4),
SecurityLevel::Sec160 => (16, 6),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do the same for these. get_state_size(security_level: SecurityLevel) and get_capacity(security_level: SecurityLevel).

Copy link
Collaborator

@ilitteri ilitteri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! LGTM

@jotabulacios jotabulacios added this pull request to the merge queue Nov 11, 2024
Merged via the queue into main with commit d35c96f Nov 11, 2024
8 checks passed
@jotabulacios jotabulacios deleted the add_rescue_prime branch November 11, 2024 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants