bitcoin_hash_toolkit 0.1.0

A toolkit for Bitcoin hashing functions
Documentation

use sha2::{Digest, Sha256};
use ripemd::Ripemd160;
use secp256k1::{Secp256k1, SecretKey, PublicKey};
use secp256k1::rand::rngs::OsRng;
use bs58;

const MAINNET_ADDRESS_PREFIX: u8 = 0x00;

/// Calculates the SHA256 hash of the input data.
pub fn sha256(data: &[u8]) -> Vec<u8> {
    let mut hasher = Sha256::new();
    hasher.update(data);
    hasher.finalize().as_slice().to_vec()
}

/// Calculates the RIPEMD160 hash of the input data.
pub fn ripemd160(data: &[u8]) -> Vec<u8> {
    let mut hasher = Ripemd160::new();
    hasher.update(data);
    hasher.finalize().as_slice().to_vec()
}

/// Calculates HASH160 (SHA256 followed by RIPEMD160), used for addresses.
pub fn hash160(data: &[u8]) -> Vec<u8> {
    let sha_result = sha256(data);
    ripemd160(&sha_result)
}

// src/lib.rs (continuation)



/// Generates a new random secp256k1 private key.
pub fn generate_private_key() -> SecretKey {
    let secp = Secp256k1::new();
    let mut rng = OsRng::default();
    SecretKey::new(&mut rng)
}

/// Derives the compressed public key from a private key.
pub fn derive_public_key(private_key: &SecretKey) -> PublicKey {
    let secp = Secp256k1::new();
    PublicKey::from_secret_key(&secp, private_key)
}

/// Derives the P2PKH Bitcoin address from a compressed public key.
pub fn derive_address(public_key: &PublicKey) -> String {
    // 1. Get the compressed public key bytes
    let pk_bytes = public_key.serialize();
    
    // 2. HASH160 (SHA256 -> RIPEMD160)
    let hash160_result = hash160(&pk_bytes);

    // 3. Prepend the network prefix (0x00 for Mainnet)
    let mut payload: Vec<u8> = vec![MAINNET_ADDRESS_PREFIX];
    payload.extend_from_slice(&hash160_result);

    // 4. Calculate checksum (SHA256(SHA256(payload)))
    let checksum_full = sha256(&sha256(&payload));
    let checksum = &checksum_full[0..4]; // First 4 bytes

    // 5. Append checksum to payload
    payload.extend_from_slice(checksum);

    // 6. Base58Check encode
    bs58::encode(payload).into_string()
}