secp256k1 – Why is my manually calculated public key totally different than libsecp?

0
52


I am instructing myself ECC utilizing the secp256k1 curve. Finally I am involved in 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 totally different than the one which libsecp returns. Possibly 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 fundamental() {
    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 non-public key
    let mut private_key_bytes: [u8; 32] = [0; 32];
    private_key_bytes.try_fill(&mut rand::thread_rng()).unwrap();

    // Convert the non-public 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 non-public secret's inside 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!("Non-public key: {:?}", private_key);
    println!("Public key: {}", public_key_encoding);

    private_key
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here