Skip to main content

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

  1. Detecting duplicated records.
  2. Locating points that are near each other.
  3. Verifying message integrity.
  4. 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

Metadata

Release files for cha-hashing 0.4.8.7.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cha-hashing 0.4.8.7.9
File Size Uploaded
cha_hashing-0.4.8.7.9.tar.gz 23.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cha-hashing 0.4.8.7.9
File Interpreter ABI Platform
cha_hashing-0.4.8.7.9-py3-none-any.whl Python 3 none any Details

Total release size: 50.6 kB

Release files / cha_hashing-0.4.8.7.9.tar.gz

Download URL cha_hashing-0.4.8.7.9.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
571ec3ab18a2e64ebdf2dc700b1c6d2d5ddc408d2351b2f8276969dec3958742
BLAKE2b-256 checksum
How to use checksums
60d817c26611ed30b05340dbd81e9faf623a4d7096d3731e18be7f65d79accbe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.13

Release files / cha_hashing-0.4.8.7.9-py3-none-any.whl

Download URL cha_hashing-0.4.8.7.9-py3-none-any.whl
Size 27.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d359f586774b62071958109abf5e453fd530040f84a8a884f0f902472858b563
BLAKE2b-256 checksum
How to use checksums
d024ec0ad1d276b36b6bb1b6739cbb8efcde6bf1b4150067b584a26fd084f3e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.13

Release history Release notifications | RSS feed

This release

0.4.8.7.9 This release

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page