Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/notstatilko/noncipher
XOR Cipher which uses hashes as gamma.
https://github.com/notstatilko/noncipher
Last synced: about 2 months ago
JSON representation
XOR Cipher which uses hashes as gamma.
- Host: GitHub
- URL: https://github.com/notstatilko/noncipher
- Owner: NotStatilko
- License: apache-2.0
- Created: 2019-06-03T16:14:29.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-06-28T16:16:32.000Z (over 4 years ago)
- Last Synced: 2024-10-11T17:50:14.350Z (3 months ago)
- Language: Python
- Homepage:
- Size: 106 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
#
NonCipher — The encryption algorithm that was based on [SafePassword](https://pastebin.com/srfVetG6).
###### Please check out [this issue](https://github.com/NotStatilko/NonCipher/issues/6) before any use
**SafePassword is an incredibly simple program, the meaning of which rolls down only in one loop. Please read the basic code at the link above, since SafePassword is the main thing in this program.**#
You can easy install NonCipher via pip
`pip install -U NonCipher`First of all, **three arguments** are passed to the main NonCipher class: **password, secret word, number of iterations**.
The **secret_word** in the hashing language is, in fact, **salt**.
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()
```The line above in pseudo-code looks like this:
```
primary_hash = password
for _ in range(iterations{1}):
primary_hash = sha512(primary_hash + secret_word)
```In NonCipher, I called the very first hash "__primary hash__"
To create a **primary hash** you need to use the class method `.init()`
This is worth paying attention to, since the more iterations there are(*__in our case, only one for example, never do it for God's sake. Ok? Ok.__*) the longer(obviously) it takes time to create an **primary hash**.
If you are ready to wait, you can set up > **5,000,000**, **so only 1/3 of your primary hash may take quite a long time to pick up**.
After initialization, you can view **your primary hash**, and make sure that it is impossible to pick it up.
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()print(nc._primary_hash)
```
Also you can see the hash of your input data(**password**, **secret_word**, **iterations**), it is also important, and later I will explain why`print(nc._hash_of_input_data)`
#
What's next?
Next, another 64 is created from the **primary hash**, they form the first list of hashes, from which a single **password of 4096 characters** is obtained during encryption.
And they are created like this:
```
unique_numbers = set([
*sha256(self._primary_hash).digest(),
*sha256(self._hash_of_input_data).digest(),
*sha256(self._primary_hash + self._hash_of_input_data).digest()
])
self._block = [
get_hash_of(
self._primary_hash, self._hash_of_input_data, i
)
for i in list(unique_numbers)[:64]
]
```
**If the text is longer than 4096 characters — NonCipher will create a new selection of hashes(new block) from the last existing** `self._block`, similar to the **primary hash**. And then everything is encrypted with a simple [XOR algorithm](https://en.m.wikipedia.org/wiki/XOR_cipher).In fact, it was a complete description of the algorithm. I came up with it myself(but it definitely already exists, lol), and it seems to me that this algorithm is crypto-resistant. If you want to try to decrypt the text encrypted by this program, use the constant `TRY_TO_DECRYPT`
```
from NonCipher import NonCipher, TRY_TO_DECRYPTnc = NonCipher(?,?,?)
nc.init()print(nc.cipher(TRY_TO_DECRYPT))
```
#In the meantime, you are trying to decipher it(right? Really, yes? Yes??) I will describe here examples of using NC.
Firstly: `nc.init()` is required. Since without this, the **primary hash** will not be created, which means that using the main function for which we have gathered here(`nc.cipher(..)`) will be impossible.
#
Encryption string length <= 4096
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()string = 'Hello, World!'
encrypted_string = nc.cipher(string) # Encrypted symbols
decrypted_string = nc.cipher(encrypted_string) # Hello, World!
```
Because the basis of NC is the [XOR algorithm](https://en.m.wikipedia.org/wiki/XOR_cipher) — **one function both encrypts and decrypts strings**.#
Encryption strings length > 4096
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()string = 'Hello, World! ............' # > 4096
encrypted_string = nc.cipher(string) # Encrypted symbols
decrypted_string = nc.cipher(encrypted_string) # Encrypted symb ... stop what?
```
Exactly! If you have encrypted a string that is **more than 4096 characters, you need to call the class method** `nc.init()` **again**, since in `nc._block` there are hashes left from the last hash in the last collection(difficult, yes). I have already said that if a text with a length > 4096 a new selection of hashes from the last existing one will be created. After encryption, they are not reset. That makes sense, I'm sure.I explained something similar in the code itself, and you can **use the help function** at any time. Just do `help(nc.init)`
And in order for the code to be correctly decrypted, you need to do this:
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()string = 'Hello, World! ............' # > 4096
encrypted_string = nc.cipher(string) # Encrypted symbols
nc.init()
decrypted_string = nc.cipher(encrypted_string) # Hello, World ..........
```
#File Encryption
**NC can encrypt any files**(_if you have time for her_( ͡° ͜ʖ ͡°)).
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()with open('cats.png', 'rb') as f:
encrypted_file = nc.cipher(f)
nc.init() # if your file weighs more than 4096 bytes
decrypted_file = nc.cipher(encrypted_file)
```
__*It looks simple, but am I going to keep a 500-mb file in RAM? Are you an idiot?*__NC can write encrypted characters **to a file instead of being stored in memory**. For this, it is worthwhile to simply put **kwarg** `write_temp` to `True`. In some cases, because of this, the encryption speed increases. If `write_temp` is set to `True`, `nc.cipher(..)` returns a two-element tuple: **the name of the .ncfile file, a file-like object that is ready to read.** After reading the file_like object, **the temporary file will be deleted.** If you **don't** want this, set `remove_temp` to `False`. Below is an example.
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()with open('cats.png', 'rb') as f:
encrypted_file = nc.cipher(f, write_temp=True) # Returns two-element tuple
encrypted_string = encrypted_file[1].read() # Temporary file will be removed after read
```
Or if you don't want the temporary file to be deleted:```
encrypted_string = encrypted_file[1].read(remove_temp=False) # Temporary file is not removed
```#
Multiprocessing
To begin, you create a NonCipher class object with the standard configuration, after you have executed the `nc.init()` method - take two necessary parameters from there that will allow you to implement multi(processing/threading) `nc._primary_hash`,`nc._hash_of_input_data`.
After that you will be able to create a new object of the NonCipher class in each process, and pass the **primary hash** and the NonCipher **hash of input data** to the same arguments. After `nc.init()` execution, the **primary hash** will not be created, but the one you entered will be used, which means you don't need to wait for the time to create the **primary hash**
My example below
```
from NonCipher import NonCipher
from multiprocessing import Processnc = NonCipher('password','secret_word',1)
nc.init()def nc_process_test(file,ph,hoid):
nc = NonCipher(primary_hash=ph, hash_of_input_data=hoid)
nc.init()
print(nc.cipher(file,write_temp=True))if __name__ == '__main__':
for i in range(5):
args = (open('cats.png'),nc._primary_hash,nc._hash_of_input_data)
Process(target=nc_process_test,args=args).start()
```#
NCv4.X and encryption in different processes
NCv4.X now has the ability to encrypt and decrypt files in **different processes** to speed up NonCipher.
```
from NonCipher import NonCiphernc = NonCipher('password', 'secret_word', 1)
nc.init()if __name__ == '__main__':
with open('test.png') as f:
print(nc.cipher(f, run_in_processes=True))
```
A new variable has appeared in the NonCipher class — `nc.cipher_process_count`. You can set the number of processes more or less, depending on the power of your computer. By default, `nc.cipher_process_count` is 10.Firstly, a single password is created from all blocks; after, this password is divided into `nc.cipher_process_count` files, along with the data to be encrypted(text or file). Each such file is allocated its own part of the password with which this part of the file is encrypted. After the end of the encryption process, all the numbered parts are **assembled into one common encrypted file**.
This file can be decrypted both by the **"processor"** and the **default** methods.I, perhaps, will not go into big details. You can always look at the code, or open the Issue and ask.
#
It seems that this is all. More detailed information about each method of each NonCipher class can be obtained using the built-in function Python `help(NonCipher)`.
**Open Issue, swear my English, and also don't forget - All programming languages is good;)**