encrypt, decrypt to/from file

This commit is contained in:
2025-05-19 21:00:38 +02:00
parent e46076355d
commit 23a203ad68
2 changed files with 90 additions and 5 deletions

65
src/fileutils.rs Normal file
View File

@ -0,0 +1,65 @@
use crate::dghv_asym::{PrivateKey, PublicKey};
use rug::Integer;
use std::fs::{read_to_string, File};
use std::io::{self, Read, Write};
use std::path::Path;
pub fn write_privkey<P: AsRef<Path>>(prefix: P, sk: &PrivateKey) -> io::Result<()> {
let mut file = File::create(prefix.as_ref().with_extension("privkey"))?;
let mut hex = sk.p.to_string_radix(16);
if hex.len() % 2 != 0 {
hex.insert(0, '0');
}
writeln!(file, "{}", hex)?;
Ok(())
}
pub fn write_pubkey<P: AsRef<Path>>(prefix: P, pk: &PublicKey) -> io::Result<()> {
let mut file = File::create(prefix.as_ref().with_extension("pubkey"))?;
for x in &pk.xs {
let mut hex = x.to_string_radix(16);
if hex.len() % 2 != 0 {
hex.insert(0, '0');
}
writeln!(file, "{}", hex)?;
}
Ok(())
}
pub fn read_privkey<P: AsRef<Path>>(path: P) -> io::Result<PrivateKey> {
let hex = std::fs::read_to_string(path)?;
let hex = hex.trim();
let p = Integer::from_str_radix(hex, 16)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
Ok(PrivateKey { p })
}
pub fn read_pubkey<P: AsRef<Path>>(path: P) -> io::Result<PublicKey> {
let mut xs = Vec::new();
let content = {
let mut s = String::new();
File::open(path)?.read_to_string(&mut s)?;
s
};
for line in content.lines() {
// each line is a hex-encoded key
let bytes =
hex::decode(line.trim()).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
let hex = hex::encode(bytes);
let x = Integer::from_str_radix(&hex, 16)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
xs.push(x);
}
Ok(PublicKey { xs })
}
pub fn read_hex_from_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
let content = read_to_string(path)?;
Ok(content.trim().to_string())
}
pub fn write_hex_to_file<P: AsRef<Path>>(path: P, hex_str: &str) -> io::Result<()> {
let mut file = File::create(path)?;
writeln!(file, "{}", hex_str)?;
Ok(())
}

View File

@ -5,7 +5,9 @@ mod fileutils;
mod utils;
use crate::dghv::{decrypt_bit, encrypt_bit, generate_secret_key};
use crate::dghv_asym::{encrypt_bit_asym, generate_keys};
use crate::fileutils::{read_privkey, read_pubkey, write_privkey, write_pubkey};
use crate::fileutils::{
read_hex_from_file, read_privkey, read_pubkey, write_hex_to_file, write_privkey, write_pubkey,
};
use clap::{ArgGroup, Args, Parser, Subcommand};
use rug::Integer;
@ -64,14 +66,21 @@ struct EncryptArgs {
/// noise parameter
#[arg(short = 'n', long, default_value_t = 80)]
noise: u32,
/// optional output file for ciphertext (hex-encoded)
#[arg(short = 'o', long)]
output: Option<String>,
}
#[derive(Args)]
#[command(group(ArgGroup::new("keysource").required(true).args(&["key", "privkey"])))]
#[command(group(ArgGroup::new("cipher_source").required(true).args(&["ciphertext", "file"])))]
struct DecryptArgs {
/// ciphertext to decrypt (hex-encoded)
/// ciphertext hex string
#[arg(short = 'c', long)]
ciphertext: String,
ciphertext: Option<String>,
/// path to ciphertext file
#[arg(short = 'f', long)]
file: Option<String>,
/// key as hex string
#[arg(short = 'k', long)]
key: Option<String>,
@ -102,9 +111,21 @@ fn main() {
};
encrypt_bit(args.bit, &p, args.noise, args.noise)
};
println!("Encrypted bit (hex): {}", ct.to_string_radix(16));
let hexct = ct.to_string_radix(16);
if let Some(outfile) = args.output {
write_hex_to_file(outfile, &hexct).expect("Failed to write ciphertext to file");
} else {
println!("Encrypted bit (hex): {}", hexct);
}
}
Commands::Decrypt(args) => {
let ct_hex = if let Some(hex_str) = args.ciphertext {
hex_str
} else {
read_hex_from_file(args.file.clone().unwrap())
.expect("Failed to read ciphertext file")
};
let ct = Integer::from_str_radix(&ct_hex, 16).expect("Invalid ciphertext");
let p = if let Some(hex_str) = args.key {
Integer::from_str_radix(&hex_str, 16).expect("Invalid key hex")
} else {
@ -112,7 +133,6 @@ fn main() {
.expect("Failed to load private key")
.p
};
let ct = Integer::from_str_radix(&args.ciphertext, 16).expect("Invalid ciphertext");
let res = decrypt_bit(&ct, &p);
println!("Decrypted bit: {}", res);
}