Skip to content

Conversation

@Parrot7483
Copy link
Collaborator

@Parrot7483 Parrot7483 commented Sep 18, 2025

This PR adds full type checking for the SHA3 portable version for #395

Extract using hax.py extract --portable, prove using hax.py prove.

Besides prove code the following things where changed:

  • reorder functions in libcrux-sha3/src/generic_keccak/xof.rs
  • The absorb_full function in libcrux-sha3/src/generic_keccak/xof.rs previously did not always consume the internal buffer when it was full. This state could only be reached by misusing the API. The only bug I found.
  • split up the rho and pi function for verification purpose

This version contains a few things I would consider "hacks"

  • The extraction for the squeeze does not work. We add the expected F* code using hax_lib::fstar::replace
  • impl From<u32> for Algorithm does not work because of the panic.
  • In libcrux-sha3/src/generic_keccak/xof.rs the #[hax_lib::fstar::options("...")] has no effect. I use an hax_lib::fstar::before instead

@Parrot7483 Parrot7483 force-pushed the Parrot7483/sha3-type-check branch from 8f7a614 to 223bcaf Compare September 18, 2025 11:07
@Parrot7483 Parrot7483 marked this pull request as ready for review September 18, 2025 11:50
@Parrot7483 Parrot7483 requested review from a team as code owners September 18, 2025 11:50
Copy link
Member

@franziskuskiefer franziskuskiefer left a comment

Choose a reason for hiding this comment

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

Sorry for being a little slow on this.
Here a couple first comments. Can you address them and update? Then we can do another round.

self.buf_len + input_remainder_len <= RATE
);

hax_lib::assert!(input_remainder_len.to_int() + self.buf_len.to_int() <= RATE.to_int());
Copy link
Member

Choose a reason for hiding this comment

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

This requires the unconditional hax_lib dependency for debug builds. Is there a better way to do this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think I understand this correctly. Would putting a cfg(hax) be enough? It is only needed for proof.

@Parrot7483
Copy link
Collaborator Author

@franziskuskiefer I applied your feedback and also cherry-picked one commit from my AVX/NEON branch adding the correct precondition on the traits and doing some light refactoring (mainly having consistent names for variables).

Copy link
Member

@franziskuskiefer franziskuskiefer left a comment

Choose a reason for hiding this comment

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

Thanks, looks pretty good. A couple things and some cleanup, then this can go in.

Comment on lines 122 to 123
let value = get_ij(s, i / 5, i % 5);
let bytes = value.to_le_bytes();
Copy link
Member

Choose a reason for hiding this comment

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

Are these changes needed for the proof? If yes, they'd need some explanation to why. If not, we should keep it as is.
Same for the similar change below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, if I inline everything F* can't figure out that the bounds are correct every time. Sometimes it works sometimes it doesn't.

I think inlining let bytes = get_ij(s, octets / 5, octets % 5).to_le_bytes() should be possible.

)]
pub(crate) trait Squeeze1<T: KeccakItem<1>> {
#[hax_lib::attributes]
pub(crate) trait Squeeze<T: KeccakItem<1>> {
Copy link
Member

Choose a reason for hiding this comment

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

Why did this lose the 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I want to emphasize that having the Squeeze trait multiple times is because of HAX not supporting &[&mut [u8]; N] or other types with mutables inside. If that would work that would simplify a lot of things in this crate. I will write a comment explaining it.

@Parrot7483
Copy link
Collaborator Author

@franziskuskiefer I applied your review. cherry-picked 1064d0d from SIMD branch. Merged main.

@Parrot7483 Parrot7483 force-pushed the Parrot7483/sha3-type-check branch from fb88708 to 153b003 Compare November 19, 2025 15:12
@Parrot7483
Copy link
Collaborator Author

I have a tendency to pressing these big green buttons on github messing everything up. sorry.

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.

2 participants