Skip to main content

rsa/algorithms/
pad.rs

1//! Special handling for converting the BigUint to u8 vectors
2
3use alloc::vec::Vec;
4use crypto_bigint::BoxedUint;
5use zeroize::Zeroizing;
6
7use crate::errors::{Error, Result};
8
9/// Returns a new vector of the given length, with 0s left padded.
10#[inline]
11fn left_pad(input: &[u8], padded_len: usize) -> Result<Vec<u8>> {
12    if input.len() > padded_len {
13        return Err(Error::InvalidPadLen);
14    }
15
16    let mut out = vec![0u8; padded_len];
17    out[padded_len - input.len()..].copy_from_slice(input);
18    Ok(out)
19}
20
21/// Converts input to the new vector of the given length, using BE and with 0s left padded.
22/// In some cases BoxedUint might already have leading zeroes, this function removes them
23/// before padding again.
24#[inline]
25pub(crate) fn uint_to_be_pad(input: BoxedUint, padded_len: usize) -> Result<Vec<u8>> {
26    let leading_zeros = input.leading_zeros() as usize / 8;
27    left_pad(&input.to_be_bytes()[leading_zeros..], padded_len)
28}
29
30/// Converts input to the new vector of the given length, using BE and with 0s left padded.
31/// In some cases BoxedUint might already have leading zeroes, this function removes them
32/// before padding again.
33#[inline]
34pub(crate) fn uint_to_zeroizing_be_pad(input: BoxedUint, padded_len: usize) -> Result<Vec<u8>> {
35    let leading_zeros = input.leading_zeros() as usize / 8;
36
37    let m = Zeroizing::new(input);
38    let m = Zeroizing::new(m.to_be_bytes());
39
40    left_pad(&m[leading_zeros..], padded_len)
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    #[test]
47    fn test_left_pad() {
48        const INPUT_LEN: usize = 3;
49        let input = vec![0u8; INPUT_LEN];
50
51        // input len < padded len
52        let padded = left_pad(&input, INPUT_LEN + 1).unwrap();
53        assert_eq!(padded.len(), INPUT_LEN + 1);
54
55        // input len == padded len
56        let padded = left_pad(&input, INPUT_LEN).unwrap();
57        assert_eq!(padded.len(), INPUT_LEN);
58
59        // input len > padded len
60        let padded = left_pad(&input, INPUT_LEN - 1);
61        assert!(padded.is_err());
62    }
63}