RustCrypto / RustCrypto/formats
Relax `Encoding::encode_string`'s limit to `usize::MAX/4 * 3`?
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 338
- Forks
- 188
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 15
Description
base64 uses the following logic:
/// Calculate the base64 encoded length for a given input length, optionally including any
/// appropriate padding bytes.
///
/// Returns `None` if the encoded length can't be represented in `usize`. This will happen for
/// input lengths in approximately the top quarter of the range of `usize`.
pub const fn encoded_len(bytes_len: usize, padding: bool) -> Option<usize> {
let rem = bytes_len % 3;
let complete_input_chunks = bytes_len / 3;
// `?` is disallowed in const, and `let Some(_) = _ else` requires 1.65.0, whereas this
// messier syntax works on 1.48
let complete_chunk_output =
if let Some(complete_chunk_output) = complete_input_chunks.checked_mul(4) {
complete_chunk_output
} else {
return None;
};
if rem > 0 {
if padding {
complete_chunk_output.checked_add(4)
} else {
let encoded_rem = match rem {
1 => 2,
// only other possible remainder is 2
// can't use a separate _ => unreachable!() in const fns in ancient rust versions
_ => 3,
};
complete_chunk_output.checked_add(encoded_rem)
}
} else {
Some(complete_chunk_output)
}
While base64ct does checked_mul at the beginning:
const fn encoded_len_inner(n: usize, padded: bool) -> Option<usize> {
match n.checked_mul(4) {
Some(q) => {
if padded {
Some(((q / 3) + 3) & !3)
} else {
Some((q / 3) + (q % 3 != 0) as usize)
}
}
None => None,
}
}
Since the Base64 encoding takes generally 4/3 length of the input, is it possible to relax the Encoding::encode_string's limit by reworking calculations?
cc @tarcieri
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at Encoding::encode_string and compare its length calculations with base64's encoded_len and base64ct's encoded_len_inner. Determine whether the checked arithmetic can safely support the proposed limit while preserving overflow behavior; done means the encoding accepts the larger valid range without producing unrepresentable lengths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cryptography
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100