use k256::elliptic_curve::point::AffineCoordinates;
use k256::elliptic_curve::sec1::ToEncodedPoint;
use k256::{ProjectivePoint, Scalar, SecretKey};
use rand::rngs::OsRng;
use crate::types::{scalar_to_hex, KeyPairHex};
use crate::utils::random_non_zero_scalar;
const GENERATOR: ProjectivePoint = ProjectivePoint::GENERATOR;
pub fn generate_keypair_hex(format: &str) -> KeyPairHex {
let os_rng = OsRng;
let secret_scalar_nonzero = random_non_zero_scalar(os_rng);
let secret_key = SecretKey::from(secret_scalar_nonzero);
let secret_scalar: Scalar = *secret_scalar_nonzero.as_ref(); let private_key_hex = scalar_to_hex(&secret_scalar);
let public_key = secret_key.public_key();
let mut point = public_key.to_projective();
let public_key_hex = match format {
"xonly" => {
let affine = point.to_affine();
let y_is_odd = affine.y_is_odd();
if y_is_odd.into() {
let flipped_scalar = secret_scalar.negate();
point = GENERATOR * flipped_scalar;
}
let final_affine = point.to_affine();
hex::encode(final_affine.x().as_slice())
}
"uncompressed" => hex::encode(point.to_encoded_point(false).as_bytes()),
"compressed" => hex::encode(point.to_encoded_point(true).as_bytes()),
_ => hex::encode(point.to_encoded_point(true).as_bytes()),
};
KeyPairHex {
private_key_hex,
public_key_hex,
}
}
pub fn generate_keypairs(count: usize, format: &str) -> Vec<KeyPairHex> {
(0..count).map(|_| generate_keypair_hex(format)).collect()
}
pub fn get_public_keys(keypairs: &[KeyPairHex]) -> Vec<String> {
keypairs
.iter()
.map(|kp| kp.public_key_hex.clone())
.collect()
}