plexcryptool/src/main.rs

237 lines
7.4 KiB
Rust

#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]
//!
//! This is a mixed rust/python library that also offers an executable.
//! The intended usage is the solving of tasks for cryptology and maybe math, in the context of a
//! # various tools for use in cryptology contexts
//! university degree. I wrote this for cryptology at DHBW Mannheim.
//!
//! ## main function
//! This project contains an executable, see [main.rs](main.rs)
//!
//! ## lib module
//! This project contains is a library, see [lib.rs](lib.rs).
//! Note that this library offers Python bindings using [PyO3](pyo3.rs)
//! ___
//! Author: Christoph J. Scherr <software@cscherr.de>
//!
//! License: MIT
//!
//! Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
mod binary;
mod math;
mod algo;
mod common;
use std::{str::FromStr, fmt::Debug};
use clap::{Args, Parser, Subcommand};
use clap_num::maybe_hex;
use num_bigint;
/*************************************************************************************************/
// This is just structures for parsing Cli args
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// Which submodule to use
#[command(subcommand)]
command: Commands,
/// Machine output
#[arg(short, long, default_value_t = false, global = true)]
machine: bool,
/// Verbose output
#[arg(short, long, default_value_t = false, global = true)]
verbose: bool,
}
#[derive(Subcommand, Debug)]
enum Commands {
/// Use math functions
Math(MathCommand),
/// Use binary functions
Binary(BinaryCommand),
/// Use custom algorithms
Algo(AlgoCommand),
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct MathCommand {
#[command(subcommand)]
action: MathActions
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct BinaryCommand {
#[command(subcommand)]
action: BinaryActions
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct AlgoCommand {
#[command(subcommand)]
action: AlgoActions
}
#[derive(Subcommand, Clone, Debug, PartialEq, Eq)]
enum MathActions {
#[command(name="modexp")]
Modexp(ModexpArgs),
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct ModexpArgs {
base: String,
exp: String,
field: String
}
#[derive(Subcommand, Clone, Debug, PartialEq, Eq)]
enum BinaryActions {
/// bit rotation/circular shifting (only 32bit)
#[command(name="rotate")]
Rotate(RotateArgs),
Xor(XorArgs)
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct RotateArgs {
#[arg(short, long, default_value_t = false)]
left: bool,
base: u32,
shift_width: u32,
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct XorArgs {
a: u128,
b: u128,
}
#[derive(Subcommand, Clone, Debug, PartialEq, Eq)]
enum AlgoActions {
#[command(name="feistel0-i")]
Feistel0Inner(Feistel0InnerArgs),
#[command(name="feistel0-sbox")]
Feistel0SBOX(Feistel0SBOXArgs),
#[command(name="feistel0")]
Feistel0(Feistel0Args)
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct Feistel0InnerArgs {
#[clap(value_parser=maybe_hex::<u16>)]
input: u16,
#[clap(value_parser=maybe_hex::<u16>)]
key: u16,
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct Feistel0SBOXArgs {
#[clap(value_parser=maybe_hex::<u8>)]
index: u8,
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
struct Feistel0Args{
#[clap(value_parser=maybe_hex::<u32>)]
input: u32,
#[clap(value_parser=maybe_hex::<u32>)]
key: u32,
#[arg(short, long, default_value_t = false)]
decrypt: bool,
}
/*************************************************************************************************/
/// main function of plexcryptool.
///
/// This function is the entrypoint of the binary. It parses Commandline options and calls the
/// internal functions with the corresponding values, then shows the results to the user.
pub fn main() {
let args = Cli::parse();
match args.command {
Commands::Math(action) => {
match action.action {
MathActions::Modexp(mod_exp_args) => {
let b = num_bigint::BigInt::from_str(&mod_exp_args.base.as_str()).expect("could not make bigint");
let e = num_bigint::BigInt::from_str(&mod_exp_args.exp.as_str()).expect("could not make bigint");
let f = num_bigint::BigInt::from_str(&mod_exp_args.field.as_str()).expect("could not make bigint");
let result = math::modexp::modular_exponentiation(b.clone(), e, f, args.verbose);
if args.machine {
println!("{}", result)
}
else {
println!("result is {}", result)
}
}
}
}
Commands::Binary(action) => {
match action.action {
BinaryActions::Rotate(bin_rot_args) => {
let result: u32;
if bin_rot_args.left {
result = binary::rotl32(bin_rot_args.base, bin_rot_args.shift_width);
}
else {
result = binary::rotr32(bin_rot_args.base, bin_rot_args.shift_width);
}
if args.machine {
println!("{}", result)
}
else {
println!("result is {}", result)
}
},
BinaryActions::Xor(bin_xor_args) => {
let result: u128 = binary::xor(bin_xor_args.a, bin_xor_args.b);
if args.machine {
println!("{}", result)
}
else {
println!("result is {}", result)
}
}
}
}
Commands::Algo(action) => {
match action.action {
AlgoActions::Feistel0Inner(alg_fei_args) => {
let result: u16 = algo::feistel0::inner(alg_fei_args.input, alg_fei_args.key, args.verbose);
if args.machine {
println!("{}", result)
}
else {
println!("result is {} ({:04x})", result, result)
}
}
AlgoActions::Feistel0SBOX(alg_fsb_args) => {
let result: u8 = algo::feistel0::sbox(alg_fsb_args.index);
if args.machine {
println!("{}", result)
}
else {
println!("result is {} ({:08x})", result, result)
}
}
AlgoActions::Feistel0(alg_fe0_args) => {
let keys = algo::feistel0::key_scheduler(alg_fe0_args.key);
let result: u32;
if alg_fe0_args.decrypt {
result = algo::feistel0::decrypt(alg_fe0_args.input, keys, args.verbose);
}
else {
result = algo::feistel0::encrypt(alg_fe0_args.input, keys, args.verbose);
}
if args.machine {
println!("{}", result)
}
else {
println!("result is {} ({:08x})", result, result)
}
}
}
}
}
}