use bip39::Mnemonic;
use blake2b_simd::Params;
use blst::min_pk::SecretKey as BlsPrivate;
use blst::{
blst_bendian_from_scalar, blst_lendian_from_scalar, blst_scalar, blst_scalar_from_bendian,
blst_scalar_from_lendian, blst_sk_check, BLST_ERROR,
};
use rand::rngs::OsRng;
use rand::RngCore;
use crate::error::Result;
pub fn mnemonic_to_seed(phrase: &str, passphrase: Option<&str>) -> Result<[u8; 64]> {
let mnemonic = Mnemonic::parse(phrase)?;
Ok(mnemonic.to_seed(passphrase.unwrap_or_default()))
}
pub fn new_mnemonic() -> Result<Mnemonic> {
let mut entropy = [0u8; 32];
OsRng.fill_bytes(&mut entropy);
Ok(Mnemonic::from_entropy(&entropy)?)
}
pub fn blake2b_256(data: &[u8]) -> [u8; 32] {
let digest = Params::new()
.hash_length(32)
.to_state()
.update(data)
.finalize();
let mut ret = [0u8; 32];
ret.copy_from_slice(digest.as_bytes());
ret
}
pub fn address_hash(ingest: &[u8]) -> [u8; 20] {
let digest = Params::new()
.hash_length(20)
.to_state()
.update(ingest)
.finalize();
let mut hash = [0u8; 20];
hash.copy_from_slice(digest.as_bytes());
hash
}
pub fn bls_serialize(sk: &BlsPrivate) -> std::result::Result<[u8; 32], BLST_ERROR> {
let sk_in = sk.serialize();
let mut sk = blst_scalar::default();
if sk_in.len() != 32 {
return Err(BLST_ERROR::BLST_BAD_ENCODING);
}
unsafe {
blst_scalar_from_bendian(&mut sk, sk_in.as_ptr());
if !blst_sk_check(&sk) {
return Err(BLST_ERROR::BLST_BAD_ENCODING);
}
}
let mut sk_out = [0; 32];
unsafe {
blst_lendian_from_scalar(sk_out.as_mut_ptr(), &sk);
}
Ok(sk_out)
}
pub fn bls_deserialize(sk_in: &[u8]) -> std::result::Result<BlsPrivate, BLST_ERROR> {
let mut sk = blst_scalar::default();
if sk_in.len() != 32 {
return Err(BLST_ERROR::BLST_BAD_ENCODING);
}
unsafe {
blst_scalar_from_lendian(&mut sk, sk_in.as_ptr());
if !blst_sk_check(&sk) {
return Err(BLST_ERROR::BLST_BAD_ENCODING);
}
}
let mut sk_out = [0; 32];
unsafe {
blst_bendian_from_scalar(sk_out.as_mut_ptr(), &sk);
}
BlsPrivate::deserialize(&sk_out)
}