subtraction and calculating char in GF
This commit is contained in:
parent
9f3e8718b8
commit
59a7e22e70
260
src/math/ecc.rs
260
src/math/ecc.rs
|
@ -165,158 +165,146 @@ impl ElipticCurve {
|
||||||
if !self.check_point(p2, false) {
|
if !self.check_point(p2, false) {
|
||||||
return Err(String::from("{p2} is not a valid point"));
|
return Err(String::from("{p2} is not a valid point"));
|
||||||
}
|
}
|
||||||
if self.field.prime_base {
|
// case 1: both infty
|
||||||
// verbisity stuff
|
if p1.is_infinity_point && p2.is_infinity_point {
|
||||||
//if self.verbose {
|
if self.verbose {
|
||||||
// println!("{} = {}; {} = -{} = {} <=> {}",
|
println!("case 1");
|
||||||
// p1.r, p2.r, p1.s, p2.s, self.neg(p2).s,
|
|
||||||
// p1.r == p2.r && p1.s == self.neg(p2).s,
|
|
||||||
// );
|
|
||||||
//}
|
|
||||||
// case 1: both infty
|
|
||||||
if p1.is_infinity_point && p2.is_infinity_point {
|
|
||||||
if self.verbose {
|
|
||||||
println!("case 1");
|
|
||||||
}
|
|
||||||
return Ok(self.INFINITY_POINT);
|
|
||||||
}
|
}
|
||||||
// case 2: one is infty
|
return Ok(self.INFINITY_POINT);
|
||||||
else if p1.is_infinity_point && !p2.is_infinity_point ||
|
}
|
||||||
!p1.is_infinity_point && p2.is_infinity_point
|
// case 2: one is infty
|
||||||
{
|
else if p1.is_infinity_point && !p2.is_infinity_point ||
|
||||||
if self.verbose {
|
!p1.is_infinity_point && p2.is_infinity_point
|
||||||
println!("case 2");
|
{
|
||||||
}
|
if self.verbose {
|
||||||
return Ok(self.INFINITY_POINT);
|
println!("case 2");
|
||||||
}
|
}
|
||||||
// case 3: r_1 != r_2
|
return Ok(self.INFINITY_POINT);
|
||||||
else if p1.r != p2.r {
|
}
|
||||||
if self.verbose {
|
// case 3: r_1 != r_2
|
||||||
println!("case 3");
|
else if p1.r != p2.r {
|
||||||
}
|
if self.verbose {
|
||||||
if self.field.prime_base {
|
println!("case 3");
|
||||||
let m: u128 = self.field.reduce::<i128, u128>(p2.s as i128 - p1.s as i128) *
|
|
||||||
self.field.inverse(
|
|
||||||
self.field.reduce::<i128, u128>(p2.r as i128 - p1.r as i128)
|
|
||||||
).expect("could not find inverse");
|
|
||||||
let m: i128 = m as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("m = [s_2 - s_1]/[r_2 - r_1] = [{} - {}]/[{} - {}] = {} = {}",
|
|
||||||
p2.s, p1.s, p2.r, p1.r, m, self.field.reduce::<_, u128>(m))
|
|
||||||
}
|
|
||||||
let m: i128 = self.field.reduce(m);
|
|
||||||
|
|
||||||
let r3 = m.pow(2) - p1.r as i128 - p2.r as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
|
||||||
m.pow(2), p1.r, p2.r, r3, self.field.reduce::<_, u128>(r3));
|
|
||||||
}
|
|
||||||
let r3 = self.field.reduce::<_, u128>(r3);
|
|
||||||
|
|
||||||
let s3 = m.pow(3) - 2*m*p1.r as i128 - m*p2.r as i128 + p1.s as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("s_3 = m³ − 2*m*r_1 − m*r_2 + s1 =\
|
|
||||||
{} - 2*{m}*{} - {m}*{} + {} = {} = {}",
|
|
||||||
m.pow(3), p1.r, p2.r, p1.s, s3,
|
|
||||||
self.field.reduce::<_, u128>(s3));
|
|
||||||
}
|
|
||||||
let s3 = self.field.reduce::<_, u128>(s3) as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("-s_3 = - {s3} = {}", self.field.reduce::<_, u128>(-s3));
|
|
||||||
println!("Q = ({}, {})", r3, s3);
|
|
||||||
}
|
|
||||||
let p3 = self.new_point(r3, self.field.reduce::<_, u128>(-s3)).expect("calculated point does not exist");
|
|
||||||
|
|
||||||
if self.verbose {
|
|
||||||
seperator();
|
|
||||||
println!("result: ({}, {})", p3.r, p3.s);
|
|
||||||
seperator();
|
|
||||||
}
|
|
||||||
return Ok(p3);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
panic!("TODO");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// case 4: r_1 = r_2 && s_1 = -s_2
|
if self.field.prime_base {
|
||||||
else if p1.r == p2.r && p1.s == self.neg(p2).s {
|
let m: u128 = self.field.reduce::<i128, u128>(p2.s as i128 - p1.s as i128) *
|
||||||
|
self.field.inverse(
|
||||||
|
self.field.reduce::<i128, u128>(p2.r as i128 - p1.r as i128)
|
||||||
|
).expect("could not find inverse");
|
||||||
|
let m: i128 = m as i128;
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("case 4");
|
println!("m = [s_2 - s_1]/[r_2 - r_1] = [{} - {}]/[{} - {}] = {} = {}",
|
||||||
|
p2.s, p1.s, p2.r, p1.r, m, self.field.reduce::<_, u128>(m))
|
||||||
}
|
}
|
||||||
return Ok(self.INFINITY_POINT);
|
let m: i128 = self.field.reduce(m);
|
||||||
}
|
|
||||||
// case 5: P + P where P = (r, 0)
|
let r3 = m.pow(2) - p1.r as i128 - p2.r as i128;
|
||||||
else if p1 == p2 && p1.s == 0 {
|
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("case 5");
|
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
||||||
|
m.pow(2), p1.r, p2.r, r3, self.field.reduce::<_, u128>(r3));
|
||||||
}
|
}
|
||||||
return Ok(self.INFINITY_POINT);
|
let r3 = self.field.reduce::<_, u128>(r3);
|
||||||
}
|
|
||||||
// case 6: P + P where s != 0
|
let s3 = m.pow(3) - 2*m*p1.r as i128 - m*p2.r as i128 + p1.s as i128;
|
||||||
else if p1 == p2 && p1.s != 0 {
|
|
||||||
if self.verbose {
|
if self.verbose {
|
||||||
println!("case 6");
|
println!("s_3 = m³ − 2*m*r_1 − m*r_2 + s1 =\
|
||||||
|
{} - 2*{m}*{} - {m}*{} + {} = {} = {}",
|
||||||
|
m.pow(3), p1.r, p2.r, p1.s, s3,
|
||||||
|
self.field.reduce::<_, u128>(s3));
|
||||||
}
|
}
|
||||||
if self.field.prime_base {
|
let s3 = self.field.reduce::<_, u128>(s3) as i128;
|
||||||
let m: i128 = (self.field.reduce::<_, u128>(3 * p1.r.pow(2) + self.a) *
|
if self.verbose {
|
||||||
self.field.inverse(
|
println!("-s_3 = - {s3} = {}", self.field.reduce::<_, u128>(-s3));
|
||||||
self.field.reduce::<u128, u128>(2 * p1.s)
|
println!("Q = ({}, {})", r3, s3);
|
||||||
).expect("could not find inverse")) as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("m = [3*r² + a]/[2s] = [3*{}² + {}]/[2*{}] = \
|
|
||||||
{}/{} = \
|
|
||||||
{}*{} = \
|
|
||||||
{} = {}",
|
|
||||||
p1.r, self.a, p1.s,
|
|
||||||
|
|
||||||
self.field.reduce::<_, u128>(3 * p1.r.pow(2) + self.a),
|
|
||||||
2 * p1.s,
|
|
||||||
|
|
||||||
self.field.reduce::<_, u128>(3 * p1.r.pow(2) + self.a),
|
|
||||||
self.field.inverse(self.field.reduce::<u128, u128>(2 * p1.s)).unwrap(),
|
|
||||||
|
|
||||||
m,
|
|
||||||
self.field.reduce::<_, u128>(m)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let m: i128 = self.field.reduce(m);
|
|
||||||
|
|
||||||
let r3: i128 = self.field.reduce::<_, i128>(m.pow(2)) - p1.r as i128 - p2.r as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
|
||||||
m.pow(2), p1.r, p2.r, r3, self.field.reduce::<_, u128>(r3));
|
|
||||||
}
|
|
||||||
let r3: i128 = self.field.reduce(r3);
|
|
||||||
|
|
||||||
let s3: i128 = m.pow(3) - 2*m*p1.r as i128 - m*p2.r as i128 + p1.s as i128;
|
|
||||||
if self.verbose {
|
|
||||||
println!("s_3 = m³ − 2*m*r_1 − m*r_2 + s1 = {} - 2*{m}*{} - {m}*{} + {} = \
|
|
||||||
{} = {}",
|
|
||||||
m.pow(3), p1.r, p2.r, p1.s, s3, self.field.reduce::<_, u128>(s3));
|
|
||||||
}
|
|
||||||
let s3: i128 = self.field.reduce(s3);
|
|
||||||
let p3 = self.new_point(r3 as u128, self.field.reduce::<_, u128>(-s3)).expect("calculated point does not exist in curve");
|
|
||||||
|
|
||||||
if self.verbose {
|
|
||||||
seperator();
|
|
||||||
println!("result: ({}, {})", p3.r, p3.s);
|
|
||||||
seperator();
|
|
||||||
}
|
|
||||||
return Ok(p3);
|
|
||||||
}
|
}
|
||||||
else {
|
let p3 = self.new_point(r3, self.field.reduce::<_, u128>(-s3)).expect("calculated point does not exist");
|
||||||
panic!("TODO");
|
|
||||||
|
if self.verbose {
|
||||||
|
seperator();
|
||||||
|
println!("result: ({}, {})", p3.r, p3.s);
|
||||||
|
seperator();
|
||||||
}
|
}
|
||||||
|
return Ok(p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// how do we get here?
|
|
||||||
// this should never occur
|
|
||||||
else {
|
else {
|
||||||
panic!("No rules for adding these two points, mathmatically impossible.")
|
panic!("TODO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// case 4: r_1 = r_2 && s_1 = -s_2
|
||||||
|
else if p1.r == p2.r && p1.s == self.neg(p2).s {
|
||||||
|
if self.verbose {
|
||||||
|
println!("case 4");
|
||||||
|
}
|
||||||
|
return Ok(self.INFINITY_POINT);
|
||||||
|
}
|
||||||
|
// case 5: P + P where P = (r, 0)
|
||||||
|
else if p1 == p2 && p1.s == 0 {
|
||||||
|
if self.verbose {
|
||||||
|
println!("case 5");
|
||||||
|
}
|
||||||
|
return Ok(self.INFINITY_POINT);
|
||||||
|
}
|
||||||
|
// case 6: P + P where s != 0
|
||||||
|
else if p1 == p2 && p1.s != 0 {
|
||||||
|
if self.verbose {
|
||||||
|
println!("case 6");
|
||||||
|
}
|
||||||
|
if self.field.prime_base {
|
||||||
|
let m: i128 = (self.field.reduce::<_, u128>(3 * p1.r.pow(2) + self.a) *
|
||||||
|
self.field.inverse(
|
||||||
|
self.field.reduce::<u128, u128>(2 * p1.s)
|
||||||
|
).expect("could not find inverse")) as i128;
|
||||||
|
if self.verbose {
|
||||||
|
println!("m = [3*r² + a]/[2s] = [3*{}² + {}]/[2*{}] = \
|
||||||
|
{}/{} = \
|
||||||
|
{}*{} = \
|
||||||
|
{} = {}",
|
||||||
|
p1.r, self.a, p1.s,
|
||||||
|
|
||||||
|
self.field.reduce::<_, u128>(3 * p1.r.pow(2) + self.a),
|
||||||
|
2 * p1.s,
|
||||||
|
|
||||||
|
self.field.reduce::<_, u128>(3 * p1.r.pow(2) + self.a),
|
||||||
|
self.field.inverse(self.field.reduce::<u128, u128>(2 * p1.s)).unwrap(),
|
||||||
|
|
||||||
|
m,
|
||||||
|
self.field.reduce::<_, u128>(m)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let m: i128 = self.field.reduce(m);
|
||||||
|
|
||||||
|
let r3: i128 = self.field.reduce::<_, i128>(m.pow(2)) - p1.r as i128 - p2.r as i128;
|
||||||
|
if self.verbose {
|
||||||
|
println!("r_3 = m² - r_1 - r_2 = {} - {} - {} = {} = {}",
|
||||||
|
m.pow(2), p1.r, p2.r, r3, self.field.reduce::<_, u128>(r3));
|
||||||
|
}
|
||||||
|
let r3: i128 = self.field.reduce(r3);
|
||||||
|
|
||||||
|
let s3: i128 = m.pow(3) - 2*m*p1.r as i128 - m*p2.r as i128 + p1.s as i128;
|
||||||
|
if self.verbose {
|
||||||
|
println!("s_3 = m³ − 2*m*r_1 − m*r_2 + s1 = {} - 2*{m}*{} - {m}*{} + {} = \
|
||||||
|
{} = {}",
|
||||||
|
m.pow(3), p1.r, p2.r, p1.s, s3, self.field.reduce::<_, u128>(s3));
|
||||||
|
}
|
||||||
|
let s3: i128 = self.field.reduce(s3);
|
||||||
|
let p3 = self.new_point(r3 as u128, self.field.reduce::<_, u128>(-s3)).expect("calculated point does not exist in curve");
|
||||||
|
|
||||||
|
if self.verbose {
|
||||||
|
seperator();
|
||||||
|
println!("result: ({}, {})", p3.r, p3.s);
|
||||||
|
seperator();
|
||||||
|
}
|
||||||
|
return Ok(p3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic!("TODO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// how do we get here?
|
||||||
|
// this should never occur
|
||||||
else {
|
else {
|
||||||
return Err(String::from("Only prime fields are supported currently"));
|
panic!("No rules for adding these two points, mathmatically impossible.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
use crate::{math::modexp, cplex::printing::seperator, math::modred::modred};
|
use crate::{math::modexp, cplex::printing::seperator, math::modred::modred};
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::{fmt::Debug, ops::BitXor};
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use num::{Integer, NumCast};
|
use num::{Integer, NumCast};
|
||||||
|
|
||||||
|
@ -205,7 +205,41 @@ impl GalloisField {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
r = a ^ b;
|
r = a ^ b;
|
||||||
println!("r = a ^ b = {a:b} ^ {b:b} = {r:b}");
|
println!("r = a ^ b = {a:b} ^ {b:b} = {r:b}\n\
|
||||||
|
r = a + b = ({}) + ({}) = {}",
|
||||||
|
self.display(a),
|
||||||
|
self.display(b),
|
||||||
|
self.display(r),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
num::cast(self.reduce::<_, T>(r)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// subtraction in the field
|
||||||
|
///
|
||||||
|
/// in case of a prime base, addition works as normal,
|
||||||
|
/// if the base is a prime power, all elements are treated as polynomials, so the
|
||||||
|
/// operations are changed too.
|
||||||
|
pub fn sub<T>(&self, a: T, b: T) -> T
|
||||||
|
where
|
||||||
|
T: Integer,
|
||||||
|
T: Debug,
|
||||||
|
T: NumCast
|
||||||
|
{
|
||||||
|
let a: i128 = self.reduce(num::cast::<_, u128>(a).unwrap());
|
||||||
|
let b: i128 = self.reduce(num::cast::<_, u128>(b).unwrap());
|
||||||
|
let r: i128;
|
||||||
|
if self.prime_base {
|
||||||
|
r = a - b;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = a ^ b;
|
||||||
|
println!("r = a ^ b = {a:b} ^ {b:b} = {r:b}\n\
|
||||||
|
r = a + b = ({}) + ({}) = {}",
|
||||||
|
self.display(a),
|
||||||
|
self.display(b),
|
||||||
|
self.display(r),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
num::cast(self.reduce::<_, T>(r)).unwrap()
|
num::cast(self.reduce::<_, T>(r)).unwrap()
|
||||||
}
|
}
|
||||||
|
@ -405,18 +439,30 @@ impl GalloisField {
|
||||||
seperator();
|
seperator();
|
||||||
println!("calculating characteristic of F_{}", self.base);
|
println!("calculating characteristic of F_{}", self.base);
|
||||||
}
|
}
|
||||||
let mut i = 1u128;
|
if self.prime_base {
|
||||||
while self.reduce::<_, u128>(i) != 0 {
|
let mut i = 1u128;
|
||||||
i = self.add(i, 1);
|
while self.reduce::<_, u128>(i) != 0 {
|
||||||
}
|
i += 1;
|
||||||
if self.verbose {
|
}
|
||||||
println!("{i} = {} (mod {})", self.reduce::<_, u128>(i), self.base);
|
if self.verbose {
|
||||||
println!("Therefore, char(F_{}) = {i}", self.base);
|
println!("{i} = {} (mod {})", self.reduce::<_, u128>(i), self.base);
|
||||||
seperator();
|
println!("Therefore, char(F_{}) = {i}", self.base);
|
||||||
}
|
seperator();
|
||||||
|
}
|
||||||
|
|
||||||
self.cha = i;
|
self.cha = i;
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if self.base.is_power_of_two() {
|
||||||
|
// if you need the k part of 2**k = self.base
|
||||||
|
//let l: u32 = self.base.ilog2();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic!("GalloisField for bases other then primes or powers of two not implemented.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// display an element in the field
|
/// display an element in the field
|
||||||
|
@ -428,7 +474,7 @@ impl GalloisField {
|
||||||
T: NumCast,
|
T: NumCast,
|
||||||
T: Debug
|
T: Debug
|
||||||
{
|
{
|
||||||
let mut n: u128 = self.reduce(num::cast::<_, u128>(n).unwrap());
|
let n: u128 = self.reduce(num::cast::<_, u128>(n).unwrap());
|
||||||
let mut buf: String = String::new();
|
let mut buf: String = String::new();
|
||||||
let n_len = n.count_ones() + n.count_zeros();
|
let n_len = n.count_ones() + n.count_zeros();
|
||||||
let mut first: bool = true;
|
let mut first: bool = true;
|
||||||
|
@ -597,6 +643,31 @@ pub mod test {
|
||||||
assert_eq!(field.add(0b1010101, 0b10101010), field.reduce(0b11111111));
|
assert_eq!(field.add(0b1010101, 0b10101010), field.reduce(0b11111111));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gallois_sub() {
|
||||||
|
let field = GalloisField::new(977, true, None);
|
||||||
|
let ns = [132,1232,121,424];
|
||||||
|
for i in 0..976 {
|
||||||
|
for n in ns {
|
||||||
|
assert_eq!(field.sub(i, n), field.reduce(i-n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let field = GalloisField::new(8, true, None);
|
||||||
|
assert_eq!(field.sub(0b1, 0b10), field.reduce(0b11));
|
||||||
|
assert_eq!(field.sub(0b11, 0b10), field.reduce(0b01));
|
||||||
|
assert_eq!(field.sub(0b101, 0b1010), field.reduce(0b1111));
|
||||||
|
assert_eq!(field.sub(0b1010101, 0b10101010), field.reduce(0b11111111));
|
||||||
|
|
||||||
|
let field = GalloisField::new(16, true, None);
|
||||||
|
assert_eq!(field.sub(0b1, 0b10), field.reduce(0b11));
|
||||||
|
assert_eq!(field.sub(0b11, 0b10), field.reduce(0b01));
|
||||||
|
assert_eq!(field.sub(0b1111, 0b1011), field.reduce(0b0100));
|
||||||
|
assert_eq!(field.sub(0b101, 0b1010), field.reduce(0b1111));
|
||||||
|
assert_eq!(field.sub(0b1000, 0b111), field.reduce(0b1111));
|
||||||
|
assert_eq!(field.sub(0b1010101, 0b10101010), field.reduce(0b11111111));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gallois_reduce_c2() {
|
fn test_gallois_reduce_c2() {
|
||||||
let field = GalloisField::new(16, true, None);
|
let field = GalloisField::new(16, true, None);
|
||||||
|
|
Loading…
Reference in New Issue