mirror of
https://github.com/mii443/encrypt.git
synced 2025-08-22 15:05:33 +00:00
fix pow
This commit is contained in:
@ -1,48 +1,40 @@
|
||||
use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Rem}, fmt::Debug};
|
||||
|
||||
use primitive_types::U512;
|
||||
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
pub struct FiniteFieldElement<T>
|
||||
where
|
||||
T: PartialEq + Copy
|
||||
{
|
||||
pub value: T,
|
||||
pub p: T,
|
||||
pub one: T
|
||||
pub struct FiniteFieldElement {
|
||||
pub value: U512,
|
||||
pub p: U512
|
||||
}
|
||||
|
||||
impl<T> FiniteFieldElement<T>
|
||||
where
|
||||
T: PartialEq + Copy
|
||||
{
|
||||
pub fn new(value: T, p: T, one: T) -> Self {
|
||||
Self { value, p, one }
|
||||
impl FiniteFieldElement {
|
||||
pub fn new(value: U512, p: U512) -> Self {
|
||||
Self { value, p }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FiniteFieldElement<T>
|
||||
where
|
||||
T: Rem<Output = T> + Add<Output = T> + Sub<Output = T> + Div<Output = T> + PartialEq + PartialOrd + Copy + Debug
|
||||
{
|
||||
fn pow(self, e: T) -> Self {
|
||||
let one = self.one;
|
||||
let two = one + one;
|
||||
let mut r = Self::new(one, self.p, self.one);
|
||||
let mut i = e;
|
||||
let zero = self.value - self.value;
|
||||
while i > zero {
|
||||
if i % two != zero {
|
||||
r = r * self;
|
||||
impl FiniteFieldElement {
|
||||
fn pow(self, e: U512) -> Self {
|
||||
let k = e.bits();
|
||||
let mut a1 = self.value;
|
||||
let mut a2 = self.value * self.value;
|
||||
let mut i = (k - 2) as i64;
|
||||
|
||||
while i >= 0 {
|
||||
if e.bit(i as usize) {
|
||||
a1 = (a1 * a2) % self.p;
|
||||
} else {
|
||||
a2 = (a1 * a2) % self.p;
|
||||
a1 = (a1 * a1) % self.p;
|
||||
}
|
||||
i = i / two;
|
||||
i -= 1;
|
||||
}
|
||||
r * self
|
||||
Self::new(a1, self.p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Add for FiniteFieldElement<T>
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
|
||||
{
|
||||
impl Add for FiniteFieldElement {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
@ -51,26 +43,20 @@ where
|
||||
}
|
||||
let sum = self.value + rhs.value;
|
||||
if sum >= self.p {
|
||||
Self::new(sum - self.p, self.p, self.one)
|
||||
Self::new(sum - self.p, self.p)
|
||||
} else {
|
||||
Self::new(sum, self.p, self.one)
|
||||
Self::new(sum, self.p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AddAssign for FiniteFieldElement<T>
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
|
||||
{
|
||||
impl AddAssign for FiniteFieldElement {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = (*self) + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Sub for FiniteFieldElement<T>
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
|
||||
{
|
||||
impl Sub for FiniteFieldElement {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
@ -78,58 +64,47 @@ where
|
||||
panic!("Cannot sub different field value.");
|
||||
}
|
||||
if self.value < rhs.value {
|
||||
Self::new(self.p - rhs.value + self.value , self.p, self.one)
|
||||
Self::new(self.p - rhs.value + self.value , self.p)
|
||||
} else {
|
||||
Self::new(self.value - rhs.value, self.p, self.one)
|
||||
Self::new(self.value - rhs.value, self.p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SubAssign for FiniteFieldElement<T>
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
|
||||
{
|
||||
impl SubAssign for FiniteFieldElement {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = (*self) - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Mul for FiniteFieldElement<T>
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + Div<Output = T> + Rem<Output = T> + PartialEq + PartialOrd + Copy + Debug
|
||||
{
|
||||
impl Mul for FiniteFieldElement {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
if self.p != rhs.p {
|
||||
panic!("Cannot mul different field value.");
|
||||
}
|
||||
let one = self.one;
|
||||
let two = one + one;
|
||||
let zero = self.value - self.value;
|
||||
let mut tmp = self;
|
||||
let mut i = rhs.value;
|
||||
let mut r = Self::new(zero, self.p, self.one);
|
||||
while i > zero {
|
||||
if i % two != zero {
|
||||
let mut r = Self::new(U512::from(0), self.p);
|
||||
while i > U512::from(0) {
|
||||
if i & U512::from(1) == U512::from(1) {
|
||||
r += tmp;
|
||||
}
|
||||
i = i / two;
|
||||
i = i >> 1;
|
||||
tmp = tmp + tmp;
|
||||
}
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Div for FiniteFieldElement<T>
|
||||
where
|
||||
T: Add<Output = T> + Sub<Output = T> + Rem<Output = T> + Div<Output = T> + PartialEq + PartialOrd + Copy + Debug
|
||||
{
|
||||
impl Div for FiniteFieldElement {
|
||||
type Output = Self;
|
||||
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
let one = self.one;
|
||||
self * rhs.pow(self.p - one - one)
|
||||
let rhs = rhs.pow(self.p - U512::from(2));
|
||||
println!("{:?} * {:?}", self, rhs);
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,40 +116,42 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn add() {
|
||||
let a = FiniteFieldElement::new(U512::from(2), U512::from(7), U512::from(1));
|
||||
let b = FiniteFieldElement::new(U512::from(1), U512::from(7), U512::from(1));
|
||||
let c = FiniteFieldElement::new(U512::from(3), U512::from(7), U512::from(1));
|
||||
let a = FiniteFieldElement::new(U512::from(2u8), U512::from(7u8));
|
||||
let b = FiniteFieldElement::new(U512::from(1u8), U512::from(7u8));
|
||||
let c = FiniteFieldElement::new(U512::from(3u8), U512::from(7u8));
|
||||
assert_eq!(a + b, c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub() {
|
||||
let a = FiniteFieldElement::new(U512::from(6), U512::from(7), U512::from(1));
|
||||
let b = FiniteFieldElement::new(U512::from(4), U512::from(7), U512::from(1));
|
||||
let c = FiniteFieldElement::new(U512::from(2), U512::from(7), U512::from(1));
|
||||
let a = FiniteFieldElement::new(U512::from(6u8), U512::from(7u8));
|
||||
let b = FiniteFieldElement::new(U512::from(4u8), U512::from(7u8));
|
||||
let c = FiniteFieldElement::new(U512::from(2u8), U512::from(7u8));
|
||||
assert_eq!(a - b, c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul() {
|
||||
let a = FiniteFieldElement::new(U512::from(3), U512::from(13), U512::from(1));
|
||||
let b = FiniteFieldElement::new(U512::from(12), U512::from(13), U512::from(1));
|
||||
let c = FiniteFieldElement::new(U512::from(10), U512::from(13), U512::from(1));
|
||||
let a = FiniteFieldElement::new(U512::from(3u8), U512::from(13u8));
|
||||
let b = FiniteFieldElement::new(U512::from(12u8), U512::from(13u8));
|
||||
let c = FiniteFieldElement::new(U512::from(10u8), U512::from(13u8));
|
||||
assert_eq!(a * b, c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pow() {
|
||||
let a = FiniteFieldElement::new(U512::from(3), U512::from(13), U512::from(1));
|
||||
let b = FiniteFieldElement::new(U512::from(1), U512::from(13), U512::from(1));
|
||||
let a = FiniteFieldElement::new(U512::from(3u8), U512::from(13u8));
|
||||
let b = FiniteFieldElement::new(U512::from(1u8), U512::from(13u8));
|
||||
assert_eq!(a.pow(U512::from(3)), b);
|
||||
|
||||
println!("{:?}", FiniteFieldElement::new(U512::from(5u8), U512::from(19u8)).pow(U512::from(17)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div() {
|
||||
let a = FiniteFieldElement::new(U512::from(7), U512::from(19), U512::from(1));
|
||||
let b = FiniteFieldElement::new(U512::from(5), U512::from(19), U512::from(1));
|
||||
let c = FiniteFieldElement::new(U512::from(9), U512::from(19), U512::from(1));
|
||||
let a = FiniteFieldElement::new(U512::from(7u8), U512::from(19u8));
|
||||
let b = FiniteFieldElement::new(U512::from(5u8), U512::from(19u8));
|
||||
let c = FiniteFieldElement::new(U512::from(9u8), U512::from(19u8));
|
||||
assert_eq!(a / b, c);
|
||||
}
|
||||
}
|
17
src/main.rs
17
src/main.rs
@ -3,7 +3,7 @@ use primitive_types::U512;
|
||||
// 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
||||
fn main() {
|
||||
println!("Encryption Library");
|
||||
/*
|
||||
|
||||
let p = U512::from_str_radix("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10).unwrap();
|
||||
|
||||
let secp256_k1_a = FiniteFieldElement::new(U512::from(0u8), p);
|
||||
@ -12,16 +12,15 @@ fn main() {
|
||||
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("32670510020758816978083085130507043184471273380659243275938904335757337482424", 10).unwrap(), p);
|
||||
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10).unwrap(), p);
|
||||
|
||||
*/
|
||||
/*
|
||||
let p = U512::from_str_radix("5", 10).unwrap();
|
||||
let one = U512::from(1u8);
|
||||
|
||||
let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p, one);
|
||||
let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p, one);
|
||||
let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p, one);
|
||||
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p, one);
|
||||
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p, one);
|
||||
|
||||
let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p);
|
||||
let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p);
|
||||
let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p);
|
||||
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p);
|
||||
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p);
|
||||
*/
|
||||
let ec = EllipticCurve {
|
||||
a: secp256_k1_a,
|
||||
b: secp256_k1_b
|
||||
|
Reference in New Issue
Block a user