Skip to content

Commit

Permalink
Updated package to v0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mayur7garg committed Mar 7, 2021
1 parent 58e483b commit a367efa
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 143 deletions.
136 changes: 68 additions & 68 deletions Examples.ipynb

Large diffs are not rendered by default.

77 changes: 75 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,75 @@
# FeistelCipher
Naive implementation of Feistel Cipher using Python
# Feistel Cipher
The Feistel Cipher package can be used to implement a Feistel Cipher using either inbuilt or custom functions for encyrpting and decrypting integers.

*Current Version: 0.2.0*

*Requires: Python 3.5+*

## Inspiration
The creation of the package is both inspired by and based on the explanation given **Dr. Mike Pound** on the **[Computerphile](https://www.youtube.com/user/Computerphile)** YouTube channel in the video titled **[Feistel Cipher - Computerphile](https://youtu.be/FGhj3CGxl8I)**.

## Installation

You can install the **Feistel Cipher** package from **[PyPI](https://pypi.org/project/feistelcipher/)**

pip install feistelcipher

## Usage

### Import the necessary classes
```python
import feistelcipher.FeistelCipher as fc
import feistelcipher.CryptFunctions as cfs
import feistelcipher.StandardCryptFunctions as scf
```

### Create a `CryptFunctions` object
```python
funcList = cfs.CryptFunctions()
```
### Add functions and associated keys to the `CryptFunctions` object
```python
funcList.addFunc(scf.strLength)
funcList.addFunc(scf.quotient, [7])
funcList.addFunc(scf.power, [3])
funcList.addFunc(scf.truncate, [5])
funcList.addFunc(scf.scaledDistance, [1, 2, 3, 4])
```

### Create a `FeistelCipher` object using the `CryptFunctions` object
```python
cipher = fc.FeistelCipher(funcList)
```

### Encryption
```python
enc = cipher.encrypt(1_234_567)
print(repr(enc))
```
##### Output

>>> EncryptedObject(437201434, 43067, 4)

### Decryption
```python
dec = cipher.decrypt(enc)
print(dec)
```

##### Output

>>> 1234567

## Advanced Usage and Explanation
For detailed explanation and usage of this package with custom functions, kindly refer to [Examples.ipynb](https://github.com/mayur7garg/FeistelCipher/blob/main/Examples.ipynb) in the [GitHub repo](https://github.com/mayur7garg/FeistelCipher).

## Upcoming improvements
- Support for Keyword arguments
- Encrypting/Decrypting iterables of integers
- Support for easily saving the `FeistelCipher` object to a pickled or binary file
- Improved Documentation

## Thank You
If you liked this package or found it useful, consider starring the associated GitHub repository.

> Created by - *Mayur Kr. Garg*
16 changes: 12 additions & 4 deletions build/lib/feistelcipher/CryptFunctions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class CryptFunctions():
class CryptFunctionBlock():
def __init__(self, func, key: int) -> None:
def __init__(self, func, key = None) -> None:
self.func = func
self.key = key
self.key = [] if key is None else key

def execute(self, num: int) -> int:
return self.func(self.key, num)
return self.func(num, *self.key)

def __init__(self):
self.cryptFuncs = []
Expand All @@ -16,5 +16,13 @@ def __iter__(self):
def __getitem__(self, index):
return self.cryptFuncs[index]

def addFunc(self, func, key: int) -> None:
def __str__(self) -> str:
s: str = f"\n{'Function':32}Keys\n\n"
for funcBlock in self:
s += f"{funcBlock.func.__name__:32}{funcBlock.key}\n"

return s

def addFunc(self, func, key = None) -> None:
self.cryptFuncs += [self.CryptFunctionBlock(func, key)]

25 changes: 17 additions & 8 deletions build/lib/feistelcipher/FeistelCipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,24 @@ def execCipherBlock(self, left: int, right: int, cryptFunc: CryptFunctions.Crypt
temp = left ^ cryptFunc.execute(right)
return (right, temp)

def printCipherBlock(self):
print(self.cryptFuncs)

def encrypt(self, numToEncrypt: int) -> 'EncryptedObject':
signOffset = 1 if numToEncrypt < 0 else 0
numToEncrypt = str(numToEncrypt)

if len(numToEncrypt) % 2 == 1:
numToEncrypt = '0' + numToEncrypt
numToEncrypt = numToEncrypt[:signOffset] + '0' + numToEncrypt[signOffset:]

blockLength = len(numToEncrypt)//2
leftHalf = int(numToEncrypt[blockLength:])
rightHalf = int(numToEncrypt[:blockLength])
blockLength = len(numToEncrypt) // 2

if (blockLength == 1 and signOffset == 1) or (int(numToEncrypt[:blockLength]) == 0):
leftHalf = int(numToEncrypt)
rightHalf = 0
else:
leftHalf = int(numToEncrypt[blockLength:])
rightHalf = int(numToEncrypt[:blockLength])

for cryptFunc in self.cryptFuncs:
(leftHalf, rightHalf) = self.execCipherBlock(leftHalf, rightHalf, cryptFunc)
Expand All @@ -41,10 +51,9 @@ def decrypt(self, encryptedObject: EncryptedObject) -> int:
blockLength = encryptedObject.blockLength

for cryptFunc in self.cryptFuncs[::-1]:
(leftHalf, rightHalf) = self.execCipherBlock(
leftHalf, rightHalf, cryptFunc)
(leftHalf, rightHalf) = self.execCipherBlock(leftHalf, rightHalf, cryptFunc)

leftHalf = str(leftHalf).rjust(blockLength, '0')
leftHalf = str(leftHalf)
rightHalf = str(rightHalf).rjust(blockLength, '0')

return int(leftHalf+rightHalf)
return int(rightHalf) if int(leftHalf) == 0 else int(leftHalf + rightHalf)
78 changes: 25 additions & 53 deletions build/lib/feistelcipher/StandardCryptFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,47 @@
This script contains some standard functions which can be used in the
implementation of a Feistel Cipher.
All functions in this script accept two arguments -
key : int
This value acts as an encoding key for the function.
It must be a non-negative integer.
Not all functions may utilise this argument but it must always
be provided to keep the function signatures consistent.
num : int
This value acts as the value on which the function acts.
It must be a non-negative integer.
All functions in this script return a non-negative integer
All functions in this script return an integer
(assuming the functions are called using valid arguments).
This script also contains a list containing references to all the
functions in this script which can be used to randomly add a function
block to the Feistel Cipher.
Created By -
Mayur Kr. Garg
"""

def identity(key: int, num: int) -> int:
def identity(num: int) -> int:
return num


def add(key: int, num: int) -> int:
def add(num: int, key: int) -> int:
return key + num

def multiply(num: int, key: int) -> int:
return key * num

def multiply(key: int, num: int) -> int:
return key*num


def addThenMultiply(key: int, num: int) -> int:
return (num+key)*key


def strLength(key: int, num: int) -> int:
def strLength(num: int) -> int:
return len(str(num))

def power(num: int, key: int) -> int:
key = abs(key) if num == 0 else key
return int(pow(num, key))

def power(key: int, num: int) -> int:
return pow(num, key)


def reverse(key: int, num: int) -> int:
return int(str(num)[::-1])
def reverse(num: int) -> int:
sign = 1 if num > 0 else -1
return int(str(abs(num))[::-1]) * sign

def truncate(num: int, key: int) -> int:
sign = 1 if num > 0 else -1
num = abs(num)
key = max(1, min(key, len(str(num))))
return int(str(num)[:key]) * sign

def truncate(key: int, num: int) -> int:
if key <= 0:
key = 1
return int(str(num)[:key])


def remainder(key: int, num: int) -> int:
if key <= 0:
key = 1
def remainder(num: int, key: int) -> int:
key = 1 if key == 0 else key
return num % key

def quotient(num: int, key: int) -> int:
key = 1 if key == 0 else key
return num // key

def quotient(key: int, num: int) -> int:
if key <= 0:
key = 1
return num//key


ALL_FUNCTIONS = [identity, add, multiply, addThenMultiply,
strLength, power, reverse, truncate, remainder, quotient]
def scaledDistance(num: int, x1: int, x2: int, y1: int, y2: int) -> int:
return int(num * pow(pow(x1 - x2, 2) + pow(y1 - y2, 2), 0.5))
3 changes: 2 additions & 1 deletion build/lib/feistelcipher/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__version__ = "0.1.0"
__version__ = "0.2.0"
__author__ = "Mayur Kr. Garg"
Binary file added dist/feistelcipher-0.2.0-py3-none-any.whl
Binary file not shown.
Binary file added dist/feistelcipher-0.2.0.tar.gz
Binary file not shown.
80 changes: 76 additions & 4 deletions feistelcipher.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,14 +1,86 @@
Metadata-Version: 2.1
Name: feistelcipher
Version: 0.1.0
Summary: Naive implementation of Feistel Cipher using Python
Version: 0.2.0
Summary: Naive implementation of Feistel Cipher for encrypting/decrypting integers using custom function blocks.
Home-page: https://github.com/mayur7garg/FeistelCipher
Author: Mayur Kr. Garg
Author-email: mayur7garg@gmail.com
License: MIT
Description: # FeistelCipher
Naive implementation of Feistel Cipher using Python
Description: # Feistel Cipher
The Feistel Cipher package can be used to implement a Feistel Cipher using either inbuilt or custom functions for encyrpting and decrypting integers.

*Current Version: 0.2.0*

*Requires: Python 3.5+*

## Inspiration
The creation of the package is both inspired by and based on the explanation given **Dr. Mike Pound** on the **[Computerphile](https://www.youtube.com/user/Computerphile)** YouTube channel in the video titled **[Feistel Cipher - Computerphile](https://youtu.be/FGhj3CGxl8I)**.

## Installation

You can install the **Feistel Cipher** package from **[PyPI](https://pypi.org/project/feistelcipher/)**

pip install feistelcipher

## Usage

### Import the necessary classes
```python
import feistelcipher.FeistelCipher as fc
import feistelcipher.CryptFunctions as cfs
import feistelcipher.StandardCryptFunctions as scf
```

### Create a `CryptFunctions` object
```python
funcList = cfs.CryptFunctions()
```
### Add functions and associated keys to the `CryptFunctions` object
```python
funcList.addFunc(scf.strLength)
funcList.addFunc(scf.quotient, [7])
funcList.addFunc(scf.power, [3])
funcList.addFunc(scf.truncate, [5])
funcList.addFunc(scf.scaledDistance, [1, 2, 3, 4])
```

### Create a `FeistelCipher` object using the `CryptFunctions` object
```python
cipher = fc.FeistelCipher(funcList)
```

### Encryption
```python
enc = cipher.encrypt(1_234_567)
print(repr(enc))
```
##### Output

>>> EncryptedObject(437201434, 43067, 4)

### Decryption
```python
dec = cipher.decrypt(enc)
print(dec)
```

##### Output

>>> 1234567

## Advanced Usage and Explanation
For detailed explanation and usage of this package with custom functions, kindly refer to [Examples.ipynb](https://github.com/mayur7garg/FeistelCipher/blob/main/Examples.ipynb) in the [GitHub repo](https://github.com/mayur7garg/FeistelCipher).

## Upcoming improvements
- Support for Keyword arguments
- Encrypting/Decrypting iterables of integers
- Support for easily saving the `FeistelCipher` object to a pickled or binary file
- Improved Documentation

## Thank You
If you liked this package or found it useful, consider starring the associated GitHub repository.

> Created by - *Mayur Kr. Garg*
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Expand Down
3 changes: 2 additions & 1 deletion feistelcipher/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__version__ = "0.1.0"
__version__ = "0.2.0"
__author__ = "Mayur Kr. Garg"
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

setup(
name = "feistelcipher",
version = "0.1.0",
description = "Naive implementation of Feistel Cipher using Python",
version = "0.2.0",
description = "Naive implementation of Feistel Cipher for encrypting/decrypting integers using custom function blocks.",
long_description = README,
long_description_content_type = "text/markdown",
url = "https://github.com/mayur7garg/FeistelCipher",
Expand Down

0 comments on commit a367efa

Please sign in to comment.