Skip to content

Instantly share code, notes, and snippets.

@mikedilger
Created March 27, 2025 01:00
Show Gist options
  • Save mikedilger/333fe810b77a919887f1e70a5e3d903f to your computer and use it in GitHub Desktop.
Save mikedilger/333fe810b77a919887f1e70a5e3d903f to your computer and use it in GitHub Desktop.
translate_private_key.rs
use clap::Parser;
use ed25519_dalek::SigningKey;
use ed25519_dalek::pkcs8::{DecodePrivateKey, EncodePrivateKey};
use ed25519_dalek::pkcs8::spki::der::pem::LineEnding;
use std::io::{Read, Write};
use std::ops::Deref;
#[cfg(target_os = "windows")]
const LINE_ENDING: LineEnding = LineEnding::CRLF;
#[cfg(target_os = "macos")]
const LINE_ENDING: LineEnding = LineEnding::CR;
#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
const LINE_ENDING: LineEnding = LineEnding::LF;
#[derive(clap::ValueEnum, Clone, Default, Debug, PartialEq, Eq, Hash)]
enum Format {
Binary,
#[default] Hex,
Pem,
}
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// Input format
#[arg(short, long)]
input: Format,
/// Output format
#[arg(short, long)]
output: Format,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
// Read input
let mut input = String::new();
std::io::stdin().read_to_string(&mut input)?;
// Just copy if formats match
if args.input == args.output {
std::io::stdout().write_all(input.as_bytes())?;
return Ok(());
}
// Translate everything into the dalek type
let signing_key = match args.input {
Format::Binary => {
if input.len() < 32 {
return Err(Box::new(std::io::Error::other("Input is < 32 bytes")));
}
SigningKey::from_bytes(input.as_bytes().try_into().unwrap())
},
Format::Hex => {
if input.len() < 64 {
return Err(Box::new(std::io::Error::other("Input is < 64 bytes")));
}
let bytes = hex::decode(&input[0..64])?;
SigningKey::from_bytes(bytes[0..32].try_into().unwrap())
},
Format::Pem => {
SigningKey::from_pkcs8_pem(&input)?
},
};
match args.output {
Format::Binary => {
std::io::stdout().write_all(signing_key.as_bytes())?;
},
Format::Hex => {
println!("{}", hex::encode(signing_key.as_bytes()));
},
Format::Pem => {
println!("{}", signing_key.to_pkcs8_pem(LINE_ENDING)?.deref());
},
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment