Compare commits
2 commits
a0448a339a
...
79c923a08c
Author | SHA1 | Date | |
---|---|---|---|
79c923a08c | |||
9d37023df4 |
23 changed files with 391 additions and 11 deletions
|
@ -1 +1,2 @@
|
||||||
from .plexcryptool import *
|
from .plexcryptool import *
|
||||||
|
from . import scripts as scripts
|
||||||
|
|
10
src-py/plexcryptool/__init__.pyi
Normal file
10
src-py/plexcryptool/__init__.pyi
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
"""
|
||||||
|
Bindings for the plexcryptool rust library
|
||||||
|
|
||||||
|
plexcryptool.plexcryptool is direct access to the shared library, do not use it.
|
||||||
|
"""
|
||||||
|
from . import binary
|
||||||
|
from . import math
|
||||||
|
from . import algo
|
||||||
|
from . import cplex
|
||||||
|
from . import scripts
|
4
src-py/plexcryptool/algo/__init__.pyi
Normal file
4
src-py/plexcryptool/algo/__init__.pyi
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
"""
|
||||||
|
various algorithms implemented
|
||||||
|
"""
|
||||||
|
from . import feistel0 as feistel0
|
59
src-py/plexcryptool/algo/feistel0.pyi
Normal file
59
src-py/plexcryptool/algo/feistel0.pyi
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
"""
|
||||||
|
# basic implementation of a feistel network
|
||||||
|
|
||||||
|
This module implements a feistel network according to an exercise at DHBW Mannheim.
|
||||||
|
For demonstration purposes only, do not use this in a secure environment.
|
||||||
|
|
||||||
|
___
|
||||||
|
@Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
|
@License: MIT
|
||||||
|
@Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
"""
|
||||||
|
def inner(input: int, key: int, verbose: bool) -> int:
|
||||||
|
"""
|
||||||
|
the inner function of the feistel network
|
||||||
|
|
||||||
|
takes input, scrambles it by using two s and p boxes,
|
||||||
|
then xors with the key.
|
||||||
|
|
||||||
|
:param input unsigned 16 bit int
|
||||||
|
:param key unsigned 16 bit int
|
||||||
|
:param verbose print steps
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def encrypt(plaintext: int, keys: list[int], verbose: bool) -> int:
|
||||||
|
"""
|
||||||
|
encrypt using the feistel0 network
|
||||||
|
|
||||||
|
performes some rounds of the feistelnetwork to encrypt the input.
|
||||||
|
This will only encrypt a single block.
|
||||||
|
|
||||||
|
DO NOT USE THIS FOR ACTUAL ENCRYPTION!
|
||||||
|
|
||||||
|
:param plaintext unsigned 32 bit int
|
||||||
|
:param keys vec of the round keys, usually 3 diffrent ones.
|
||||||
|
:param verbose print steps
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def decrypt(ciphertext: int, keys: list[int], verbose: bool) -> int:
|
||||||
|
"""
|
||||||
|
decrypt using the feistel0 network
|
||||||
|
|
||||||
|
performs encryption backwards more or less
|
||||||
|
|
||||||
|
DO NOT USE THIS FOR ACTUAL ENCRYPTION!
|
||||||
|
|
||||||
|
:param ciphertext unsigned 32 bit int
|
||||||
|
:param keys vec of the round keys, usually 3 diffrent ones.
|
||||||
|
:param verbose print steps
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def sbox(index: int) -> int:
|
||||||
|
"""
|
||||||
|
returns the value of the sbox at index.
|
||||||
|
|
||||||
|
:param index range 0 - 15
|
||||||
|
"""
|
4
src-py/plexcryptool/cplex/__init__.pyi
Normal file
4
src-py/plexcryptool/cplex/__init__.pyi
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
"""
|
||||||
|
various common functionalities used by many modules
|
||||||
|
"""
|
||||||
|
from . import printing as printing
|
28
src-py/plexcryptool/cplex/printing.pyi
Normal file
28
src-py/plexcryptool/cplex/printing.pyi
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
"""
|
||||||
|
common functionality for printing
|
||||||
|
|
||||||
|
Implements code that might be used by many other modules
|
||||||
|
|
||||||
|
___
|
||||||
|
@Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
|
@License: MIT
|
||||||
|
@Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def version():
|
||||||
|
"""
|
||||||
|
prints the plexcryptool version
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def about():
|
||||||
|
"""
|
||||||
|
prints the about section
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def seperator():
|
||||||
|
"""
|
||||||
|
prints a separator line
|
||||||
|
"""
|
||||||
|
...
|
|
@ -1,10 +0,0 @@
|
||||||
"""
|
|
||||||
Some basic math functionalities
|
|
||||||
"""
|
|
||||||
def modular_exponentiation(base: int, exp: int, field: int) -> int:
|
|
||||||
"""
|
|
||||||
calculates base^exp in the gallois given gallois field
|
|
||||||
|
|
||||||
Uses iterative squaring to be able to calculate large exponents aswell.
|
|
||||||
"""
|
|
||||||
...
|
|
9
src-py/plexcryptool/math/__init__.pyi
Normal file
9
src-py/plexcryptool/math/__init__.pyi
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
"""
|
||||||
|
# math module
|
||||||
|
|
||||||
|
Funcionality for math things. Contains tedious algorithms like binary exponentiation.
|
||||||
|
"""
|
||||||
|
from . import modexp as modexp
|
||||||
|
from . import modred as modred
|
||||||
|
from . import pm1 as pm1
|
||||||
|
|
27
src-py/plexcryptool/math/modexp.pyi
Normal file
27
src-py/plexcryptool/math/modexp.pyi
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
"""
|
||||||
|
modular exponentiaton
|
||||||
|
|
||||||
|
Implements fast exponentiation with applied modulo. Usefull for calculations in a gallois
|
||||||
|
field.
|
||||||
|
|
||||||
|
___
|
||||||
|
@Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
|
@License: MIT
|
||||||
|
@Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def modular_exponentiation(
|
||||||
|
base: int,
|
||||||
|
orig_exp: int,
|
||||||
|
field: int,
|
||||||
|
verbose: bool
|
||||||
|
) -> int:
|
||||||
|
"""
|
||||||
|
perform modular exponentiation
|
||||||
|
|
||||||
|
:param base the base of the exponentiation
|
||||||
|
:param orig_exp the exponent of the base
|
||||||
|
:param field the number that describes the gallois field (should be prime)
|
||||||
|
:param verbose print steps
|
||||||
|
"""
|
||||||
|
...
|
23
src-py/plexcryptool/math/modred.pyi
Normal file
23
src-py/plexcryptool/math/modred.pyi
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
"""
|
||||||
|
modular reduction
|
||||||
|
|
||||||
|
Implements automatic modular reduction in a field specified by a given relation.
|
||||||
|
|
||||||
|
Basically, any binary number can be written as a polynomial. This polynomial can be reduced by
|
||||||
|
the relation that defines a field. In that field. This is what we call modular reduction.
|
||||||
|
|
||||||
|
___
|
||||||
|
@Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
|
@License: MIT
|
||||||
|
@Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def modred(poly: int, relation: int, verbose: bool) -> int:
|
||||||
|
"""
|
||||||
|
perform modular reduction
|
||||||
|
|
||||||
|
:param poly the polynomial as int
|
||||||
|
:param relation the relation as int
|
||||||
|
:param verbose print steps
|
||||||
|
"""
|
||||||
|
...
|
29
src-py/plexcryptool/math/pm1.pyi
Normal file
29
src-py/plexcryptool/math/pm1.pyi
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
"""
|
||||||
|
P minus 1 method
|
||||||
|
|
||||||
|
Determine the prime factors of a number with the p minus 1 method.
|
||||||
|
Effecient for numbers with low ranged prime factors.
|
||||||
|
|
||||||
|
___
|
||||||
|
@Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
|
@License: MIT
|
||||||
|
@Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def p_minus_one(n: int, max_prime: int, verbose: bool) -> list[int]:
|
||||||
|
"""
|
||||||
|
p minus 1 prime number test
|
||||||
|
|
||||||
|
:param n u128 number to check
|
||||||
|
:param max_prime the highest prime power to use
|
||||||
|
:param verbose print steps
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def alt_gcd(a: int, b: int) -> int:
|
||||||
|
"""
|
||||||
|
find greatest common divisor
|
||||||
|
|
||||||
|
this is a primitive extended euclidic algorithm.
|
||||||
|
"""
|
||||||
|
...
|
|
@ -2,4 +2,5 @@
|
||||||
Bindings for the plexcryptool rust library
|
Bindings for the plexcryptool rust library
|
||||||
|
|
||||||
plexcryptool.plexcryptool is direct access to the shared library, do not use it.
|
plexcryptool.plexcryptool is direct access to the shared library, do not use it.
|
||||||
|
(you should not see this specific version of this text)
|
||||||
"""
|
"""
|
||||||
|
|
9
src-py/plexcryptool/scripts/__init__.py
Normal file
9
src-py/plexcryptool/scripts/__init__.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
"""
|
||||||
|
various scripts
|
||||||
|
|
||||||
|
these are coded in python and can currently not be called from the executable.
|
||||||
|
"""
|
||||||
|
from . import authur1 as authur1
|
||||||
|
from . import basic_decrypt as basic_decrypt
|
||||||
|
from . import md5_analyzer as md5_analyzer
|
||||||
|
from . import trash_hash as trash_hash
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
/// common functionality
|
/// common functionality for printing
|
||||||
///
|
///
|
||||||
/// Implements code that might be used by many other modules
|
/// Implements code that might be used by many other modules
|
||||||
///
|
///
|
||||||
|
|
152
src/math/gallois.rs
Normal file
152
src/math/gallois.rs
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
use num::Integer;
|
||||||
|
|
||||||
|
/// calculation in a gallois field
|
||||||
|
///
|
||||||
|
/// This module contains functions that can be used to calculate things in a gallois field
|
||||||
|
///
|
||||||
|
/// Author: Christoph J. Scherr <software@cscherr.de>
|
||||||
|
/// License: MIT
|
||||||
|
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||||
|
|
||||||
|
use crate::math::modexp;
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#[derive(Debug)]
|
||||||
|
/// used when trying to find a root for a number which does not have a root.
|
||||||
|
pub struct NoInverseError;
|
||||||
|
|
||||||
|
impl fmt::Display for NoInverseError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "inverse for 0 does not exist")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#[derive(Debug)]
|
||||||
|
/// used when trying to find a root for a number which does not have a root.
|
||||||
|
pub struct DivisionByZeroError;
|
||||||
|
|
||||||
|
impl fmt::Display for DivisionByZeroError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "division by zero")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#[derive(Debug)]
|
||||||
|
/// used when trying to find a root for a number which does not have a root.
|
||||||
|
pub struct NoRootError;
|
||||||
|
|
||||||
|
impl fmt::Display for NoRootError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "no root in the specified gallois field")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
/// represent a gallois field
|
||||||
|
pub struct GalloisFiled {
|
||||||
|
base: u128,
|
||||||
|
cha: u128,
|
||||||
|
verbose: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// implementations for the gallois field
|
||||||
|
impl GalloisFiled {
|
||||||
|
/// make a new gallois field
|
||||||
|
pub fn new(base: u128, verbose: bool) -> Self {
|
||||||
|
let mut field = GalloisFiled{
|
||||||
|
base,
|
||||||
|
// TODO: calculate the characteristic
|
||||||
|
cha: 0,
|
||||||
|
verbose
|
||||||
|
};
|
||||||
|
if verbose {
|
||||||
|
dbg!(&field);
|
||||||
|
}
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// reduce a number to fit into the gallois field
|
||||||
|
pub fn reduce(self, n: u128) -> u128 {
|
||||||
|
let mut n = n;
|
||||||
|
if n < 0 {
|
||||||
|
while n < 0 {
|
||||||
|
n += self.base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n %= self.base;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// reduce a negative number to fit into the gallois field
|
||||||
|
pub fn reduce_neg(self, n: i128) -> u128 {
|
||||||
|
let mut n = n;
|
||||||
|
if n < 0 {
|
||||||
|
while n < 0 {
|
||||||
|
n += self.base as i128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n %= self.base as i128;
|
||||||
|
return n as u128;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// calculate the exponent of a base in the field
|
||||||
|
pub fn pow(self, base: u128, exp: u128) -> u128 {
|
||||||
|
return modexp::modular_exponentiation_wrapper(base, exp, self.base, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// find the additive inverse of a number
|
||||||
|
pub fn a_inverse(self, n: u128) -> u128 {
|
||||||
|
return self.base - self.reduce(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// find the multiplicative inverse of a number
|
||||||
|
pub fn inverse(self, n: u128) -> Result<u128, NoInverseError> {
|
||||||
|
if n == 0 {
|
||||||
|
return Err(NoInverseError);
|
||||||
|
}
|
||||||
|
let egcd = (n as i128).extended_gcd(&(self.base as i128));
|
||||||
|
dbg!(n);
|
||||||
|
return Ok(egcd.x as u128);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn divide(self, a: u128, b: u128) -> Result<u128, DivisionByZeroError> {
|
||||||
|
let b = self.inverse(b);
|
||||||
|
match b {
|
||||||
|
Ok(r) => {
|
||||||
|
return Ok(self.reduce(a * r));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
dbg!(e);
|
||||||
|
return Err(DivisionByZeroError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// calculate the square root of a number in a field
|
||||||
|
pub fn sqrt(self, n: u128) -> Result<u128, NoRootError> {
|
||||||
|
// TODO implement this
|
||||||
|
panic!("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#[test]
|
||||||
|
fn test_gallois_sqrt() {
|
||||||
|
panic!("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gallois_inverse() {
|
||||||
|
let field = GalloisFiled::new(31, true);
|
||||||
|
assert_eq!(field.inverse(12).unwrap(), 13);
|
||||||
|
assert_eq!(field.inverse(28).unwrap(), 10);
|
||||||
|
assert!(field.inverse(0).is_err());
|
||||||
|
|
||||||
|
let field = GalloisFiled::new(83, true);
|
||||||
|
assert_eq!(field.inverse(6).unwrap(), 14);
|
||||||
|
assert_eq!(field.inverse(54).unwrap(), 20);
|
||||||
|
assert!(field.inverse(0).is_err());
|
||||||
|
}
|
|
@ -9,3 +9,4 @@
|
||||||
pub mod modexp;
|
pub mod modexp;
|
||||||
pub mod pm1;
|
pub mod pm1;
|
||||||
pub mod modred;
|
pub mod modred;
|
||||||
|
pub mod gallois;
|
||||||
|
|
|
@ -68,6 +68,19 @@ pub fn modular_exponentiation(
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// quick wrapper for modular_exponentiation without BigInts
|
||||||
|
pub fn modular_exponentiation_wrapper(
|
||||||
|
base: u128,
|
||||||
|
exp: u128,
|
||||||
|
field: u128,
|
||||||
|
verbose: bool) -> u128 {
|
||||||
|
|
||||||
|
let base = BigInt::from(base);
|
||||||
|
let exp = BigInt::from(exp);
|
||||||
|
let field = BigInt::from(field);
|
||||||
|
return modular_exponentiation(base, exp, field, verbose).to_u128().expect("number too big");
|
||||||
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
#[pyo3(name="modular_exponentiation")]
|
#[pyo3(name="modular_exponentiation")]
|
||||||
#[pyo3(signature=(base, orig_exp, field, verbose = false))]
|
#[pyo3(signature=(base, orig_exp, field, verbose = false))]
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
use crate::cplex::printing::seperator;
|
use crate::cplex::printing::seperator;
|
||||||
|
|
||||||
|
use pyo3::{prelude::*, exceptions::PyException};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_modred() {
|
fn test_modred() {
|
||||||
let rel: u64 = 0x1053;
|
let rel: u64 = 0x1053;
|
||||||
|
@ -19,6 +21,9 @@ fn test_modred() {
|
||||||
assert_eq!(modred(pol0, rel, false).unwrap(), 0x21e);
|
assert_eq!(modred(pol0, rel, false).unwrap(), 0x21e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// modular reduction of a polynomial with a given relation
|
||||||
|
///
|
||||||
|
/// (the function uses the integer representations)
|
||||||
pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result<u64, String> {
|
pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result<u64, String> {
|
||||||
|
|
||||||
let mut diffrence: u32;
|
let mut diffrence: u32;
|
||||||
|
@ -44,3 +49,18 @@ pub fn modred(mut poly: u64, relation: u64, verbose: bool) -> Result<u64, String
|
||||||
}
|
}
|
||||||
return Ok(poly);
|
return Ok(poly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyfunction]
|
||||||
|
#[pyo3(name="mordred")]
|
||||||
|
/// python wrapper for modred
|
||||||
|
pub fn py_modred(poly: u64, relation: u64, verbose: bool) -> PyResult<u64> {
|
||||||
|
let res = modred(poly, relation, verbose);
|
||||||
|
match res {
|
||||||
|
Ok(n) => {
|
||||||
|
return Ok(n);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(PyException::new_err(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue