typo and pyi for ecc

This commit is contained in:
Christoph J. Scherr 2023-06-10 18:38:01 +02:00
parent 59a7e22e70
commit edf2f02d2a
Signed by: PlexSheep
GPG Key ID: 25B4ACF7D88186CC
5 changed files with 122 additions and 45 deletions

View File

@ -0,0 +1,66 @@
"""
Elliptic curve cryptography
___
@Author: Christoph J. Scherr <software@cscherr.de>
@License: MIT
@Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
"""
from src-py.plexcryptool.math.gallois import GalloisFiled
class EllipticCurve:
"""
an elliptic curve
"""
def __init__(self, field: GalloisFiled, a: int, b: int, verbose = True) -> None:
"""
constructor
"""
...
def new_point(self, r: int, s: int) -> EllipticCurvePoint:
"""
generate a new point in the curve
"""
...
def poly(self, x: int, y: int) -> int:
"""
insert into the curves polynomial
"""
...
def check_point(self, p: EllipticCurvePoint) -> bool:
"""
check if the point is valid
"""
...
def add(self, p1: EllipticCurvePoint, p2: EllipticCurvePoint) -> EllipticCurvePoint:
"""
add two points
"""
...
def mul(self, p: EllipticCurvePoint, t: int) -> EllipticCurvePoint:
"""
multiply a point by an integer
"""
...
def get_infinity_point(self) -> EllipticCurvePoint:
"""
get the infinity point of a curve
"""
...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
class EllipticCurvePoint:
"""
represent a point on some curve
"""

View File

@ -44,3 +44,9 @@ def int_to_bytearray(n: int, size: int|None = None, endianness = 'big') -> bytea
ba: bytearray = bytearray(1) + ba ba: bytearray = bytearray(1) + ba
return ba return ba
def ba_to_int(ba: bytearray) -> int:
"""
convert bytearray to int
"""
return int(ba.hex(), 16)

View File

@ -57,8 +57,8 @@ fn register_math_module(py: Python, parent_module: &PyModule) -> PyResult<()> {
math_module.add_function(wrap_pyfunction!(math::gcd::alt_egcd, math_module)?)?; math_module.add_function(wrap_pyfunction!(math::gcd::alt_egcd, math_module)?)?;
math_module.add_function(wrap_pyfunction!(math::factorise::prime_factors , math_module)?)?; math_module.add_function(wrap_pyfunction!(math::factorise::prime_factors , math_module)?)?;
math_module.add_class::<math::gallois::GalloisField>()?; math_module.add_class::<math::gallois::GalloisField>()?;
math_module.add_class::<math::ecc::ElipticCurve>()?; math_module.add_class::<math::ecc::EllipticCurve>()?;
math_module.add_class::<math::ecc::ElipticCurvePoint>()?; math_module.add_class::<math::ecc::EllipticCurvePoint>()?;
parent_module.add_submodule(math_module)?; parent_module.add_submodule(math_module)?;
Ok(()) Ok(())
} }

View File

@ -76,7 +76,7 @@ pub fn main() {
cplex::printing::proc_result_num(result, args); cplex::printing::proc_result_num(result, args);
} }
GalloisActions::ECC(ecc_args) => { GalloisActions::ECC(ecc_args) => {
let ec = math::ecc::ElipticCurve::new(field, ecc_args.a, ecc_args.b, args.verbose).expect("Could not create eliptic curve"); let ec = math::ecc::EllipticCurve::new(field, ecc_args.a, ecc_args.b, args.verbose).expect("Could not create eliptic curve");
match ecc_args.action { match ecc_args.action {
ECCActions::Neg(ecc_neg_args) => { ECCActions::Neg(ecc_neg_args) => {
let p = ec.new_point(ecc_neg_args.r, ecc_neg_args.s); let p = ec.new_point(ecc_neg_args.r, ecc_neg_args.s);

View File

@ -27,16 +27,16 @@ use pyo3::{prelude::*, exceptions::PyValueError};
/// ///
/// real curves not supported, only in Gallois Fields /// real curves not supported, only in Gallois Fields
/// Eq and PartialEq might behave badly if the verbosity level is not the same. FIXME /// Eq and PartialEq might behave badly if the verbosity level is not the same. FIXME
pub struct ElipticCurve { pub struct EllipticCurve {
field: GalloisField, field: GalloisField,
a: u128, a: u128,
b: u128, b: u128,
points: Vec<ElipticCurvePoint>, points: Vec<EllipticCurvePoint>,
verbose: bool, verbose: bool,
INFINITY_POINT: ElipticCurvePoint INFINITY_POINT: EllipticCurvePoint
} }
impl ElipticCurve { impl EllipticCurve {
pub fn new<T>(field: GalloisField, a: T, b: T, verbose: bool) -> Result<Self, String> pub fn new<T>(field: GalloisField, a: T, b: T, verbose: bool) -> Result<Self, String>
where where
T: Integer, T: Integer,
@ -70,10 +70,10 @@ impl ElipticCurve {
Check for Diskriminante passed", field.reduce::<_, u128>(d)); Check for Diskriminante passed", field.reduce::<_, u128>(d));
} }
let mut infty = ElipticCurvePoint::new(0, 0); let mut infty = EllipticCurvePoint::new(0, 0);
infty.is_infinity_point = true; infty.is_infinity_point = true;
let infty = infty; let infty = infty;
let e = ElipticCurve { let e = EllipticCurve {
field, field,
a, a,
b, b,
@ -85,8 +85,8 @@ impl ElipticCurve {
} }
/// build a new point in the EC /// build a new point in the EC
pub fn new_point(&self, r: u128, s: u128) -> Result<ElipticCurvePoint, String> { pub fn new_point(&self, r: u128, s: u128) -> Result<EllipticCurvePoint, String> {
let p = ElipticCurvePoint::new(r, s); let p = EllipticCurvePoint::new(r, s);
if self.verbose { if self.verbose {
println!("{p}") println!("{p}")
} }
@ -119,7 +119,7 @@ impl ElipticCurve {
return res1 as i128; return res1 as i128;
} }
pub fn check_point(&self, p: ElipticCurvePoint, verbose: bool) -> bool { pub fn check_point(&self, p: EllipticCurvePoint, verbose: bool) -> bool {
if p.is_infinity_point { if p.is_infinity_point {
println!("p is infinity: {p}"); println!("p is infinity: {p}");
return true; return true;
@ -152,8 +152,8 @@ impl ElipticCurve {
/// add two points /// add two points
pub fn add(&self, p1: ElipticCurvePoint, p2: ElipticCurvePoint) -> pub fn add(&self, p1: EllipticCurvePoint, p2: EllipticCurvePoint) ->
Result<ElipticCurvePoint, String> { Result<EllipticCurvePoint, String> {
if self.verbose { if self.verbose {
seperator(); seperator();
println!("adding {p1} + {p2}"); println!("adding {p1} + {p2}");
@ -309,13 +309,13 @@ impl ElipticCurve {
} }
/// get negative of a point /// get negative of a point
pub fn neg(&self, p: ElipticCurvePoint) -> ElipticCurvePoint { pub fn neg(&self, p: EllipticCurvePoint) -> EllipticCurvePoint {
self.new_point(p.r, self.field.reduce::<_, u128>(-(p.s as i128))).expect("negation of \ self.new_point(p.r, self.field.reduce::<_, u128>(-(p.s as i128))).expect("negation of \
point is not on field, math error") point is not on field, math error")
} }
/// multip.s a point by an integer /// multip.s a point by an integer
pub fn mul<T>(&self, g: ElipticCurvePoint, t: T) -> Result<ElipticCurvePoint, String> pub fn mul<T>(&self, g: EllipticCurvePoint, t: T) -> Result<EllipticCurvePoint, String>
where where
T: Integer, T: Integer,
T: NumCast, T: NumCast,
@ -340,8 +340,8 @@ impl ElipticCurve {
} }
t_bits.reverse(); t_bits.reverse();
let l = t_bits.len() - 1; let l = t_bits.len() - 1;
let mut lh: ElipticCurvePoint = g; let mut lh: EllipticCurvePoint = g;
let mut h: ElipticCurvePoint = g; let mut h: EllipticCurvePoint = g;
let mut index: usize = l; let mut index: usize = l;
if l == 0 { if l == 0 {
return Ok(h); return Ok(h);
@ -375,8 +375,9 @@ impl ElipticCurve {
} }
#[pymethods] #[pymethods]
impl ElipticCurve { impl EllipticCurve {
#[new] #[new]
#[pyo3(signature=(field, a, b, verbose = true))]
pub fn py_new(field: GalloisField, a: i128, b: i128, verbose: bool) -> PyResult<Self> { pub fn py_new(field: GalloisField, a: i128, b: i128, verbose: bool) -> PyResult<Self> {
match Self::new(field, a, b, verbose) { match Self::new(field, a, b, verbose) {
Ok(v) => {return Ok(v)}, Ok(v) => {return Ok(v)},
@ -388,7 +389,7 @@ impl ElipticCurve {
} }
#[pyo3(name="new_point")] #[pyo3(name="new_point")]
pub fn py_new_point(&self, r: u128, s: u128) -> PyResult<ElipticCurvePoint> { pub fn py_new_point(&self, r: u128, s: u128) -> PyResult<EllipticCurvePoint> {
match self.new_point(r, s) { match self.new_point(r, s) {
Ok(v) => {return Ok(v)}, Ok(v) => {return Ok(v)},
Err(e) => { Err(e) => {
@ -404,13 +405,13 @@ impl ElipticCurve {
} }
#[pyo3(name="check_point", signature=(p, verbose = true))] #[pyo3(name="check_point", signature=(p, verbose = true))]
pub fn py_check_point(&self, p: ElipticCurvePoint, verbose: bool) -> bool { pub fn py_check_point(&self, p: EllipticCurvePoint, verbose: bool) -> bool {
self.check_point(p, verbose) self.check_point(p, verbose)
} }
#[pyo3(name="add")] #[pyo3(name="add")]
pub fn py_add(&self, p1: ElipticCurvePoint, p2: ElipticCurvePoint) pub fn py_add(&self, p1: EllipticCurvePoint, p2: EllipticCurvePoint)
-> PyResult<ElipticCurvePoint> { -> PyResult<EllipticCurvePoint> {
match self.add(p1, p2) { match self.add(p1, p2) {
Ok(v) => {return Ok(v)}, Ok(v) => {return Ok(v)},
Err(e) => { Err(e) => {
@ -421,13 +422,13 @@ impl ElipticCurve {
} }
#[pyo3(name="neg")] #[pyo3(name="neg")]
pub fn py_neg(&self, p: ElipticCurvePoint) -> ElipticCurvePoint { pub fn py_neg(&self, p: EllipticCurvePoint) -> EllipticCurvePoint {
self.neg(p) self.neg(p)
} }
#[pyo3(name="mul")] #[pyo3(name="mul")]
pub fn py_mul(&self, p1: ElipticCurvePoint, t: u128) pub fn py_mul(&self, p1: EllipticCurvePoint, t: u128)
-> PyResult<ElipticCurvePoint> { -> PyResult<EllipticCurvePoint> {
match self.mul(p1, t) { match self.mul(p1, t) {
Ok(v) => {return Ok(v)}, Ok(v) => {return Ok(v)},
Err(e) => { Err(e) => {
@ -437,6 +438,10 @@ impl ElipticCurve {
} }
} }
pub fn get_infinity_point(&self) -> EllipticCurvePoint {
return self.INFINITY_POINT;
}
fn __str__(&self) -> PyResult<String> { fn __str__(&self) -> PyResult<String> {
Ok(format!("{}", self)) Ok(format!("{}", self))
} }
@ -446,7 +451,7 @@ impl ElipticCurve {
} }
} }
impl std::fmt::Display for ElipticCurve{ impl std::fmt::Display for EllipticCurve{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "F(X, Y) = Y² - X³ -{}X - {}", self.a, self.b) write!(f, "F(X, Y) = Y² - X³ -{}X - {}", self.a, self.b)
} }
@ -457,18 +462,18 @@ impl std::fmt::Display for ElipticCurve{
/// represent a specific eliptic curves point /// represent a specific eliptic curves point
/// ///
/// PartialEq and Eq might behave badly with diffrent verbosity FIXME /// PartialEq and Eq might behave badly with diffrent verbosity FIXME
pub struct ElipticCurvePoint { pub struct EllipticCurvePoint {
r: u128, r: u128,
s: u128, s: u128,
is_infinity_point: bool, is_infinity_point: bool,
} }
#[pymethods] #[pymethods]
impl ElipticCurvePoint { impl EllipticCurvePoint {
#[new] #[new]
/// create a new point /// create a new point
pub fn new(r: u128, s: u128) -> ElipticCurvePoint { pub fn new(r: u128, s: u128) -> EllipticCurvePoint {
ElipticCurvePoint { EllipticCurvePoint {
r, r,
s, s,
is_infinity_point: false, is_infinity_point: false,
@ -484,7 +489,7 @@ impl ElipticCurvePoint {
} }
} }
impl std::fmt::Display for ElipticCurvePoint { impl std::fmt::Display for EllipticCurvePoint {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.is_infinity_point { if self.is_infinity_point {
write!(f, "(∞ INFINITY)") write!(f, "(∞ INFINITY)")
@ -503,14 +508,14 @@ pub mod test {
#[test] #[test]
fn test_eliptic_curve_new() { fn test_eliptic_curve_new() {
let f = GalloisField::new(7, true, None); let f = GalloisField::new(7, true, None);
let _ = ElipticCurve::new(f, 1, 2, true).expect_err("invalid ec can be created"); let _ = EllipticCurve::new(f, 1, 2, true).expect_err("invalid ec can be created");
let _ = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created"); let _ = EllipticCurve::new(f, -3, 3, true).expect("ec cant be created");
} }
#[test] #[test]
fn test_check_point() { fn test_check_point() {
let f = GalloisField::new(13, true, None); let f = GalloisField::new(13, true, None);
let ec = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, -3, 3, true).expect("ec cant be created");
// real points // real points
let p = vec![ let p = vec![
ec.new_point(0, 4 ).unwrap(), ec.new_point(0, 4 ).unwrap(),
@ -539,7 +544,7 @@ pub mod test {
#[test] #[test]
fn test_add_points() { fn test_add_points() {
let f = GalloisField::new(13, true, None); let f = GalloisField::new(13, true, None);
let ec = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, -3, 3, true).expect("ec cant be created");
let p1 = ec.new_point(1, 1).expect("point is on ec but an error occurs"); let p1 = ec.new_point(1, 1).expect("point is on ec but an error occurs");
let p2 = ec.new_point(5, 3).expect("point is on ec but an error occurs"); let p2 = ec.new_point(5, 3).expect("point is on ec but an error occurs");
let p3 = ec.new_point(4, 4).expect("point is on ec but an error occurs"); let p3 = ec.new_point(4, 4).expect("point is on ec but an error occurs");
@ -548,13 +553,13 @@ pub mod test {
assert_eq!(ec.add(p1, p2).expect("error for possible addition"), p3); assert_eq!(ec.add(p1, p2).expect("error for possible addition"), p3);
assert_eq!(ec.add(p2, p4).expect("error for possible addition"), p1); assert_eq!(ec.add(p2, p4).expect("error for possible addition"), p1);
assert_eq!(ec.add(p1, p1).expect("error for possible addition"), p5); assert_eq!(ec.add(p1, p1).expect("error for possible addition"), p5);
let ec = ElipticCurve::new(f, 7, 11, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 7, 11, true).expect("ec cant be created");
let p1 = ec.new_point(4, 5).expect("point is on ec but an error occurs"); let p1 = ec.new_point(4, 5).expect("point is on ec but an error occurs");
let p2 = ec.new_point(6, 10).expect("point is on ec but an error occurs"); let p2 = ec.new_point(6, 10).expect("point is on ec but an error occurs");
assert_eq!(ec.add(p1, p1).expect("error for possible addition"), p2); assert_eq!(ec.add(p1, p1).expect("error for possible addition"), p2);
let f = GalloisField::new(17, true, None); let f = GalloisField::new(17, true, None);
let ec = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, -3, 3, true).expect("ec cant be created");
let p1 = ec.new_point(3, 2).expect("point is on ec but an error occurs"); let p1 = ec.new_point(3, 2).expect("point is on ec but an error occurs");
let p2 = ec.new_point(11, 3).expect("point is on ec but an error occurs"); let p2 = ec.new_point(11, 3).expect("point is on ec but an error occurs");
let p3 = ec.new_point(7, 6).expect("point is on ec but an error occurs"); let p3 = ec.new_point(7, 6).expect("point is on ec but an error occurs");
@ -564,23 +569,23 @@ pub mod test {
assert_eq!(ec.add(p4, p4).expect("error for possible addition"), p5); assert_eq!(ec.add(p4, p4).expect("error for possible addition"), p5);
let f = GalloisField::new(11, true, None); let f = GalloisField::new(11, true, None);
let ec = ElipticCurve::new(f, 1, 1, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 1, 1, true).expect("ec cant be created");
let p1 = ec.new_point(3, 3).expect("point is on ec but an error occurs"); let p1 = ec.new_point(3, 3).expect("point is on ec but an error occurs");
let p2 = ec.new_point(6, 5).expect("point is on ec but an error occurs"); let p2 = ec.new_point(6, 5).expect("point is on ec but an error occurs");
let p3 = ec.new_point(0, 10).expect("point is on ec but an error occurs"); let p3 = ec.new_point(0, 10).expect("point is on ec but an error occurs");
assert_eq!(ec.add(p1, p2).expect("error for possible addition"), p3); assert_eq!(ec.add(p1, p2).expect("error for possible addition"), p3);
let f = GalloisField::new(19, true, None); let f = GalloisField::new(19, true, None);
let ec = ElipticCurve::new(f, 7, 13, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 7, 13, true).expect("ec cant be created");
let p1 = ec.new_point(2, 15).expect("point is on ec but an error occurs"); let p1 = ec.new_point(2, 15).expect("point is on ec but an error occurs");
let p2 = ec.new_point(6, 10).expect("point is on ec but an error occurs"); let p2 = ec.new_point(6, 10).expect("point is on ec but an error occurs");
let p3 = ec.new_point(9, 8).expect("point is on ec but an error occurs"); let p3 = ec.new_point(9, 8).expect("point is on ec but an error occurs");
assert_eq!(ec.add(p1, p2).expect("error for possible addition"), p3); assert_eq!(ec.add(p1, p2).expect("error for possible addition"), p3);
let ec = ElipticCurve::new(f, 10, 3, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 10, 3, true).expect("ec cant be created");
let p1 = ec.new_point(5, 11).expect("point is on ec but an error occurs"); let p1 = ec.new_point(5, 11).expect("point is on ec but an error occurs");
let p2 = ec.new_point(5, 8).expect("point is on ec but an error occurs"); let p2 = ec.new_point(5, 8).expect("point is on ec but an error occurs");
assert_eq!(ec.add(p1, p2).expect("error for possible addition"), ec.INFINITY_POINT); assert_eq!(ec.add(p1, p2).expect("error for possible addition"), ec.INFINITY_POINT);
let ec = ElipticCurve::new(f, 7, 13, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 7, 13, true).expect("ec cant be created");
let p1 = ec.new_point(7, 5).expect("point is on ec but an error occurs"); let p1 = ec.new_point(7, 5).expect("point is on ec but an error occurs");
let p2 = ec.new_point(2, 15).expect("point is on ec but an error occurs"); let p2 = ec.new_point(2, 15).expect("point is on ec but an error occurs");
assert_eq!(ec.add(p1, p1).expect("error for possible addition"), p2); assert_eq!(ec.add(p1, p1).expect("error for possible addition"), p2);
@ -590,7 +595,7 @@ pub mod test {
fn test_mul_points() { fn test_mul_points() {
// from ecc lectures // from ecc lectures
let f = GalloisField::new(13, true, None); let f = GalloisField::new(13, true, None);
let ec = ElipticCurve::new(f, 7, 11, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 7, 11, true).expect("ec cant be created");
let p1 = ec.new_point(4, 5).expect("point is on ec but an error occurs"); let p1 = ec.new_point(4, 5).expect("point is on ec but an error occurs");
let p2 = ec.new_point(6, 10).expect("point is on ec but an error occurs"); let p2 = ec.new_point(6, 10).expect("point is on ec but an error occurs");
let p3 = ec.new_point(4, 8).expect("point is on ec but an error occurs"); let p3 = ec.new_point(4, 8).expect("point is on ec but an error occurs");
@ -601,13 +606,13 @@ pub mod test {
assert_eq!(ec.mul(p2, 4u32).expect("error for possible addition"), p4); assert_eq!(ec.mul(p2, 4u32).expect("error for possible addition"), p4);
let f = GalloisField::new(13, true, None); let f = GalloisField::new(13, true, None);
let ec = ElipticCurve::new(f, -3, 3, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, -3, 3, true).expect("ec cant be created");
let p1 = ec.new_point(1, 1).expect("point is on ec but an error occurs"); let p1 = ec.new_point(1, 1).expect("point is on ec but an error occurs");
let p2 = ec.new_point(11, 12).expect("point is on ec but an error occurs"); let p2 = ec.new_point(11, 12).expect("point is on ec but an error occurs");
assert_eq!(ec.mul(p1, 2u64).expect("error for possible addition"), p2); assert_eq!(ec.mul(p1, 2u64).expect("error for possible addition"), p2);
let f = GalloisField::new(17, true, None); let f = GalloisField::new(17, true, None);
let ec = ElipticCurve::new(f, 11, 3, true).expect("ec cant be created"); let ec = EllipticCurve::new(f, 11, 3, true).expect("ec cant be created");
let p1 = ec.new_point(5, 8).expect("point is on ec but an error occurs"); let p1 = ec.new_point(5, 8).expect("point is on ec but an error occurs");
let p2 = ec.new_point(6, 8).expect("point is on ec but an error occurs"); let p2 = ec.new_point(6, 8).expect("point is on ec but an error occurs");
assert_eq!(ec.mul(p1, 10u128).expect("error for possible addition"), p2); assert_eq!(ec.mul(p1, 10u128).expect("error for possible addition"), p2);