Trait rsa_cortex_m4::numbers::Number[][src]

pub unsafe trait Number: Deref<Target = [Digit]> + Clone + Debug + Default {
    const BITS: usize;
    const DIGITS: usize;
    fn significant_digits(&self) -> &[Digit] { ... }
fn leading_digit(&self) -> Option<Digit> { ... }
fn to_unsigned<const D: usize, const E: usize>(
        &self
    ) -> Result<Unsigned<D, E>> { ... }
fn zero() -> Self { ... }
fn is_zero(&self) -> bool { ... }
fn is_one(&self) -> bool { ... }
fn is_digit(&self) -> bool { ... }
fn is_odd(&self) -> bool { ... }
fn cmp(&self, other: &impl Number) -> Ordering { ... }
fn eq(&self, other: &impl Number) -> bool { ... }
fn deref(&self) -> &[Digit] { ... }
fn deref_mut(&mut self) -> &mut Self::Target { ... } }

Something similar to a Vec<u32>, without allocations.

The dereferenced slice is treated as little-endian digits of a big unsigned integer; this slice must be of length Self::DIGITS.

There is no need to "extend" the allocation as in, say, heapless. Simply write to the desired index / slice (via DerefMut).

In a previous version of this trait, only the significant digits (up until the leading digit) were dereferenced. To meet constant-time requirements, this was changed.

Current implementations are (with const generic usize parameters):

Of actual interest are Long (=Unsigned<D, D>) and Short (=Unsigned<D, 0>) numbers, where "Short" is tongue-in-cheek.

A lot of this dance could be skipped if only sums of const generic usizes were considered const (which they are not in Rust 1.51's min_const_generics.

All we really want is to have two "Short" primes $P, Q$, and their "Long" product $N = PQ$.

Implementing this trait

The type should consist of non-trivial consecutive Digit "plain old data", and be Clone + Debug + Default.

Then the following is all that is needed:

impl Deref for T {
  type Target = [Digit];
  fn deref(&self) -> &Self::Target {
    Number::deref(self)
  }
}
impl DerefMut for T {
  fn deref_mut(&mut self) -> &mut Self::Target {
    Number::deref_mut(self)
  }
}
unsafe impl Number for T {}
impl NumberMut for T {}

Associated Constants

const BITS: usize[src]

The number of bits that fit in this number.

const DIGITS: usize[src]

The number of digits that fit in this number.

There are compile-time checks that alignment and size of implementing types are compatible (i.e., multiples) with those of the digit type. If not, there are error messages of the form attempt to compute `0_usize - 1_usize`, which would overflow.

Loading content...

Provided methods

fn significant_digits(&self) -> &[Digit][src]

The significant digits of the number (little-endian).

fn leading_digit(&self) -> Option<Digit>[src]

The last non-zero digit of the number.

fn to_unsigned<const D: usize, const E: usize>(&self) -> Result<Unsigned<D, E>>[src]

Embed in number with D + E digits, if possible.

Not expressable as TryInto, as it would clash with blanket implementations, e.g. for Unsigned with D = X.

fn zero() -> Self[src]

fn is_zero(&self) -> bool[src]

fn is_one(&self) -> bool[src]

fn is_digit(&self) -> bool[src]

fn is_odd(&self) -> bool[src]

fn cmp(&self, other: &impl Number) -> Ordering[src]

This is little endian ordering, as opposed to the default ordering on arrays and slices!

In other words, we start comparing at the leading digits.

fn eq(&self, other: &impl Number) -> bool[src]

fn deref(&self) -> &[Digit][src]

fn deref_mut(&mut self) -> &mut Self::Target[src]

Loading content...

Implementors

impl<T: Number> Number for Wrapping<T>[src]

impl<const D: usize, const E: usize> Number for Unsigned<D, E>[src]

impl<const D: usize, const E: usize, const L: usize> Number for Array<D, E, L>[src]

Loading content...