<- Advertisement ->
I am instructing myself ECC utilizing the secp256k1 curve. In the end I am occupied with studying about Schnorr signature aggregation and MuSig protocols, however I am ranging from the bottom up.
I’ve tried to calculate the general public key given a personal key, however the public key that I calculate is completely different than the one which libsecp returns. Perhaps I am getting byte ordering mistaken someplace, or I’m misunderstanding when to make use of modulus. Can somebody level out the place my logical error is?
use num_bigint::BigUint;
use rand::Fill;
use secp256k1::{Secp256k1, SecretKey};
fn major() {
let secp = Secp256k1::new();
let sk = private_key();
let sk = SecretKey::from_slice(&sk.to_bytes_be()).unwrap();
let pk = sk.public_key(&secp);
println!("Public Key: {}", hex::encode(pk.serialize_uncompressed()));
}
fn private_key() -> BigUint {
// Generate a random 32-byte personal key
let mut private_key_bytes: [u8; 32] = [0; 32];
private_key_bytes.try_fill(&mut rand::thread_rng()).unwrap();
// Convert the personal key bytes to a BigUint
let private_key = num_bigint::BigUint::from_bytes_be(&private_key_bytes);
// Curve parameters for secp256k1
let p = BigUint::from_bytes_be(&secp256k1::constants::FIELD_SIZE);
let n = BigUint::from_bytes_be(&secp256k1::constants::CURVE_ORDER);
let g_x = BigUint::from_bytes_be(&secp256k1::constants::GENERATOR_X);
let g_y = BigUint::from_bytes_be(&secp256k1::constants::GENERATOR_Y);
// Make sure the personal secret's throughout the legitimate vary
let private_key = private_key % &n;
// Compute the corresponding public key utilizing scalar multiplication
let public_key_x = (g_x * &private_key) % &p;
let public_key_y = (g_y * &private_key) % &p;
// Encode the general public key
let public_key_encoding = format!(
"04{:064}{:064}",
hex::encode(public_key_x.to_bytes_be()),
hex::encode(public_key_y.to_bytes_be())
);
println!("Personal key: {:?}", private_key);
println!("Public key: {}", public_key_encoding);
private_key
}