Untitled

 avatar
unknown
rust
a month ago
2.3 kB
6
Indexable
pub fn derive_priv_child(key: ExKey, child_num: u32) -> Result<ExKey,BalanceError> {

    let mut hmac = Hmac::<Sha512>::new_from_slice(&key.chaincode).expect("an error occured");

    let mut data_to_hash = Vec::new();

    if child_num >= 0x80000000 {
        data_to_hash.push(0x00);

        data_to_hash.extend_from_slice(&key.key);


    }else {
        let parent_pub_key = derive_public_key_from_private(&key.key)?;
        data_to_hash.extend_from_slice(&parent_pub_key);

        println!(" normal {:?}",data_to_hash);

    }

    data_to_hash.extend_from_slice(&child_num.to_be_bytes());

    hmac.update(&data_to_hash);

    let result = hmac.finalize().into_bytes();

   

    let (left, right) = result.split_at(32);



        // Convert I_L (left 32 bytes) into a SecretKey
        let il_secret_key = SecretKey::from_slice(left).map_err(|_| BalanceError::RpcCommandError)?;
    
        // Convert the parent private key into a SecretKey
        let parent_secret_key = SecretKey::from_slice(&key.key).map_err(|_| BalanceError::RpcCommandError)?;
    
        // Derive the child private key: child_privkey = (I_L + parent_privkey) mod n
        let child_secret_key = parent_secret_key.add_tweak(&il_secret_key.into()).unwrap();

        let child_key_bytes = child_secret_key.secret_bytes();

        
    
        // The child chain code is I_R (right 32 bytes)
        let mut child_chaincode = [0u8; 32];
        child_chaincode.copy_from_slice(right);
        println!("child {:?}",child_chaincode);

        let parent_pub_key = derive_public_key_from_private(&key.key)?;
        println!("pub {:?}",parent_pub_key);

       let sha_256 = Sha256::digest(parent_pub_key);
       let ripemd_hash = Ripemd160::digest(&sha_256);
       let pubkey_bytes = ripemd_hash.to_vec();

       let child_fingerprint: [u8; 4] = pubkey_bytes[0..4].try_into().expect("Failed to create fingerprint");
       println!("child {:?}", child_fingerprint);

       let mut depth = key.depth;
       depth[0] = depth[0].saturating_add(1);








       return Ok(ExKey {
        version: key.version,
        depth: depth,
        finger_print: child_fingerprint,
        child_number: child_num.to_be_bytes(),
        chaincode:  child_chaincode.try_into().expect("error"),
        key: child_key_bytes
    });


}
Leave a Comment