pyrogram / tgcrypto

Fast and Portable Cryptography Extension Library for Pyrogram
https://pyrogram.org
GNU Lesser General Public License v3.0
175 stars 41 forks source link

ctr256_encrypt and ctr256_decrypt usage examples #4

Closed richard-scott closed 5 years ago

richard-scott commented 5 years ago

Sample code to create core dump in 'example.py'

import os
import tgcrypto

data = os.urandom(10 * 1024 * 1024)  # 10 MB of random data
key = os.urandom(32)  # Random Key
iv = os.urandom(32)  # Random IV

ctr_encrypted = tgcrypto.ctr256_encrypt(data, key, iv)
ctr_decrypted = tgcrypto.ctr256_decrypt(ctr_encrypted, key, iv)

print(data == ctr_decrypted)

Running the code:

$ python3 example.py
Segmentation fault (core dumped)

Change the "ctr" to "ige" and all works as expected.

delivrance commented 5 years ago

Change the "ctr" to "ige" and all works as expected.

Of course! It's a different AES mode and thus works slightly differently:

  1. First of all, there's a new extra parameter, state, needed for the CTR mode in order to make it a truly stream cipher. state is useless in case you want to enc/decrypt blocks within a single method call, but you must pass it. Can be a single byte: tgcrypto.ctr256_encrypt(data, key, iv, bytes(1)).

  2. The iv length in CTR mode equals the length of the block size (16 bytes =128 bits), but the extra bytes you are passing won't mess anything as they are simply ignored.

  3. During enc/decryption both iv and state will be modified; you are actually using a different iv when you call ctr256_decrypt.

Here's a full, working example which uses state and the same iv for both enc/decryption:

import os
import tgcrypto

data = os.urandom(10 * 1024 * 1024)  # 10 MB of random data
key = os.urandom(32)  # Random Key
iv = bytearray(16)  # Reserve 16 bytes for the IV
iv_copy = bytearray(16)  # Reserve 16 more bytes for the copy
iv[:] = os.urandom(16)  # Random IV
iv_copy[:] = iv  # Copy IV

ctr_encrypted = tgcrypto.ctr256_encrypt(data, key, iv, bytes(1))
ctr_decrypted = tgcrypto.ctr256_decrypt(ctr_encrypted, key, iv_copy, bytes(1))

print(data == ctr_decrypted)  # True
richard-scott commented 5 years ago

Thanks for the clarification, it works now :-)