//! Multi Precision Integers.
use std::fmt;
use std::io::Write;
use std::cmp::Ordering;
use quickcheck::{Arbitrary, Gen};
use rand::Rng;
use constants::{
Curve,
HashAlgorithm,
PublicKeyAlgorithm,
SymmetricAlgorithm,
};
use crypto::Hash;
use crypto::mem::secure_cmp;
use serialize::Serialize;
use nettle;
/// Holds a single MPI.
#[derive(Clone, Hash)]
pub struct MPI {
/// Length of the integer in bits.
bits: usize,
/// Integer value as big-endian.
value: Box<[u8]>,
}
impl From<Vec<u8>> for MPI {
fn from(v: Vec<u8>) -> Self {
Self::new(&v)
}
}
impl MPI {
/// Creates a new MPI.
///
/// This function takes care of leading zeros.
pub fn new(value: &[u8]) -> Self {
let mut leading_zeros = 0;
for b in value {
leading_zeros += b.leading_zeros() as usize;
if *b != 0 {
break;
}
}
let offset = leading_zeros / 8;
let value = Vec::from(&value[offset..]).into_boxed_slice();
MPI {
bits: value.len() * 8 - leading_zeros % 8,
value: value,
}
}
/// Creates new MPI for EC point.
pub fn new_weierstrass(x: &[u8], y: &[u8], field_bits: usize) -> Self {
let field_sz = if field_bits % 8 > 0 { 1 } else {