fixed poly
This commit is contained in:
parent
d494db5216
commit
a4ac68528c
141
src/math/ecc.rs
141
src/math/ecc.rs
|
@ -1,8 +1,10 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
/// eliptic curve cryptography
|
use std::{ops::{Mul, Neg}, fmt::Debug};
|
||||||
|
|
||||||
|
/// eliptic curve cryptograp.s
|
||||||
///
|
///
|
||||||
/// This module implements structs and functionalities used for eliptic curve cryptography (ECC).
|
/// This module implements structs and functionalities used for eliptic curve cryptograp.s (ECC).
|
||||||
/// Do not expect it to actually be secure, I made this for cryptography lectures.
|
/// Do not expect it to actually be secure, I made this for cryptograp.s lectures.
|
||||||
///
|
///
|
||||||
/// Author: Christoph J. Scherr <software@cscherr.de>
|
/// Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
/// License: MIT
|
/// License: MIT
|
||||||
|
@ -10,19 +12,11 @@
|
||||||
|
|
||||||
use super::gallois::GalloisField;
|
use super::gallois::GalloisField;
|
||||||
|
|
||||||
|
use num::Integer;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
/// This is a very special math point, it does not really exist but is useful.
|
|
||||||
pub const INFINITY_POINT: ElipticCurvePoint = ElipticCurvePoint {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
is_infinity_point: true,
|
|
||||||
verbose: false
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[pyclass]
|
|
||||||
/// represent a specific eliptic curve
|
/// represent a specific eliptic curve
|
||||||
///
|
///
|
||||||
/// real curves not supported, only in Gallois Fields
|
/// real curves not supported, only in Gallois Fields
|
||||||
|
@ -32,36 +26,56 @@ pub struct ElipticCurve {
|
||||||
b: i128,
|
b: i128,
|
||||||
points: Vec<ElipticCurvePoint>,
|
points: Vec<ElipticCurvePoint>,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
INFINITY_POINT: ElipticCurvePoint,
|
INFINITY_POINT: Option<ElipticCurvePoint>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElipticCurve {
|
impl ElipticCurve {
|
||||||
pub fn new(f: GalloisField, a: i128, b: i128, verbose: bool) -> Self {
|
pub fn new(f: GalloisField, a: i128, b: i128, verbose: bool) -> Self {
|
||||||
let e = ElipticCurve {
|
let mut e = ElipticCurve {
|
||||||
f,
|
f,
|
||||||
a,
|
a,
|
||||||
b,
|
b,
|
||||||
points: Vec::new(),
|
points: Vec::new(),
|
||||||
verbose,
|
verbose,
|
||||||
INFINITY_POINT
|
INFINITY_POINT: None
|
||||||
};
|
};
|
||||||
|
let infty = ElipticCurvePoint::new(0, 0, e.f);
|
||||||
|
e.INFINITY_POINT = Some(infty);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// calculate a point for coordinates
|
/// calculate a value for coordinates
|
||||||
pub fn poly(&self, x: i128, y: i128) -> i128 {
|
pub fn poly<T>(&self, r: T, s: T) -> i128
|
||||||
return y.pow(2) - x.pow(3) - (self.a * x) - self.b;
|
where
|
||||||
|
T: Integer,
|
||||||
|
T: Mul,
|
||||||
|
T: Debug,
|
||||||
|
T: num::cast::AsPrimitive<i128>,
|
||||||
|
T: Neg
|
||||||
|
{
|
||||||
|
dbg!(&r);
|
||||||
|
dbg!(&s);
|
||||||
|
let r: i128 = num::cast::AsPrimitive::as_(r);
|
||||||
|
let s: i128 = num::cast::AsPrimitive::as_(s);
|
||||||
|
let res = s.pow(2) - r.pow(3) - (self.a * r) - self.b;
|
||||||
|
let res1 = self.f.reduce(res);
|
||||||
|
if self.verbose {
|
||||||
|
println!("F({}, {}) = {}² - {}³ - {} * {} - {} = {res} = {res1}",
|
||||||
|
r, s, s, r, self.a, r, self.b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res1 as i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_point(self, p: ElipticCurvePoint) -> bool {
|
pub fn check_point(self, p: ElipticCurvePoint) -> bool {
|
||||||
let mut valid = true;
|
let mut valid = true;
|
||||||
let r = self.f.reduce(self.poly(p.x, p.y));
|
let res = self.f.reduce(self.poly(p.r, p.s));
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("F({}, {}) = {}² - {}³ - {} * {} - {} = {r}",
|
println!("F({}, {}) = {}² - {}³ - {} * {} - {} = {res}",
|
||||||
p.x, p.y, p.y, p.x, self.a, p.x, self.b
|
p.r, p.s, p.s, p.r, self.a, p.r, self.b
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
valid &= r == 0;
|
valid &= res == 0;
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,15 +86,15 @@ fn test_check_point() {
|
||||||
let ec = ElipticCurve::new(f, 1, 679, true);
|
let ec = ElipticCurve::new(f, 1, 679, true);
|
||||||
// real points
|
// real points
|
||||||
let p = vec![
|
let p = vec![
|
||||||
ElipticCurvePoint::new(298, 531),
|
ElipticCurvePoint::new(298, 531, f),
|
||||||
ElipticCurvePoint::new(600, 127),
|
ElipticCurvePoint::new(600, 127, f),
|
||||||
ElipticCurvePoint::new(846, 176),
|
ElipticCurvePoint::new(846, 176, f),
|
||||||
];
|
];
|
||||||
// random values, not part of the ec.
|
// random values, not part of the e, fc.
|
||||||
let np = vec![
|
let np = vec![
|
||||||
ElipticCurvePoint::new(198, 331),
|
ElipticCurvePoint::new(198, 331, f),
|
||||||
ElipticCurvePoint::new(100, 927),
|
ElipticCurvePoint::new(100, 927, f),
|
||||||
ElipticCurvePoint::new(446, 876),
|
ElipticCurvePoint::new(446, 876, f),
|
||||||
];
|
];
|
||||||
for i in p {
|
for i in p {
|
||||||
dbg!(&i);
|
dbg!(&i);
|
||||||
|
@ -94,43 +108,72 @@ fn test_check_point() {
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[pyclass]
|
|
||||||
/// represent a specific eliptic curves point
|
/// represent a specific eliptic curves point
|
||||||
pub struct ElipticCurvePoint {
|
pub struct ElipticCurvePoint {
|
||||||
x: i128,
|
r: i128,
|
||||||
y: i128,
|
s: i128,
|
||||||
is_infinity_point: bool,
|
is_infinity_point: bool,
|
||||||
verbose: bool
|
field: GalloisField
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElipticCurvePoint {
|
impl ElipticCurvePoint {
|
||||||
pub fn new(x: i128, y: i128) -> Self {
|
pub fn new(r: i128, s: i128, field: GalloisField) -> ElipticCurvePoint {
|
||||||
ElipticCurvePoint {
|
ElipticCurvePoint {
|
||||||
x,
|
r,
|
||||||
y,
|
s,
|
||||||
is_infinity_point: false,
|
is_infinity_point: false,
|
||||||
verbose: false
|
field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_infinity_point() -> Self {
|
|
||||||
return INFINITY_POINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// add two points
|
/// add two points
|
||||||
pub fn add(a: Self, b: Self) -> Self {
|
pub fn add(self, point: Self) -> Result<Self, String> {
|
||||||
// TODO
|
if self.field.cha != point.field.cha {
|
||||||
panic!("TODO");
|
return Err(String::from("Points are not on the same field"));
|
||||||
|
}
|
||||||
|
if self.field.prime_base {
|
||||||
|
// case 1 both infty
|
||||||
|
if self.is_infinity_point && point.is_infinity_point {
|
||||||
|
return Ok(point);
|
||||||
|
}
|
||||||
|
// case 2 one is infty
|
||||||
|
else if self.is_infinity_point && !point.is_infinity_point {
|
||||||
|
return Ok(point);
|
||||||
|
}
|
||||||
|
else if !self.is_infinity_point && point.is_infinity_point {
|
||||||
|
return Ok(self);
|
||||||
|
}
|
||||||
|
// case 3 r_1 != r_2
|
||||||
|
else if self.r != point.r {
|
||||||
|
panic!("TODO");
|
||||||
|
}
|
||||||
|
// case 4 r_1 = r_2; s_1 = -s_2
|
||||||
|
else if self.r == point.r && self.s == point.neg().s {
|
||||||
|
return Ok(Self::new(0, 0, self.field));
|
||||||
|
}
|
||||||
|
|
||||||
|
// how do we get here?
|
||||||
|
// this should never occur
|
||||||
|
else {
|
||||||
|
panic!("we dont know what to do in this case?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Err(String::from("Only prime fields are supported currently"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get negative of a point
|
/// get negative of a point
|
||||||
pub fn neg(p: Self) -> Self {
|
pub fn neg(self) -> Self {
|
||||||
// TODO
|
return ElipticCurvePoint::new(
|
||||||
panic!("TODO");
|
self.r,
|
||||||
|
self.field.reduce(-(self.s as i128)) as i128,
|
||||||
|
self.field
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// multiply a point by an integer
|
/// multip.s a point by an integer
|
||||||
pub fn mul(n: u128, a: Self) -> Self {
|
pub fn mul(self, n: u128) -> Self {
|
||||||
// TODO
|
// TODO
|
||||||
panic!("TODO");
|
panic!("TODO");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue