use pkcs8::der::Decode;
use pkcs8::{EncryptedPrivateKeyInfo, PrivateKeyInfo};
use pkcs8::pkcs5::scrypt::Params;
use secp256k1::{Secp256k1, SecretKey};
use rand::{rng, RngCore};
//
// OID for secp256k1 curve
const SECP256K1_OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.3.132.0.10");

fn generate_salt() -> [u8; 16] {
  let mut salt = [0u8; 16];
  rng().fill_bytes(&mut salt);
  salt
}

fn main() {
  let secp = Secp256k1::new();
  let (secret_key, public_key) = secp.generate_keypair(&mut rand::rng());

  let password = "test";

  let secret_bytes = &secret_key.secret_bytes();
  let pk_info = PrivateKeyInfo::new(
    pkcs8::AlgorithmIdentifierRef {
      oid: SECP256K1_OID,
      parameters: None,
    },
    secret_bytes
  );

  println!("private key length: {}", secret_bytes.len());

  let salt = generate_salt();

  let enc_priv = pk_info.encrypt_with_params(
    pkcs8::pkcs5::pbes2::Parameters::scrypt_aes256cbc(
      Params::new(15, 8, 1, secret_bytes.len()).unwrap(),
      &salt,
      &salt
    ).unwrap(),
    password
  ).unwrap();

  &enc_priv.write_der_file("./out.der").unwrap();
  let buf = std::fs::read("./out.der").unwrap();

  let enc_key = EncryptedPrivateKeyInfo::from_der(buf.as_slice()).unwrap();
  let dec_doc = enc_key.decrypt(password.as_bytes()).unwrap();
  let dec_key = PrivateKeyInfo::from_der(dec_doc.as_bytes()).unwrap();

  dbg!(&dec_key);

  let sec_key_bytes = dec_key.private_key;
  let mut sec_key_bytes = [0u8; 32];
  sec_key_bytes.copy_from_slice(dec_key.private_key);
  let sec_key = SecretKey::from_byte_array(sec_key_bytes);
  println!("original key: {:#?}", secret_key);
  println!("decrypted key: {:#?}", sec_key);
}
