diff --git a/src/bink1998.rs b/src/bink1998.rs index 1cee8a1..8d396c6 100644 --- a/src/bink1998.rs +++ b/src/bink1998.rs @@ -75,12 +75,12 @@ pub fn generate( todo!() } -fn unpack(p_raw: &[u8]) -> Result { - const HASH_LENGTH_BITS: u8 = 28; - const SERIAL_LENGTH_BITS: u8 = 30; - const UPGRADE_LENGTH_BITS: u8 = 1; - const EVERYTHING_ELSE: u8 = HASH_LENGTH_BITS + SERIAL_LENGTH_BITS + UPGRADE_LENGTH_BITS; +const HASH_LENGTH_BITS: u8 = 28; +const SERIAL_LENGTH_BITS: u8 = 30; +const UPGRADE_LENGTH_BITS: u8 = 1; +const EVERYTHING_ELSE: u8 = HASH_LENGTH_BITS + SERIAL_LENGTH_BITS + UPGRADE_LENGTH_BITS; +fn unpack(p_raw: &[u8]) -> Result { let mut reader = BitReader::new(p_raw); // The signature length is unknown, but everything else is, so we can calculate it let signature_length_bits = (p_raw.len() * 8) as u8 - EVERYTHING_ELSE; @@ -99,7 +99,18 @@ fn unpack(p_raw: &[u8]) -> Result { } fn pack(p_key: ProductKey) -> Vec { - todo!() + let mut p_raw: u128 = 0; + + p_raw |= (p_key.signature as u128) << EVERYTHING_ELSE; + p_raw |= (p_key.hash as u128) << (SERIAL_LENGTH_BITS + UPGRADE_LENGTH_BITS); + p_raw |= (p_key.serial as u128) << UPGRADE_LENGTH_BITS; + p_raw |= p_key.upgrade as u128; + + p_raw + .to_be_bytes() + .into_iter() + .skip_while(|&x| x == 0) + .collect() } #[cfg(test)] @@ -111,7 +122,7 @@ mod tests { use crate::crypto::initialize_elliptic_curve; #[test] - fn test() { + fn verify_test() { // Example product key and its BINK ID let product_key = "D9924-R6BG2-39J83-RYKHF-W47TT"; let bink_id = "2E"; @@ -136,4 +147,23 @@ mod tests { assert!(super::verify(&e_curve, &gen_point, &pub_point, product_key).unwrap()); } + + #[test] + fn pack_test() { + let p_key = super::ProductKey { + upgrade: false, + serial: 640010550, + hash: 39185432, + signature: 6939952665262054, + }; + + let p_raw = super::pack(p_key); + + assert_eq!( + p_raw, + vec![ + 0xC5, 0x3E, 0xCD, 0x2A, 0xF7, 0xBF, 0x31, 0x2A, 0xF6, 0x0C, 0x4C, 0x4B, 0x92, 0x6C + ] + ); + } } diff --git a/src/crypto.rs b/src/crypto.rs index 9476fcb..ce406c3 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,5 +1,5 @@ use openssl::{ - bn::BigNum, + bn::{BigNum, BigNumContext}, ec::{EcGroup, EcPoint}, }; @@ -12,7 +12,7 @@ pub fn initialize_elliptic_curve( public_key_x_sel: &str, public_key_y_sel: &str, ) -> (EcGroup, EcPoint, EcPoint) { - let mut context = openssl::bn::BigNumContext::new().unwrap(); + let mut context = BigNumContext::new().unwrap(); let p = BigNum::from_dec_str(p_sel).unwrap(); let a = BigNum::from_dec_str(a_sel).unwrap();