Skip to content

Commit

Permalink
Merge pull request #600 from cryspen/jonas/fips-204-sample-in-ball
Browse files Browse the repository at this point in the history
[ML-DSA] Use all of commitment hash to sample verifiers challenge
  • Loading branch information
jschneider-bensch authored Sep 30, 2024
2 parents 8c05744 + 899dabd commit f8a7d13
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 235 deletions.
3 changes: 1 addition & 2 deletions libcrux-ml-dsa/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,4 @@ pub const SIGNING_RANDOMNESS_SIZE: usize = 32;
pub(crate) const MESSAGE_REPRESENTATIVE_SIZE: usize = 64;
pub(crate) const MASK_SEED_SIZE: usize = 64;

pub(crate) const VERIFIER_CHALLENGE_SEED_SIZE: usize = 32;
pub(crate) const REJECTION_SAMPLE_BOUND: usize = 576;
pub(crate) const REJECTION_SAMPLE_BOUND_SIGN: usize = 814;
2 changes: 2 additions & 0 deletions libcrux-ml-dsa/src/hash_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ pub(crate) mod portable {
}

/// A SIMD256 implementation of [`shake128::XofX4`] and [`shake256::Xof`] for AVX2.
#[cfg(feature = "simd256")]
pub(crate) mod simd256 {

use libcrux_sha3::{
Expand Down Expand Up @@ -437,6 +438,7 @@ pub(crate) mod simd256 {
}

/// A SIMD256 implementation of [`shake128::Xof`] and [`shake256::Xof`] for Neon.
#[cfg(feature = "simd128")]
pub(crate) mod neon {

use libcrux_sha3::neon::x2::{self, incremental::KeccakState};
Expand Down
18 changes: 6 additions & 12 deletions libcrux-ml-dsa/src/ml_dsa_generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ pub(crate) fn sign<
// 2⁻¹²⁸[1].
//
// [1]: https://github.com/cloudflare/circl/blob/main/sign/dilithium/mode2/internal/dilithium.go#L341
while attempt < REJECTION_SAMPLE_BOUND {
while attempt < REJECTION_SAMPLE_BOUND_SIGN {
attempt += 1;

let mask =
Expand Down Expand Up @@ -215,11 +215,8 @@ pub(crate) fn sign<
SIMDUnit,
Shake256,
ONES_IN_VERIFIER_CHALLENGE,
>(
commitment_hash_candidate[0..VERIFIER_CHALLENGE_SEED_SIZE]
.try_into()
.unwrap(),
));
COMMITMENT_HASH_SIZE,
>(commitment_hash_candidate));

let challenge_times_s1 = vector_times_ring_element::<SIMDUnit, COLUMNS_IN_A>(
&s1_as_ntt,
Expand Down Expand Up @@ -263,7 +260,7 @@ pub(crate) fn sign<

if ones_in_hint > MAX_ONES_IN_HINT {
} else {
attempt = REJECTION_SAMPLE_BOUND; // exit loop now
attempt = REJECTION_SAMPLE_BOUND_SIGN; // exit loop now
commitment_hash = Some(commitment_hash_candidate);
signer_response = Some(signer_response_candidate);
hint = Some(hint_candidate);
Expand Down Expand Up @@ -361,11 +358,8 @@ pub(crate) fn verify<
SIMDUnit,
Shake256,
ONES_IN_VERIFIER_CHALLENGE,
>(
signature.commitment_hash[0..VERIFIER_CHALLENGE_SEED_SIZE]
.try_into()
.unwrap(),
));
COMMITMENT_HASH_SIZE,
>(signature.commitment_hash));

let w_approx = compute_w_approx::<SIMDUnit, ROWS_IN_A, COLUMNS_IN_A>(
&A_as_ntt,
Expand Down
9 changes: 5 additions & 4 deletions libcrux-ml-dsa/src/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,9 @@ pub(crate) fn sample_challenge_ring_element<
SIMDUnit: Operations,
Shake256: shake256::Xof,
const NUMBER_OF_ONES: usize,
const SEED_SIZE: usize,
>(
seed: [u8; 32],
seed: [u8; SEED_SIZE],
) -> PolynomialRingElement<SIMDUnit> {
let mut state = Shake256::init_absorb(&seed);
let randomness = state.squeeze_first_block();
Expand Down Expand Up @@ -683,7 +684,7 @@ mod tests {
];

assert_eq!(
sample_challenge_ring_element::<SIMDUnit, Shake256, 39>(seed).to_i32_array(),
sample_challenge_ring_element::<SIMDUnit, Shake256, 39, 32>(seed).to_i32_array(),
expected_coefficients
);

Expand All @@ -707,7 +708,7 @@ mod tests {
];

assert_eq!(
sample_challenge_ring_element::<SIMDUnit, Shake256, 49>(seed).to_i32_array(),
sample_challenge_ring_element::<SIMDUnit, Shake256, 49, 32>(seed).to_i32_array(),
expected_coefficients
);

Expand All @@ -731,7 +732,7 @@ mod tests {
];

assert_eq!(
sample_challenge_ring_element::<SIMDUnit, Shake256, 60>(seed).to_i32_array(),
sample_challenge_ring_element::<SIMDUnit, Shake256, 60, 32>(seed).to_i32_array(),
expected_coefficients
);
}
Expand Down
15 changes: 0 additions & 15 deletions libcrux-ml-dsa/src/simd/avx2/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,6 @@ pub fn subtract(lhs: Vec256, rhs: Vec256) -> Vec256 {
mm256_sub_epi32(lhs, rhs)
}

// Multiply two vectors of 32-bit integers and return two vectors containing
// the high 32 bits of each of the pairwise products.
fn simd_multiply_i32_and_return_high(lhs: Vec256, rhs: Vec256) -> Vec256 {
let prod02 = mm256_mul_epi32(lhs, rhs);
let prod13 = mm256_mul_epi32(
mm256_shuffle_epi32::<0b11_11_01_01>(lhs),
mm256_shuffle_epi32::<0b11_11_01_01>(rhs),
);

mm256_unpackhi_epi64(
mm256_unpacklo_epi32(prod02, prod13),
mm256_unpackhi_epi32(prod02, prod13),
)
}

#[inline(always)]
pub fn montgomery_multiply_by_constant(lhs: Vec256, constant: i32) -> Vec256 {
let rhs = mm256_set1_epi32(constant);
Expand Down
4 changes: 2 additions & 2 deletions libcrux-ml-dsa/tests/kats/dilithium.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ def sign(self, sk_bytes, m, rnd=None):
# Create challenge polynomial
w1_bytes = w1.bit_pack_w(self.gamma_2)
c_tilde = self._h(mu + w1_bytes, self.ctildebytes)
c = self._sample_in_ball(c_tilde[:32]) # SEEDBYTES
c = self._sample_in_ball(c_tilde) # SEEDBYTES

# Store c in NTT form
c.to_ntt()
Expand Down Expand Up @@ -539,7 +539,7 @@ def verify(self, pk_bytes, m, sig_bytes):

tr = self._h(pk_bytes, 64) # TRBYTES
mu = self._h(tr + m, 64)
c = self._sample_in_ball(c_tilde[:32])
c = self._sample_in_ball(c_tilde)

# Convert to NTT for computation
c.to_ntt()
Expand Down
Loading

0 comments on commit f8a7d13

Please sign in to comment.