keepsimple1 / libaes

A small and fast AES cipher in safe Rust
Apache License 2.0
25 stars 1 forks source link

Support for CTR-128 mode #32

Open shijimasoft opened 10 months ago

shijimasoft commented 10 months ago

Hello again! I wanted to ask you if support for CTR-128 mode has been planned, was curious if you were already working on it or it is not planned anytime soon. Please let me know, thank you!

keepsimple1 commented 10 months ago

There is no plan for CTR-128 yet. If it's useful for you and you could contribute on it, that would be great!

shijimasoft commented 10 months ago

I would have gladly contributed, but I don't even know the basic math for encryption algorithms :_)

keepsimple1 commented 10 months ago

That's okay. Do you have a time line when you need this feature?

shijimasoft commented 10 months ago

At this time I am rewriting an old project using AES (CBC and CTR), I do not have an exact timeline, in the next few weeks I will be optimizing and re-implementing new portions of code, but it would certainly be great to have it soon. If you are interested give ctrdecrypt a quick check :)

keepsimple1 commented 10 months ago

Got it. I will take a closer look hopefully this weekend.

shijimasoft commented 10 months ago

Thank you so much :>

keepsimple1 commented 10 months ago

As CTR mode encryption could be parallelized and essentially works in a stream mode, what kind of API are you looking for? Any good examples from other languages / tools for CTR mode you wanted to follow?

shijimasoft commented 10 months ago

I searched the official PyCrypto documentation and found this: CounTeR (CTR). This mode is very similar to ECB, in that encryption of one block is done independently of all other blocks. Unlike ECB, the block position contributes to the encryption and no information leaks about symbol frequency.

Each message block is associated to a counter which must be unique across all messages that get encrypted with the same key (not just within the same message). The counter is as big as the block size (for 128-bit key it is 16 bytes).

Counters can be generated in several ways. The most straightword one is to choose an initial counter block (which can be made public, similarly to the IV for the other modes) and increment its lowest m bits by one (modulo 2^m) for each block. In most cases, m is chosen to be half the block size.

See NIST SP800-38A, Section 6.5 (for the mode) and Appendix B (for how to manage the initial counter block).

Practical example:

# Example from PyCrypto
from Crypto.Cipher import AES
from Crypto.Util import Counter

key = "c3b55cd549b6e47e91f6a212641e1cb3".decode('hex')
icounter = 20780279403903244019572234206052352
data = "9fdc5cc09bcbea918b62b915c9a4f9f8".decode('hex')

cipher = AES.new(key, AES.MODE_CTR, counter=Counter.new(128, initial_value=icounter))

# fe359918ef8fc93d8a19841fe8fb20e4
decdata = cipher.decrypt(data)

The AES function accepts an initial counter (which in Rust would be a u128 or an array of [u8; 16])

keepsimple1 commented 10 months ago

Thanks for the info. Adding a link: https://pycryptodome.readthedocs.io/en/latest/src/cipher/classic.html#ctr-mode and the counter module: https://pycryptodome.readthedocs.io/en/latest/src/util/util.html#crypto-util-counter-module

shijimasoft commented 10 months ago

Thank you too!

keepsimple1 commented 3 months ago

A reference implementation in C in OpenSSL: https://github.com/openssl/openssl/blob/master/crypto/modes/ctr128.c

shijimasoft commented 3 months ago

Hello! I took a look at the code, but it doesn't include the decrypt method, right?

shijimasoft commented 2 months ago

Sorry, never mind. I forgot that the CTR AES mode has identical encrypt and decrypt functions