hsc/
lib.rs

1#![feature(macro_metavar_expr)]
2
3use std::path::Path;
4
5use aok::{Error, Result, OK};
6use blake3::Hasher;
7use ed25519_dalek::{Signer, SigningKey, SECRET_KEY_LENGTH};
8use rand::rngs::OsRng;
9use tokio::{
10  fs::{write, File},
11  io::AsyncReadExt,
12};
13// use trt::join;
14
15pub async fn key(key: impl AsRef<Path>, create: bool) -> Result<SigningKey> {
16  let key = key.as_ref();
17  match File::open(key).await {
18    Ok(mut k) => {
19      let mut signing_key_bytes: [u8; SECRET_KEY_LENGTH] = Default::default();
20      k.read_exact(&mut signing_key_bytes).await?;
21      Ok::<_, Error>(SigningKey::from_bytes(&signing_key_bytes))
22    }
23    Err(err) => {
24      if create && err.kind() == tokio::io::ErrorKind::NotFound {
25        let mut csprng = OsRng;
26        let signing_key: SigningKey = SigningKey::generate(&mut csprng);
27
28        let key_str = key.as_os_str().to_string_lossy();
29        let pk_fp = if key_str.ends_with(".sk") {
30          key_str[..key_str.len() - 2].to_owned() + "pk"
31        } else {
32          (key_str + ".pk").into()
33        };
34        write(pk_fp, signing_key.verifying_key().as_bytes()).await?;
35        write(key, signing_key.as_bytes()).await?;
36        Ok(signing_key)
37      } else {
38        Err(err.into())
39      }
40    }
41  }
42}
43
44pub async fn hsc(fp: impl AsRef<Path>, key: SigningKey) -> Result<()> {
45  let fp = fp.as_ref();
46  let hash: Hasher = ifs::hash(fp).await?;
47  let hash = hash.finalize();
48  let sign = key.sign(hash.as_bytes()).to_bytes();
49  // let mut b3 = fp.to_owned().into_os_string();
50  // b3.push(".b3");
51  let mut hsc = fp.to_owned().into_os_string();
52  hsc.push(".hsc");
53  write(hsc, sign).await?;
54  /*
55  use ed25519_dalek::Verifier;
56  let verifying_key = key.verifying_key();
57  let r = verifying_key.verify(&hash, &Signature::from_bytes(&sign));
58  */
59  OK
60}