This commit is contained in:
mii8080
2022-05-27 08:01:34 +00:00
committed by GitHub
parent 58a6e27743
commit e1c0dca87d
2 changed files with 65 additions and 89 deletions

View File

@ -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);
} }
} }

View File

@ -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