ring/arithmetic/bigint/
modulusvalue.rs1use super::{
16 super::{MAX_LIMBS, MIN_LIMBS},
17 BoxedLimbs, Modulus, PublicModulus,
18};
19use crate::{
20 bits::BitLength,
21 error,
22 limb::{self, Limb, LIMB_BYTES},
23};
24
25pub(crate) struct OwnedModulusValue<M> {
27 limbs: BoxedLimbs<M>, len_bits: BitLength,
30}
31
32impl<M: PublicModulus> Clone for OwnedModulusValue<M> {
33 fn clone(&self) -> Self {
34 Self {
35 limbs: self.limbs.clone(),
36 len_bits: self.len_bits,
37 }
38 }
39}
40
41impl<M> OwnedModulusValue<M> {
42 pub(crate) fn from_be_bytes(input: untrusted::Input) -> Result<Self, error::KeyRejected> {
43 let num_limbs = (input.len() + LIMB_BYTES - 1) / LIMB_BYTES;
44 const _MODULUS_MIN_LIMBS_AT_LEAST_2: () = assert!(MIN_LIMBS >= 2);
45 if num_limbs < MIN_LIMBS {
46 return Err(error::KeyRejected::unexpected_error());
47 }
48 if num_limbs > MAX_LIMBS {
49 return Err(error::KeyRejected::too_large());
50 }
51 if untrusted::Reader::new(input).peek(0) {
56 return Err(error::KeyRejected::invalid_encoding());
57 }
58
59 let mut limbs = BoxedLimbs::zero(num_limbs);
60 limb::parse_big_endian_and_pad_consttime(input, &mut limbs)
61 .map_err(|error::Unspecified| error::KeyRejected::unexpected_error())?;
62 limb::limbs_reject_even_leak_bit(&limbs)
63 .map_err(|_: error::Unspecified| error::KeyRejected::invalid_component())?;
64
65 let len_bits = limb::limbs_minimal_bits(&limbs);
66
67 Ok(Self { limbs, len_bits })
68 }
69
70 pub fn verify_less_than<L>(&self, l: &Modulus<L>) -> Result<(), error::Unspecified> {
71 if self.len_bits() > l.len_bits() {
72 return Err(error::Unspecified);
73 }
74 if self.limbs.len() == l.limbs().len() {
75 limb::verify_limbs_less_than_limbs_leak_bit(&self.limbs, l.limbs())?;
76 }
77 Ok(())
78 }
79
80 pub fn len_bits(&self) -> BitLength {
81 self.len_bits
82 }
83
84 #[inline]
85 pub(super) fn limbs(&self) -> &[Limb] {
86 &self.limbs
87 }
88}