ring/rsa/
public_exponent.rs
1use crate::error;
2use crate::polyfill::{unwrap_const, ArrayFlatMap, LeadingZerosStripped};
3use core::num::NonZeroU64;
4
5#[derive(Clone, Copy)]
7pub struct PublicExponent(NonZeroU64);
8
9impl PublicExponent {
10 #[cfg(test)]
11 const ALL_CONSTANTS: [Self; 3] = [Self::_3, Self::_65537, Self::MAX];
12
13 pub(super) const _3: Self = Self(unwrap_const(NonZeroU64::new(3)));
14 pub(super) const _65537: Self = Self(unwrap_const(NonZeroU64::new(65537)));
15
16 const MAX: Self = Self(unwrap_const(NonZeroU64::new((1u64 << 33) - 1)));
28
29 pub(super) fn from_be_bytes(
30 input: untrusted::Input,
31 min_value: Self,
32 ) -> Result<Self, error::KeyRejected> {
33 if input.len() > 5 {
37 return Err(error::KeyRejected::too_large());
38 }
39 let value = input.read_all(error::KeyRejected::invalid_encoding(), |input| {
40 if input.peek(0) {
43 return Err(error::KeyRejected::invalid_encoding());
44 }
45 let mut value = 0u64;
46 loop {
47 let byte = input
48 .read_byte()
49 .map_err(|untrusted::EndOfInput| error::KeyRejected::invalid_encoding())?;
50 value = (value << 8) | u64::from(byte);
51 if input.at_end() {
52 return Ok(value);
53 }
54 }
55 })?;
56
57 let value = NonZeroU64::new(value).ok_or_else(error::KeyRejected::too_small)?;
62 if value < min_value.0 {
63 return Err(error::KeyRejected::too_small());
64 }
65 if value > Self::MAX.0 {
66 return Err(error::KeyRejected::too_large());
67 }
68
69 if value.get() & 1 != 1 {
71 return Err(error::KeyRejected::invalid_component());
72 }
73
74 Ok(Self(value))
75 }
76
77 pub fn be_bytes(&self) -> impl ExactSizeIterator<Item = u8> + Clone + '_ {
81 let bytes = ArrayFlatMap::new(core::iter::once(self.0.get()), u64::to_be_bytes).unwrap();
83 LeadingZerosStripped::new(bytes)
84 }
85
86 pub(super) fn value(self) -> NonZeroU64 {
87 self.0
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test_public_exponent_constants() {
97 for value in PublicExponent::ALL_CONSTANTS.iter() {
98 let value: u64 = value.0.into();
99 assert_eq!(value & 1, 1);
100 assert!(value >= PublicExponent::_3.0.into()); assert!(value <= PublicExponent::MAX.0.into());
102 }
103 }
104}