Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to generate new random key pairs #11

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true
},
}
67 changes: 67 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ anyhow = "1.0.69"
bech32 = "0.9.1"
clap = { version = "4.1.4", features = ["derive"] }
hex = "0.4.3"
rand = "0.8.5"
regex = {version = "1.7.1", features = ["std", "unicode-case"], default-features = false}
reqwest = { version = "0.11.14", features = ["json", "rustls-tls"], default-features=false }
rustls = "0.20.8"
secp256k1 = "0.26.0"
serde = { version = "1.0.152", features = ["derive"] }
thiserror = "1.0"
tokio = { version = "1.25.0", features = ["macros", "rt", "rt-multi-thread"], default-features = false }
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This is kind of bonkers, so here's a command-line utility that you can run to co

## Features:
>Note: "keys" + "nip5" arguments accept multiple inputs for bulk operations
- generate new random keypair
- convert from bech32 (npub/nsec/note) to hex
- convert from hex to bech32 (npub/nsec/note)
- supports NIP-05 domain identifiers:
Expand Down Expand Up @@ -45,6 +46,17 @@ Just provide the hex-encoded key or note-id and a `--kind` argument. The `kind`s
- nsec
- note

To generate a `new random keypair`, you can do

```shell
$> key-convertr --gen-keys

Hex Public Key: c2366301f37d8aad12ab316971dcc30da849a79a7888051b0a8b0756e606421e
Hex Secret Key: dd115775e70e97a5f130c7587046aac3a690145b087e70faaba7c88d57ff578d
Bech32 Public Key: npub1cgmxxq0n0k926y4tx95hrhxrpk5ynfu60zyq2xc23vr4desxgg0qxffg34
Bech32 Secret Key: nsec1m5g4wa08p6t6tufscav8q342cwnfq9zmppl8p74t5lyg64ll27xs27mn0y
```

To convert from an `bech32(npub/nsec/note) to hex-encoding`, you can do

```shell
Expand Down
36 changes: 35 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use anyhow::Result;
use bech32::{FromBase32, ToBase32, Variant};
use clap::error::ErrorKind;
use clap::{command, ArgGroup, CommandFactory, Parser};
use rand::rngs::OsRng;
use rand::RngCore;
use regex::Regex;
use secp256k1::{PublicKey, Secp256k1, SecretKey};
use serde::{Deserialize, Serialize};
use thiserror::Error;

Expand Down Expand Up @@ -39,7 +42,7 @@ struct Nip5Id {
// input error handling: only exactly ONE of 'n' args can be used
ArgGroup::new("convert_method")
.required(true)
.args(&["kind", "to_hex", "nip5"]),
.args(&["kind", "to_hex", "nip5", "gen_keys"]),
))]
struct Args {
#[arg(
Expand Down Expand Up @@ -79,6 +82,12 @@ struct Args {
help = "nip5 identifiers stats logging"
)]
nip_stats: bool,

#[arg(
long,
help = "boolean flag indicating to generate new keys and print them in hex and bech32 format"
)]
gen_keys: bool,
}

#[tokio::main]
Expand Down Expand Up @@ -112,6 +121,31 @@ async fn main() -> Result<()> {
}
}
Ok(())
} else if args.gen_keys {
// Generate keys and print them in hex and bech32 format
let secp = Secp256k1::new();

let mut bytes = [0u8; 32];
let mut rng = OsRng;

rng.try_fill_bytes(&mut bytes).unwrap();

// Generate a secret key from random bytes
let secret_key = SecretKey::from_slice(&bytes).expect("Error generating secret key");

// Derive the corresponding public key
let (pubkey, _) = PublicKey::from_secret_key(&secp, &secret_key).x_only_public_key();
let hex_pubkey = hex::encode(pubkey.serialize());
let hex_secret_key = hex::encode(&secret_key[..]);

let bech32_pubkey = bech32_encode(Prefix::Npub, &hex_pubkey);
let bech32_secret_key = bech32_encode(Prefix::Nsec, &hex_secret_key);

println!("Hex Public Key: {}", hex_pubkey);
println!("Hex Secret Key: {}", hex_secret_key);
println!("Bech32 Public Key: {}", bech32_pubkey);
println!("Bech32 Secret Key: {}", bech32_secret_key);
Ok(())
} else {
Err(
Args::command() // in the event of an args bug, this will print an error and exit
Expand Down