ring/rsa/
public_modulus.rs
1use crate::{
2 arithmetic::{bigint, montgomery::RR},
3 bits::{self, FromByteLen as _},
4 cpu,
5 error::{self, InputTooLongError},
6 rsa::N,
7};
8use core::ops::RangeInclusive;
9
10pub struct PublicModulus {
12 value: bigint::OwnedModulus<N>,
13 oneRR: bigint::One<N, RR>,
14}
15
16impl Clone for PublicModulus {
17 fn clone(&self) -> Self {
18 let PublicModulus { value, oneRR } = self;
19 let value = value.clone();
20
21 let cpu = cpu::features();
24 let n = value.modulus(cpu);
25 let oneRR = oneRR.clone_into(n.alloc_zero());
26
27 Self { value, oneRR }
28 }
29}
30
31impl PublicModulus {
39 pub(super) fn from_be_bytes(
40 n: untrusted::Input,
41 allowed_bit_lengths: RangeInclusive<bits::BitLength>,
42 cpu_features: cpu::Features,
43 ) -> Result<Self, error::KeyRejected> {
44 let min_bits = *allowed_bit_lengths.start();
48 let max_bits = *allowed_bit_lengths.end();
49
50 const MIN_BITS: bits::BitLength = bits::BitLength::from_bits(1024);
54
55 let value = bigint::OwnedModulusValue::from_be_bytes(n)?;
57 let bits = value.len_bits();
58
59 assert!(min_bits >= MIN_BITS);
63 let bits_rounded_up = bits::BitLength::from_byte_len(bits.as_usize_bytes_rounded_up())
64 .map_err(error::erase::<InputTooLongError>)
65 .unwrap(); if bits_rounded_up < min_bits {
67 return Err(error::KeyRejected::too_small());
68 }
69 if bits > max_bits {
70 return Err(error::KeyRejected::too_large());
71 }
72 let value = bigint::OwnedModulus::from(value);
73 let m = value.modulus(cpu_features);
74 let oneRR = bigint::One::newRR(m.alloc_zero(), &m);
75
76 Ok(Self { value, oneRR })
77 }
78
79 pub fn be_bytes(&self) -> impl ExactSizeIterator<Item = u8> + Clone + '_ {
83 self.value.be_bytes()
84 }
85
86 pub fn len_bits(&self) -> bits::BitLength {
88 self.value.len_bits()
89 }
90
91 pub(super) fn value(&self, cpu_features: cpu::Features) -> bigint::Modulus<N> {
92 self.value.modulus(cpu_features)
93 }
94
95 pub(super) fn oneRR(&self) -> &bigint::Elem<N, RR> {
96 self.oneRR.as_ref()
97 }
98}