diff --git a/src/cli.rs b/src/cli.rs index 6c88f43..7b4b3fa 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,6 +2,11 @@ use std::{fs::File, io::BufReader, path::Path}; use anyhow::{anyhow, Result}; use clap::Parser; +use openssl::{ + bn::{BigNum, BigNumRef}, + ec::{EcGroup, EcGroupRef, EcPoint, EcPointRef}, + pkey::Private, +}; use serde_json::from_reader; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -104,3 +109,113 @@ pub fn validate_command_line(options: &mut Options) -> Result Ok(keys) } + +pub struct Cli { + options: Options, + keys: serde_json::Value, + private_key: BigNum, + gen_order: BigNum, + gen_point: EcPoint, + pub_point: EcPoint, + e_curve: EcGroup, + product_key: Option, + count: u32, +} + +impl Cli { + pub fn new(options: Options, keys: serde_json::Value) -> Self { + let bink = &keys["BINK"][&options.binkid]; + // We cannot produce a valid key without knowing the private key k. The reason for this is that + // we need the result of the function K(x; y) = kG(x; y). + let private_key = BigNum::from_dec_str(bink["n"].as_str().unwrap()).unwrap(); + + // We can, however, validate any given key using the available public key: {p, a, b, G, K}. + // genOrder the order of the generator G, a value we have to reverse -> Schoof's Algorithm. + let gen_order = BigNum::from_dec_str(bink["priv"].as_str().unwrap()).unwrap(); + + let p = bink["p"].as_str().unwrap(); + let a = bink["a"].as_str().unwrap(); + let b = bink["b"].as_str().unwrap(); + let gx = bink["g"]["x"].as_str().unwrap(); + let gy = bink["g"]["y"].as_str().unwrap(); + let kx = bink["pub"]["x"].as_str().unwrap(); + let ky = bink["pub"]["y"].as_str().unwrap(); + let n = bink["n"].as_str().unwrap(); + let k = bink["priv"].as_str().unwrap(); + + if options.verbose { + println!("-----------------------------------------------------------"); + println!( + "Loaded the following elliptic curve parameters: BINK[{}]", + options.binkid + ); + println!("-----------------------------------------------------------"); + println!(" P: {p}"); + println!(" a: {a}"); + println!(" b: {b}"); + println!("Gx: {gx}"); + println!("Gy: {gy}"); + println!("Kx: {kx}"); + println!("Ky: {ky}"); + println!(" n: {n}"); + println!(" k: {k}"); + println!(); + } + + let (e_curve, gen_point, pub_point) = + Cli::initialize_elliptic_curve(p, a, b, gx, gy, kx, ky); + + Self { + options, + keys, + private_key, + gen_order, + gen_point, + pub_point, + e_curve, + product_key: None, + count: 0, + } + } + + fn initialize_elliptic_curve( + p_sel: &str, + a_sel: &str, + b_sel: &str, + generator_x_sel: &str, + generator_y_sel: &str, + public_key_x_sel: &str, + public_key_y_sel: &str, + ) -> (EcGroup, EcPoint, EcPoint) { + let mut context = openssl::bn::BigNumContext::new().unwrap(); + + let p = BigNum::from_dec_str(p_sel).unwrap(); + let a = BigNum::from_dec_str(a_sel).unwrap(); + let b = BigNum::from_dec_str(b_sel).unwrap(); + let generator_x = BigNum::from_dec_str(generator_x_sel).unwrap(); + let generator_y = BigNum::from_dec_str(generator_y_sel).unwrap(); + + let public_key_x = BigNum::from_dec_str(public_key_x_sel).unwrap(); + let public_key_y = BigNum::from_dec_str(public_key_y_sel).unwrap(); + + let c_curve = EcGroup::from_components(p, a, b, &mut context).unwrap(); + + let mut gen_point = EcPoint::new(&c_curve).unwrap(); + let _ = gen_point.set_affine_coordinates_gfp( + &c_curve, + &generator_x, + &generator_y, + &mut context, + ); + + let mut pub_point = EcPoint::new(&c_curve).unwrap(); + let _ = pub_point.set_affine_coordinates_gfp( + &c_curve, + &public_key_x, + &public_key_y, + &mut context, + ); + + (c_curve, gen_point, pub_point) + } +} diff --git a/src/main.rs b/src/main.rs index d918138..e890108 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,8 @@ mod cli; fn main() -> Result<()> { let mut args = cli::parse_command_line()?; - let _keys = cli::validate_command_line(&mut args); + let keys = cli::validate_command_line(&mut args)?; + let _cli = cli::Cli::new(args, keys); println!("Hello, world!"); Ok(()) }