#![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 //! //! License: MIT //! //! Source: 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::)] input: u16, #[clap(value_parser=maybe_hex::)] key: u16, } #[derive(Args, Clone, Debug, PartialEq, Eq)] struct Feistel0SBOXArgs { #[clap(value_parser=maybe_hex::)] index: u8, } #[derive(Args, Clone, Debug, PartialEq, Eq)] struct Feistel0Args{ #[clap(value_parser=maybe_hex::)] plaintext: u32, #[clap(value_parser=maybe_hex::)] key: u32, } /*************************************************************************************************/ /// 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 = algo::feistel0::encrypt(alg_fe0_args.plaintext, keys, args.verbose); if args.machine { println!("{}", result) } else { println!("result is {} ({:016x})", result, result) } } } } } }