1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Add field::get_required_bits

This commit is contained in:
Dennis Kuhnert 2017-02-26 12:02:39 +01:00
parent 0793d8b4eb
commit 83c7ce2f21

View file

@ -3,10 +3,8 @@
// @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
// @date 2017
extern crate num;
use self::num::{Integer, Zero, One};
use self::num::bigint::{BigInt, ToBigInt};
use num::{Integer, Zero, One};
use num::bigint::{BigInt, ToBigInt};
use std::convert::From;
use std::ops::{Add, Sub, Mul, Div};
use std::fmt;
@ -16,26 +14,6 @@ lazy_static! {
static ref P: BigInt = BigInt::parse_bytes(b"21888242871839275222246405745257275088696311157297823662689037894645226208583", 10).unwrap();
}
/// Calculates the gcd using a iterative implementation of the extended euclidian algorithm.
fn extended_euclid(a: &BigInt, b: &BigInt) -> (BigInt, BigInt, BigInt) {
let (mut s, mut old_s) = (BigInt::zero(), BigInt::one());
let (mut t, mut old_t) = (BigInt::one(), BigInt::zero());
let (mut r, mut old_r) = (b.clone(), a.clone());
while !&r.is_zero() {
let quotient = &old_r / &r;
let tmp_r = old_r.clone();
old_r = r.clone();
r = &tmp_r - &quotient * &r;
let tmp_s = old_s.clone();
old_s = s.clone();
s = &tmp_s - &quotient * &s;
let tmp_t = old_t.clone();
old_t = t.clone();
t = &tmp_t - &quotient * &t;
}
return (old_r, old_s, old_t)
}
pub trait Pow<RHS> {
type Output;
fn pow(self, RHS) -> Self::Output;
@ -57,6 +35,8 @@ pub trait Field : From<i32> + From<u32> + From<usize> + for<'a> From<&'a str>
fn min_value() -> Self;
/// Returns the largest value that can be represented by this field type.
fn max_value() -> Self;
/// Returns the number of required bits to represent this field type.
fn get_required_bits() -> usize;
}
#[derive(PartialEq,PartialOrd,Clone)]
@ -80,6 +60,9 @@ impl Field for FieldPrime {
fn max_value() -> FieldPrime {
FieldPrime{ value: &*P - ToBigInt::to_bigint(&1).unwrap() }
}
fn get_required_bits() -> usize {
(*P).bits()
}
}
impl Display for FieldPrime {
@ -250,6 +233,31 @@ impl<'a> Pow<&'a FieldPrime> for FieldPrime {
}
}
/// Calculates the gcd using a iterative implementation of the extended euclidian algorithm.
/// Returning `(d, s, t)` so that `d = s * a + t * b`
///
/// # Arguments
/// * `a` - First number as `BigInt`
/// * `b` - Second number as `BigInt`
fn extended_euclid(a: &BigInt, b: &BigInt) -> (BigInt, BigInt, BigInt) {
let (mut s, mut old_s) = (BigInt::zero(), BigInt::one());
let (mut t, mut old_t) = (BigInt::one(), BigInt::zero());
let (mut r, mut old_r) = (b.clone(), a.clone());
while !&r.is_zero() {
let quotient = &old_r / &r;
let tmp_r = old_r.clone();
old_r = r.clone();
r = &tmp_r - &quotient * &r;
let tmp_s = old_s.clone();
old_s = s.clone();
s = &tmp_s - &quotient * &s;
let tmp_t = old_t.clone();
old_t = t.clone();
t = &tmp_t - &quotient * &t;
}
return (old_r, old_s, old_t)
}
#[cfg(test)]
mod tests {
use super::*;