Skip to content

Instantly share code, notes, and snippets.

@mcdallas
Created February 8, 2018 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcdallas/d623779fa72c12823bf6fc1d2166dadd to your computer and use it in GitHub Desktop.
Save mcdallas/d623779fa72c12823bf6fc1d2166dadd to your computer and use it in GitHub Desktop.
extern crate num;
use num::bigint::BigInt;
use num::FromPrimitive;
use num::Integer;
use num::One;
use num::Zero;
#[derive(PartialEq, Clone)]
struct Point {
x: BigInt,
y: BigInt
}
pub fn powm(base: &BigInt, exp: &BigInt, modulus: &BigInt) -> BigInt {
let zero = BigInt::zero();
let one: BigInt = BigInt::one();
let two = &one + &one;
let mut exp = exp.clone();
let mut result = one.clone();
let mut base = base % modulus;
while exp > zero {
if &exp % &two == one {
result = (result * &base) % modulus;
}
exp = exp >> 1;
base = (&base * &base) % modulus;
}
result.mod_floor(modulus)
}
fn point_add(p: &Point, q: &Point, P: &BigInt) -> Point {
let lam: BigInt = if p == q {
3u32 * &p.x * &p.x * powm(&((2u32 * &p.y) % P), &(P - 2u32), P)
} else {
powm(&(&q.x - &p.x), &(P - 2u32), P) * (&q.y - &p.y) % P
};
let rx = num::pow(lam.clone(), 2) - &p.x - &q.x;
let ry: BigInt = lam * (&p.x - &rx) - &p.y;
Point{x: rx.mod_floor(P), y: ry.mod_floor(P)}
}
fn point_mul(p: &Point, d: u32, P: BigInt) -> Point {
let mut n: Point = (*p).clone();
let mut q: Option<Point> = None;
let binary: String = format!("{:0256b}", d);
for (i, digit) in binary.chars().rev().enumerate() {
if digit == '1' {
q = match q { None => Some(n.clone()), Some(i) => Some(point_add(&i, &n, &P)) }
}
n = point_add(&n, &n, &P);
}
q.unwrap()
}
fn main() {
let G: Point = Point {
x: BigInt::parse_bytes(b"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16).unwrap(),
y: BigInt::parse_bytes(b"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16).unwrap()
};
let P: BigInt = BigInt::parse_bytes(b"115792089237316195423570985008687907853269984665640564039457584007908834671663", 10).unwrap();
let res = point_mul(&G, 125, P);
println!(" {}", res.x);
println!(" {}", res.y);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment