encrypt, decrypt to/from file
This commit is contained in:
65
src/fileutils.rs
Normal file
65
src/fileutils.rs
Normal 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(())
|
||||
}
|
30
src/main.rs
30
src/main.rs
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user