A hashing and encryption with Customizable Hashing Algorithm CHA, WARNING: DO NOT USE IN REAL USE CASES! THIS WAS MADE JUST FOR FUN!
Project description
READ ME
This was made for fun and learning cryptography and python. Everything here is not for real use-cases. Keep in mind that the functions here are probably insecure. They went through 0 security checks, and were made without thinking of the security side of things.
Hashing use cases
- Detecting duplicated records.
- Locating points that are near each other.
- Verifying message integrity.
- Verifying passwords.
Installation
pip
pip install cha-hashing
how to use
import CHA *
from CHA import FeistelN
from CHA import CHAObject
from CHA import HashMaker
from CHA import Piranha
from CHA import PEMFile
or just
from CHA import *
How RA works
The shuffle algorithm
def shuffle(to_shuffle_list: list):
to_shuffle_list = to_shuffle_list.copy()
to_append_size = to_shuffle_list[0]
a = []
for i1 in range(to_append_size % len(to_shuffle_list)):
a.append(to_shuffle_list.pop(0))
to_shuffle_list.reverse()
for i2 in a:
to_shuffle_list.append(i2)
e = []
for i3, ch in enumerate(to_shuffle_list):
if i3 % 2 == 0:
e.append(to_shuffle_list.pop(i3))
for i4 in e:
to_shuffle_list.append(i4)
return to_shuffle_list
Step One: Encipher
The function enciphers each letter with a letter in the shuffle list if it exists there, then shifts the letters in the shuffle list by the ord of c ** ord c each time.
for c in message:
for i in range(0, pow(ord(c), ord(c), len(shuffle_list))):
first = shuffle_list.pop(0)
shuffle_list.append(first)
ord_shuffle_list = [ord(c) for c in shuffle_list]
shuffled = shuffle(ord_shuffle_list)
shuffle_list = [chr(c) for c in shuffled]
if c in characters and c in shuffle_list:
index = characters.index(c)
original_message.append(shuffle_list[index])
else:
original_message.append(c)
Step Two: Padding
binary_formatted_message = [format(ord(c), 'b') for c in original_message]
amount_to_shift = len(padding_list) - len(binary_formatted_message)
if amount_to_shift <= 0: amount_to_shift *= -1
shift_must = ord(original_message[0]) if len(original_message) > 0 else shift_must_if_om0
amount_to_shift += shift_must
binary_formatted_message.extend(padding_list)
Step Three: Keying
key = binary_formatted_message.copy()
for i in range(0, amount_to_shift):
if times % rev_every == 0:
key.reverse()
first = key.pop(0)
key.append(first)
if key == binary_formatted_message:
first = key.pop(0)
key.append(first)
Step Four: XORing
In this step we XOR the ciphertext with our key
binary_formatted_message = list(int(c, 2) for c in binary_formatted_message)
key = list(int(c, 2) for c in key)
xored = []
for i in range(len(binary_formatted_message)):
xored.append(binary_formatted_message[i] ^ key[i])
Step Five: Repeat and shift padding
binary_formatted_message = list(int(c, 2) for c in binary_formatted_message)
key = list(int(c, 2) for c in key)
xored = []
for i in range(len(binary_formatted_message)):
xored.append(binary_formatted_message[i] ^ key[i])
Step Six: Final
We join this large list, turn that into an int, and then we return a CHAObject object of it
s_xored = [str(n) for n in xored]
s = ''
for string in s_xored:
s += string.strip("-")
s = s[0:size_limit_of_0]
for i in range(pow(amount_to_shift, amount_to_shift, len(padding_list))):
intL = [int(c, 2) for c in padding_list]
padding_list = shuffle(intL)
padding_list = [format(c, 'b') for c in padding_list]
message = s
CHA - Customizable Hashing Algorithm
CHA works the same way as RA, but customizable. so I'll only talk about the customization.
message
The plaintext that enters the function.
padding
The padding as a byte string separated by a space, like : '01110011 00110011 11000110'
.
this will be appended to the message
shaffle_list
The letter shuffle list Check the encipher step in the RA
size_limit_of_0
how many 0 are allowed
rep
number of repetitions
char_set
Additional chars used in the shuffle_list
shift_must_if_om0
shift_must = ord(om[0]) if len(om) > 0 else shift_must_if_om0
rev_every
Will preform some additional tasks with every time % $rev_every == 0
CHAB
Like CHA but the message is in bytes
HMAC
Syntax for hmac:
from CHA import FeistelN
from CHA import CHAFHMAC
# our secret key:
secret = b'test'
# message
msg = b'secret msg'
# creating a hmac obj
hmac_obj = CHAFHMAC(secret, func=FeistelN.fRAB_with_nonce(secret))
hmac_obj.update(msg)
# getting a mac
mac = hmac_obj.hexdigest()
print(mac)
# verifying a mac
print(hmac_obj.verify(mac))
Creating your own algorithm using HashMaker
RandomShaffle
This function will help you make your own random shuffled charset (secrets.SystemRandom().shuffle(letters)
but with built-in langs)
returns a string
RandomBits
This function will help you make your own random bits. returns a string or a list
how_many:
how many groups of bits do you want.
group:
how many in one group, 8 for a byte
how_to_format:
Can be " " or "l".
"l" for a list.
" " for a " ".join(bits)
get_CHA_args
This function will print the syntax needed. and return the padding, and shuffle key.
Note
There is a chance that some padding or shuffle_key have a backdoor in them (I don't know if there really is, but probably).
Encryption with CHA
CHA can be also used as an encryption function using the feistel cipher (see CHAF)
for example:
def fCHA(b):
padding, shuffle_list, size, rep, char_set, smio = CHAObject.get_RA_args()
return CHAObject.CHAB(b,padding,shuffle_list, 128, 16, '', 153)
s = input("Enter an input:\n").encode()
e = FeistelN().DE(s, 8, fCHA)
print(e)
d = FeistelN().DE(e, 8,fCHA, 'd')
print(d)
to make your own:
define a function
define a function using this template
def fCHA(b):
padding, shuffle_list, size, rep, char_set, smio = CHAObject.get_RA_args()
return CHAObject.CHAB(b,padding,shuffle_list, 128, 16, '', 153)
the function needs to return bytes, here we're using CHAB with the RA args.
Call DE
then the Feistel function uses 64 bits everytime, I configed the DE function on the FeistelN class to do this automatically.
mode 'e'
this will return a list of hexes
mode 'd'
will return the string
Feistel Cipher - Computerphile
BlackFrog
This is an asymmetric encryption algorithm
Key generation:
—---------------------------------------------------------------
Let n = large prime number
Pick e such that gcd(e,n) == 1 and e < n and e is prime
d = e**-1 % n
N = n * e * random
E = e**d % N
D = d**d % n
Public key: {E,N}
Private key: {n,d,e,D}
Encryption:
—---------------------------------------------------------------
ciphertext = message*E % N
Decryption:
—---------------------------------------------------------------
message = ciphertext*D % n
Generate keys
returns two keys, one public, one private
Encrypt
Encrypts bytes with public key and returns cipher text as bytes
Decrypt
Decrypt bytes with private key and returns message text as bytes
Piranha
I made this cipher using the RAB-Feistel network.
I made this to learn about modes of operation.
Right now the available modes are:
- ECB
- CBC
- CTR
- EAA (My Encrypt and Authenticate, not EAX)
key = b"super secret key"
msg = b'Test message'
# EBC
cipher = Piranha(key, Piranha.EBC)
c = cipher.encrypt(msg)
print(c)
cipher = Piranha(key, Piranha.EBC)
m = cipher.decrypt(c)
print(m)
# CBC
cipher = Piranha(key, Piranha.CBC)
paddedMsg = Piranha.pad(msg, Piranha.BlockSize)
c = cipher.encrypt(paddedMsg)
print(c)
cipher = Piranha(key, Piranha.CBC, iv=cipher.iv)
m = Piranha.unpad(cipher.decrypt(c))
print(m)
# CTR
cipher = Piranha(key, Piranha.CTR)
paddedMsg = Piranha.pad(msg, Piranha.BlockSize)
c = cipher.encrypt(paddedMsg)
print(c)
cipher = Piranha(key, Piranha.CTR, iv=cipher.iv)
m = Piranha.unpad(cipher.decrypt(c))
# EAA
key = b"key"
m = Piranha.pad(b'test')
cipher = Piranha(key, Piranha.EAA, data=m)
a = cipher.encrypt(m)
print(a)
cipher = Piranha(key, Piranha.EAA, iv=cipher.iv, data=a)
print(Piranha.unpad(cipher.decrypt(a)))
KRY and KRHASH
I made this cipher using the KRHASH-Feistel network.
I made this to learn about modes of operation.
Right now the available modes are:
- ECB
- CBC
- CTR
- EAA (My Encrypt and Authenticate, not EAX)
Works similar to Piranha, just replace Piranha with KRY
CowCowModes
I made this cipher using the CowCow-sp network.
I made this to learn about modes of operation.
Right now the available modes are:
- ECB
- CTR
- EAA (My Encrypt and Authenticate, not EAX)
Works similar to Piranha, just replace Piranha with CowCowModes
Modes (Build you own)
Right now the available modes are:
- ECB
- CBC
- CTR
- EAA (My Encrypt and Authenticate, not EAX)
Warning: do not init directly, use Modes.new()
Notes:
This is insecure! I made everything for fun and learning! Do not use in real usecases
PS: I know my code looks bad
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file cha_hashing-0.4.8.7.9.tar.gz
.
File metadata
- Download URL: cha_hashing-0.4.8.7.9.tar.gz
- Upload date:
- Size: 23.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 571ec3ab18a2e64ebdf2dc700b1c6d2d5ddc408d2351b2f8276969dec3958742 |
|
MD5 | 195eef43e2156e777ab92c3511053e61 |
|
BLAKE2b-256 | 60d817c26611ed30b05340dbd81e9faf623a4d7096d3731e18be7f65d79accbe |
File details
Details for the file cha_hashing-0.4.8.7.9-py3-none-any.whl
.
File metadata
- Download URL: cha_hashing-0.4.8.7.9-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d359f586774b62071958109abf5e453fd530040f84a8a884f0f902472858b563 |
|
MD5 | 4c84cdc30fb3b40fc71373228edbe5e4 |
|
BLAKE2b-256 | d024ec0ad1d276b36b6bb1b6739cbb8efcde6bf1b4150067b584a26fd084f3e2 |