Skip to content

fix(precompile): use big-endian resize for modexp output padding#3432

Merged
rakita merged 3 commits intobluealloy:mainfrom
Wollac:modexp-resize-be
Feb 23, 2026
Merged

fix(precompile): use big-endian resize for modexp output padding#3432
rakita merged 3 commits intobluealloy:mainfrom
Wollac:modexp-resize-be

Conversation

@Wollac
Copy link
Copy Markdown
Contributor

@Wollac Wollac commented Feb 20, 2026

Summary

  • Replace left_pad_vec with a new resize_be utility for modexp output normalization.
  • left_pad_vec incorrectly truncates trailing (least-significant) bytes when the output exceeds mod_len. This is incorrect for big-endian values.
  • The new resize_be utility correctly handles both padding (left-pad with zeroes) and truncation (drop leading bytes).
  • Avoid an extra allocation by resizing the output vector in place instead of creating a new one.

Motivation

crypto().modexp() is a trait method that can be overridden, so the output may exceed mod_len bytes and contain leading zeroes. The previous code silently corrupted results in that case by truncating from the wrong side.resize_be only assumes the mathematical invariant that the output value is < modulus, not any specific byte length.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 20, 2026

Merging this PR will improve performance by 3.62%

⚡ 1 improved benchmark
✅ 175 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
blake2/2_rounds 3.3 µs 3.2 µs +3.62%

Comparing Wollac:modexp-resize-be (ac1ab76) with main (026017c)

Open in CodSpeed

Copy link
Copy Markdown
Member

@rakita rakita left a comment

Choose a reason for hiding this comment

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

I see, this only can happen if crypto().modexp returns some badly formated data.

for style lets create left_pad_vec_be that would do a similar thing to left_pad_vec

Address review feedback to match the existing left_pad_vec naming
convention. Also change the API to take &[u8] and return Cow<[u8]>
instead of mutating a Vec in place.
@rakita
Copy link
Copy Markdown
Member

rakita commented Feb 23, 2026

@Wollac can you check if changes are okay. And will merge afterwards

@Wollac
Copy link
Copy Markdown
Contributor Author

Wollac commented Feb 23, 2026

Yes, this fixes the issue I observed.
One tradeoff worth noting: Due to the Cows it'll most likely lead to an additional Vec allocation even for the most common case where output already has the perfect length. The original resize_be approach tried to avoid this by modifying the vec in place.

@rakita
Copy link
Copy Markdown
Member

rakita commented Feb 23, 2026

@Wollac i see, will check this in saparate PR. Will merge this as we will be releasing new version soon(tm)

@rakita rakita merged commit 39564c9 into bluealloy:main Feb 23, 2026
31 checks passed
@github-actions github-actions bot mentioned this pull request Feb 23, 2026
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