Metadata-Version: 2.1
Name: cha_hashing
Version: 0.4.4
Summary: A Hashing and encryption with Customizable Hashing Algorithm CHA, WARNING: DO NOT USE IN REAL USE CASES! THIS WAS MADE JUST FOR FUN!
Home-page: https://github.com/RoyNisimov1/CHA
Author: Roy Nisimov
License: MIT
Keywords: python,hashin,cha,encryption,decryption
Classifier: Development Status :: 1 - Planning
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: Unix
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Description-Content-Type: text/markdown
License-File: LICENSE

# 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
```
## cloning
```
git clone https://github.com/RoyNisimov1/CHA.git
```

# how to use
import CHA *
``` 
from CHA import Feistel64
from CHA import CHAObject
from CHA import HashMaker
```
or just 
```
from CHA import *
```


# How RA works
## 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)
    if c in characters and c in shuffle_list:
        index = characters.index(c)
        om.append(shuffle_list[index])
    else:
        om.append(c)
```

## Step Two: Padding
This step adds padding to the cipher text, we also have an amount to shift at the end of it

``` 
bm = [format(ord(c), 'b') for c in om]
amount_to_shift = len(padding_list) - len(bm)
if amount_to_shift <= 0: amount_to_shift *= -1
shift_must = ord(om[0]) if len(om) > 0 else shift_must_if_om0
amount_to_shift += shift_must
for i, b in enumerate(padding_list):
    bm.append(b)
```

## Step Three: Keying
We make a copy of the text list (bm in here) and shift everything by the amount to shift

``` 
key = bm.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 == bm:
    first = key.pop(0)
    key.append(first)
```

## Step Four: XORing
In this step we XOR the ciphertext with our key

```
bm = list(int(c, 2) for c in bm)
key = list(int(c, 2) for c in key)
xored = []
for i in range(len(bm)):
    xored.append(bm[i] ^ key[i])
s_xored = [str(n) for n in xored]
s = ''
for string in s_xored:
    s += string.strip("-")
s = s[0:size_limit_of_0]
```
## Step Five: Repeat and shift padding
We shift the padding by ```amount_to_shift**amount_to_shift % len(padding_list)```

This process repeat 16 times using the "s" as the new message

``` 
for i in range(pow(amount_to_shift, amount_to_shift, len(padding_list))):
    first = padding_list.pop(0)
    if times % rev_every == 0:
        padding_list.reverse()
    padding_list.append(first)
message = s
```

## Step Six: Final
We join this large list, turn that into an int, and then we return a CHAObject object of it
``` 
last_int = int(s)
return CHAObject(last_int)
```


# 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](#How-RA-works)

## 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



# Creating your own algorithm using HashMaker

## RandomShaffle
This function will help you make your own random shuffled charset (```random.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 = Feistel64.DE(s,  8, fCHA)
    print(e)
    d = Feistel64.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 Feistel64 class
to do this automatically.
### mode 'e'
this will return a list of hexes
### mode 'd'
will return the string

[Feistel Cipher - Computerphile](https://www.youtube.com/watch?v=FGhj3CGxl8I)

# *_Notes_*:

1. _Use the hexdigest function to get the value in hex_

2. *THIS HASH FUNCTION IS PROBABLY NOT THE SAFEST!*

3. I made it because I was bored, so please use something like Argon2 or Sha512 for real use cases.

4. Also, there might already be a similar hashing function that I don't know of

5. In the HashMaker there is a chance that some padding or shuffle_key have a backdoor in them (Though not probable). 

PS: I know my code looks bad
