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