Compare commits
3 Commits
0119e58d2d
...
de6d8e4b56
Author | SHA1 | Date |
---|---|---|
Ryan Heywood | de6d8e4b56 | |
Ryan Heywood | 4e83be47c0 | |
Ryan Heywood | 55ff62052b |
|
@ -865,9 +865,8 @@ name = "keyfork"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"keyfork-derive-key",
|
|
||||||
"keyfork-entropy",
|
"keyfork-entropy",
|
||||||
"keyfork-mnemonic-from-seed",
|
"keyfork-mnemonic-util",
|
||||||
"smex",
|
"smex",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -876,17 +875,10 @@ dependencies = [
|
||||||
name = "keyfork-derive-key"
|
name = "keyfork-derive-key"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
|
||||||
"clap",
|
|
||||||
"ed25519-dalek",
|
|
||||||
"keyfork-derive-util",
|
"keyfork-derive-util",
|
||||||
"keyfork-frame",
|
|
||||||
"keyfork-slip10-test-data",
|
|
||||||
"keyforkd",
|
|
||||||
"keyforkd-client",
|
"keyforkd-client",
|
||||||
"tempdir",
|
"smex",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -6,16 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bincode = { version = "1.3.3", default-features = false }
|
|
||||||
clap = { version = "4.4.2", default-features = false, features = ["std", "usage", "help", "derive"] }
|
|
||||||
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util" }
|
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util" }
|
||||||
keyfork-frame = { version = "0.1.0", path = "../keyfork-frame", default-features = false }
|
|
||||||
keyforkd-client = { version = "0.1.0", path = "../keyforkd-client" }
|
keyforkd-client = { version = "0.1.0", path = "../keyforkd-client" }
|
||||||
|
smex = { version = "0.1.0", path = "../smex" }
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
ed25519-dalek = "2.0.0"
|
|
||||||
keyfork-slip10-test-data = { path = "../keyfork-slip10-test-data" }
|
|
||||||
keyforkd = { path = "../keyforkd", default-features = false }
|
|
||||||
tempdir = "0.3.7"
|
|
||||||
tokio = { version = "1.32.0", features = ["rt", "rt-multi-thread"] }
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
use clap::Parser;
|
|
||||||
use keyfork_derive_util::{
|
|
||||||
request::{DerivationAlgorithm, DerivationRequest, DerivationResponse},
|
|
||||||
DerivationPath,
|
|
||||||
};
|
|
||||||
use keyforkd_client::{Client, Result};
|
|
||||||
|
|
||||||
#[derive(Parser, Clone, Debug)]
|
|
||||||
pub struct Command {
|
|
||||||
#[arg(long)]
|
|
||||||
pub path: DerivationPath,
|
|
||||||
|
|
||||||
#[arg(long)]
|
|
||||||
pub algorithm: DerivationAlgorithm,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Command {
|
|
||||||
pub fn handle(&self) -> Result<DerivationResponse> {
|
|
||||||
let mut client = Client::discover_socket()?;
|
|
||||||
let request = DerivationRequest::new(self.algorithm.clone(), &self.path);
|
|
||||||
client.request(&request)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
pub mod cli;
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("The first argument to the command should be a derivation path")]
|
|
||||||
Args,
|
|
||||||
|
|
||||||
#[error("The given path was incorrectly formatted: {0}")]
|
|
||||||
ArgsFormat(#[from] keyfork_derive_util::path::Error),
|
|
||||||
|
|
||||||
#[error("Unable to perform key derivation request: {0}")]
|
|
||||||
KeyforkdClient(#[from] keyforkd_client::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|
|
@ -1,10 +1,44 @@
|
||||||
use clap::Parser;
|
use std::{env, str::FromStr};
|
||||||
|
|
||||||
#[allow(clippy::wildcard_imports)]
|
use keyfork_derive_util::{
|
||||||
use keyfork_derive_key::*;
|
request::{DerivationAlgorithm, DerivationError, DerivationRequest},
|
||||||
|
DerivationPath,
|
||||||
|
};
|
||||||
|
use keyforkd_client::Client;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
#[derive(Debug, thiserror::Error)]
|
||||||
let args = cli::Command::parse();
|
pub enum Error {
|
||||||
args.handle()?;
|
#[error("Could not parse the given algorithm {0:?}: {1}")]
|
||||||
|
AlgoFormat(String, DerivationError),
|
||||||
|
|
||||||
|
#[error("Could not parse the given path: {0}")]
|
||||||
|
PathFormat(#[from] keyfork_derive_util::path::Error),
|
||||||
|
|
||||||
|
#[error("Unable to perform key derivation request: {0}")]
|
||||||
|
KeyforkdClient(#[from] keyforkd_client::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
||||||
|
fn validate(algo: &str, path: &str) -> Result<(DerivationAlgorithm, DerivationPath)> {
|
||||||
|
let algo =
|
||||||
|
DerivationAlgorithm::from_str(algo).map_err(|e| Error::AlgoFormat(algo.to_string(), e))?;
|
||||||
|
let path = DerivationPath::from_str(path)?;
|
||||||
|
Ok((algo, path))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut args = env::args();
|
||||||
|
let program_name = args.next().expect("program name");
|
||||||
|
let args = args.collect::<Vec<_>>();
|
||||||
|
let (algo, path) = match args.as_slice() {
|
||||||
|
[algo, path] => validate(algo, path)?,
|
||||||
|
_ => panic!("Usage: {program_name} algorithm path"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut client = Client::discover_socket()?;
|
||||||
|
let request = DerivationRequest::new(algo, &path);
|
||||||
|
let response = client.request(&request)?;
|
||||||
|
println!("{}", smex::encode(&response.data));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,11 @@
|
||||||
use std::{
|
use std::{env, str::FromStr};
|
||||||
env,
|
|
||||||
str::FromStr,
|
|
||||||
time::{Duration, SystemTime},
|
|
||||||
};
|
|
||||||
|
|
||||||
use ed25519_dalek::SigningKey;
|
|
||||||
use keyfork_derive_util::{
|
use keyfork_derive_util::{
|
||||||
request::{DerivationAlgorithm, DerivationRequest},
|
request::{DerivationAlgorithm, DerivationRequest},
|
||||||
DerivationIndex, DerivationPath, ExtendedPrivateKey, PrivateKey,
|
DerivationIndex, DerivationPath,
|
||||||
};
|
};
|
||||||
use keyforkd_client::Client;
|
use keyforkd_client::Client;
|
||||||
use sequoia_openpgp::{
|
use sequoia_openpgp::{packet::UserID, types::KeyFlags};
|
||||||
packet::{
|
|
||||||
key::{Key4, PrimaryRole, SubordinateRole},
|
|
||||||
signature::SignatureBuilder,
|
|
||||||
Key, UserID,
|
|
||||||
},
|
|
||||||
types::{KeyFlags, SignatureType},
|
|
||||||
Cert, Packet,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
enum Error {
|
enum Error {
|
||||||
|
@ -121,7 +108,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let request = DerivationRequest::new(DerivationAlgorithm::Ed25519, &path);
|
let request = DerivationRequest::new(DerivationAlgorithm::Ed25519, &path);
|
||||||
let derived_data = Client::discover_socket()?.request(&request)?;
|
let derived_data = Client::discover_socket()?.request(&request)?;
|
||||||
let subkeys = subkey_format.iter().map(|kt| kt.inner().clone()).collect::<Vec<_>>();
|
let subkeys = subkey_format
|
||||||
|
.iter()
|
||||||
|
.map(|kt| kt.inner().clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let cert = keyfork_derive_openpgp::derive(derived_data, subkeys.as_slice(), default_userid)?;
|
let cert = keyfork_derive_openpgp::derive(derived_data, subkeys.as_slice(), default_userid)?;
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
use keyfork_mnemonic_util::{Mnemonic, MnemonicGenerationError, Wordlist};
|
|
||||||
|
|
||||||
pub fn generate_mnemonic(entropy: &[u8]) -> Result<Mnemonic, MnemonicGenerationError> {
|
|
||||||
let wordlist = Wordlist::default().arc();
|
|
||||||
Mnemonic::from_entropy(entropy, wordlist)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use keyfork_mnemonic_util::{Mnemonic, Wordlist};
|
|
||||||
use std::{collections::HashSet, io::Read};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn count_to_get_duplicate_words() {
|
|
||||||
let tests = 100_000;
|
|
||||||
let mut count = 0.;
|
|
||||||
let entropy = &mut [0u8; 256 / 8];
|
|
||||||
let wordlist = Wordlist::default().arc();
|
|
||||||
let mut random = std::fs::File::open("/dev/urandom").unwrap();
|
|
||||||
let mut hs = HashSet::<usize>::with_capacity(24);
|
|
||||||
|
|
||||||
for _ in 0..tests {
|
|
||||||
random.read_exact(&mut entropy[..]).unwrap();
|
|
||||||
let mnemonic = Mnemonic::from_entropy(&entropy[..256 / 8], wordlist.clone()).unwrap();
|
|
||||||
let (words, _) = mnemonic.into_inner();
|
|
||||||
hs.clear();
|
|
||||||
hs.extend(words);
|
|
||||||
if hs.len() != 24 {
|
|
||||||
count += 1.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Birthday problem math is: 0.126532
|
|
||||||
// Set values to (about) 1 below, 1 above
|
|
||||||
// Source: https://en.wikipedia.org/wiki/Birthday_problem
|
|
||||||
let min = 11.5;
|
|
||||||
let max = 13.5;
|
|
||||||
assert!(
|
|
||||||
count > f64::from(tests) * min / 100.,
|
|
||||||
"{count} probability should be more than {min}%: {}",
|
|
||||||
count / f64::from(tests)
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
count < f64::from(tests) * max / 100.,
|
|
||||||
"{count} probability should be more than {max}%: {}",
|
|
||||||
count / f64::from(tests)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
#[allow(clippy::wildcard_imports)]
|
use keyfork_mnemonic_util::Mnemonic;
|
||||||
use keyfork_mnemonic_from_seed::*;
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let input = std::io::stdin();
|
let input = std::io::stdin();
|
||||||
|
@ -7,7 +6,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
input.read_line(&mut line)?;
|
input.read_line(&mut line)?;
|
||||||
let decoded = smex::decode(line.trim())?;
|
let decoded = smex::decode(line.trim())?;
|
||||||
|
|
||||||
let mnemonic = generate_mnemonic(&decoded)?;
|
let mnemonic = Mnemonic::from_entropy(&decoded, Default::default())?;
|
||||||
|
|
||||||
println!("{mnemonic}");
|
println!("{mnemonic}");
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -225,7 +225,7 @@ impl Mnemonic {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{fs::File, io::Read};
|
use std::{collections::HashSet, fs::File, io::Read};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -278,4 +278,41 @@ mod tests {
|
||||||
let their_mnemonic = bip39::Mnemonic::from_entropy(&entropy[..256 / 8]).unwrap();
|
let their_mnemonic = bip39::Mnemonic::from_entropy(&entropy[..256 / 8]).unwrap();
|
||||||
assert_eq!(my_mnemonic.to_string(), their_mnemonic.to_string());
|
assert_eq!(my_mnemonic.to_string(), their_mnemonic.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_to_get_duplicate_words() {
|
||||||
|
let tests = 100_000;
|
||||||
|
let mut count = 0.;
|
||||||
|
let entropy = &mut [0u8; 256 / 8];
|
||||||
|
let wordlist = Wordlist::default().arc();
|
||||||
|
let mut random = std::fs::File::open("/dev/urandom").unwrap();
|
||||||
|
let mut hs = HashSet::<usize>::with_capacity(24);
|
||||||
|
|
||||||
|
for _ in 0..tests {
|
||||||
|
random.read_exact(&mut entropy[..]).unwrap();
|
||||||
|
let mnemonic = Mnemonic::from_entropy(&entropy[..256 / 8], wordlist.clone()).unwrap();
|
||||||
|
let (words, _) = mnemonic.into_inner();
|
||||||
|
hs.clear();
|
||||||
|
hs.extend(words);
|
||||||
|
if hs.len() != 24 {
|
||||||
|
count += 1.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Birthday problem math is: 0.126532
|
||||||
|
// Set values to (about) 1 below, 1 above
|
||||||
|
// Source: https://en.wikipedia.org/wiki/Birthday_problem
|
||||||
|
let min = 11.5;
|
||||||
|
let max = 13.5;
|
||||||
|
assert!(
|
||||||
|
count > f64::from(tests) * min / 100.,
|
||||||
|
"{count} probability should be more than {min}%: {}",
|
||||||
|
count / f64::from(tests)
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
count < f64::from(tests) * max / 100.,
|
||||||
|
"{count} probability should be more than {max}%: {}",
|
||||||
|
count / f64::from(tests)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,8 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
keyfork-entropy = { version = "0.1.0", path = "../keyfork-entropy" }
|
||||||
|
keyfork-mnemonic-util = { version = "0.1.0", path = "../keyfork-mnemonic-util" }
|
||||||
clap = { version = "4.4.2", features = ["derive", "env"] }
|
clap = { version = "4.4.2", features = ["derive", "env"] }
|
||||||
keyfork-mnemonic-from-seed = { version = "0.1.0", path = "../keyfork-mnemonic-from-seed" }
|
|
||||||
keyfork-derive-key = { version = "0.1.0", path = "../keyfork-derive-key" }
|
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
smex = { version = "0.1.0", path = "../smex" }
|
smex = { version = "0.1.0", path = "../smex" }
|
||||||
keyfork-entropy = { version = "0.1.0", path = "../keyfork-entropy" }
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl MnemonicSeedSource {
|
||||||
MnemonicSeedSource::Tarot => todo!(),
|
MnemonicSeedSource::Tarot => todo!(),
|
||||||
MnemonicSeedSource::Dice => todo!(),
|
MnemonicSeedSource::Dice => todo!(),
|
||||||
};
|
};
|
||||||
let mnemonic = keyfork_mnemonic_from_seed::generate_mnemonic(&seed)?;
|
let mnemonic = keyfork_mnemonic_util::Mnemonic::from_entropy(&seed, Default::default())?;
|
||||||
Ok(mnemonic.to_string())
|
Ok(mnemonic.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue