Coder Social home page Coder Social logo

aeads's Issues

Eax release

Hi,
Could you make a new release or pre-release of the eax crate?
It would be nice to have a version that includes #231.
Thanks!

mgm: add soft32 backend

Currently we only support 64-bit software fallback, which can be quite inefficient on 32-bit targets.

Implement `Zeroize`

The type ChaCha20Poly1305 should implement Zeroize. Also, I do not sure if AesGcm should implement Zeroize too. It will allow the user to implement Zeroize for types containing them.

Update aead to v0.1.2

aes-gcm-siv fails to compile with latest version of aead.

   Compiling typenum v1.11.2
   Compiling subtle v2.2.1
   Compiling opaque-debug v0.2.3
   Compiling zeroize v1.0.0
   Compiling generic-array v0.12.3
   Compiling block-cipher-trait v0.6.2
   Compiling universal-hash v0.3.0
   Compiling aead v0.1.2
   Compiling polyval v0.3.1
   Compiling aesni v0.6.0
   Compiling aes v0.3.2
   Compiling aes-gcm-siv v0.2.1 (/Users/devashish/workspace/AEADs/aes-gcm-siv)
error[E0046]: not all trait items implemented, missing: `encrypt_in_place_detached`, `decrypt_in_place_detached`
   --> aes-gcm-siv/src/lib.rs:120:1
    |
120 | / impl<C> Aead for AesGcmSiv<C>
121 | | where
122 | |     C: BlockCipher<BlockSize = U16, ParBlocks = U8>,
123 | | {
...   |
159 | |     }
160 | | }
    | |_^ missing `encrypt_in_place_detached`, `decrypt_in_place_detached` in implementation
    |
    = note: `encrypt_in_place_detached` from trait: `fn(&Self, &generic_array::GenericArray<u8, <Self as aead::Aead>::NonceSize>, &[u8], &mut [u8]) -> core::result::Result<generic_array::GenericArray<u8, <Self as aead::Aead>::TagSize>, aead::Error>`
    = note: `decrypt_in_place_detached` from trait: `fn(&Self, &generic_array::GenericArray<u8, <Self as aead::Aead>::NonceSize>, &[u8], &mut [u8], &generic_array::GenericArray<u8, <Self as aead::Aead>::TagSize>) -> core::result::Result<(), aead::Error>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0046`.
error: could not compile `aes-gcm-siv`.

EAX unique nonce issue

EAX seems to only work if the same nonce is used between encryption and decryption, which defeats the purpose of a nonce. Using same nonce it works. Using different (uniquely generated) nonce I get the following: aead::Error

Please assist. Thank you

One-pass encryption/decryption

Currently all of the AEAD implementations do two passes over the plaintext/ciphertext when encrypting/decrypting respectively: for encryption, they encrypt the plaintext in the first pass, and authenticate it in the second pass. For decryption, it's vice versa.

A better approach is to pick a number of blocks to operate on in parallel and encrypt/authenticate or authenticate/decrypt in a single pass. This has better cache locality, e.g. when we encrypt data, store the resulting ciphertext, then load it again to do authentication, that is pretty much guaranteed to hit L1 cache when doing it in a single pass (and ideally we could hand off values still stored in e.g. SIMD registers)

This is a tracking issue for converting the implementations of these respective algorithms to be one pass. It also might be good to discuss ways we could have a generic implementation of one pass encryption/decryption in the aead crate (especially one specialized for the non-SIV stream-cipher + universal-hash use case) which can be reused across different algorithm implementations.

  • aes-gcm
  • aes-gcm-siv
  • aes-siv
  • chacha20poly1305
  • xsalsa20poly1305

†NOTE: SIV modes by definition cannot support 1-pass encryption (because the first pass generates the synthetic IV, which must be known in advance before encryption can be performed). However, they can support 1-pass decryption, since the IV is known in advance in that case.

Move ring-aead into a separate repository?

RustCrypto is generally for pure-Rust implementations, so ring-aead looks a bit out of place. We already have asm-hashes, so we are not completely puristic in this regard. Thus how about moving the crate into a separate repository? In future, if someone will be interested, we may add wrapper crates for other algorithm families as well.

E0599 Error when running aes_gcm example

Hello,

I updated aes_gcm to the newest version (0.5.0) and I get a E0599 error, which I was not getting on the previous version. The example is not working either. I tried

use aes_gcm::Aes256Gcm;
use aead::{Aead, NewAead, generic_array::GenericArray};

let key = GenericArray::clone_from_slice(b"an example very very secret key.");
let aead = Aes256Gcm::new(key);

let nonce = GenericArray::from_slice(b"unique nonce"); // 96-bits; unique per message
let ciphertext = aead.encrypt(nonce, b"plaintext message".as_ref()).expect("encryption failure!");
let plaintext = aead.decrypt(nonce, ciphertext.as_ref()).expect("decryption failure!");
assert_eq!(&plaintext, b"plaintext message");

And get the following error message:

no function or associated item named "new" found for struct `aes_gcm::AesGcm<aes_soft::impls::Aes256, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>` in the current scope
   --> src/tools/helpers.rs:29:27
    |
29  |       let aead = Aes256Gcm::new(key);
    |                             ^^^ function or associated item not found in `aes_gcm::AesGcm<aes_soft::impls::Aes256, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>>`
    | 
   ::: /home/.../.cargo/registry/src/github.com-1ecc6299db9ec823/aes-gcm-0.5.0/src/lib.rs:158:1
    |
158 | / pub struct AesGcm<B, N>
159 | | where
160 | |     B: BlockCipher<BlockSize = U16>,
161 | |     B::ParBlocks: ArrayLength<GenericArray<u8, B::BlockSize>>,
...   |
171 | |     nonce_size: PhantomData<N>,
172 | | }
    | | -
    | | |
    | | doesn't satisfy `_: digest::FixedOutput`
    | | doesn't satisfy `_: digest::Input`
    | | doesn't satisfy `_: digest::Reset`
    | |_doesn't satisfy `_: digest::digest::Digest`
    |   doesn't satisfy `_: std::default::Default`

I have the following cargo.toml:

aes-gcm = { version = "0.5.0", feature="aes" }
aead = "0.3.0"

Does anyone knows how I have to create the Aes256Gcm ?

Security of MGM

Apologies if this isn't the right place to ask this kind of thing, but I'm wondering precisely how secure MGM is? My research of it couldn't dig up anything about any audits that have been done on the algorithm or whether using it has any security implications. From my understanding of the paper it appears to be a cipher combinator of sorts, but I'm not an expert in crypto and since I'm blind the math in the paper was difficult to comprehend since its in a PDF and math never renders well in PDFs.
Can someone outline the security of the algorithm and when it would be beneficial to use?

Partial tag comparison

Hi,
I’m trying to use the eax crate to decrypt data with decrypt_in_place_detached but I only have the first 8 byte of the tag available as the network protocol I implement cuts off the other 8 byte of the 16 byte tag.
All aead functions expect the whole tag, so I can’t find a way to decrypt the data.

chacha20poly1305 is not no_std

Hey

It seems that somehow the alloc feature is pulled in even when it's disabled: Compiling https://github.com/nickray/chacha8poly1305-test (which I believe is using the library as intended) results in

% cargo build --target thumbv7em-none-eabi                 :(
   Compiling chacha20poly1305 v0.3.3
   Compiling chacha8poly1305-test v0.1.0 (/home/nicolas/projects/RustCrypto/chacha8poly1305-test)
error: no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait.                                                                                                                    

error: `#[alloc_error_handler]` function required, but not found

error: aborting due to 2 previous errors

error: could not compile `chacha8poly1305-test`.

I have not been able to track this down so far unfortunately.

Aes128Gcm get error

use aes_gcm::Aes128Gcm; // Or `Aes128Gcm` 
use aead::{Aead, NewAead, generic_array::GenericArray};  
let key = GenericArray::clone_from_slice(b"an example very very secret key."); 
let aead = Aes128Gcm::new(key);  
let nonce = GenericArray::from_slice(b"unique nonce"); // 96-bits; unique per message 
let ciphertext = aead.encrypt(nonce, b"plaintext message".as_ref()).expect("encryption failure!"); 
let plaintext = aead.decrypt(nonce, ciphertext.as_ref()).expect("decryption failure!"); 
assert_eq!(&plaintext, b"plaintext message");

get error

thread 'main' panicked at 'Slice must be the same length as the array', /Users/edison/.cargo/registry/src/github.com-1ecc6299db9ec823/generic-array-0.12.3/src/lib.rs:549:9

RustCrypto crates as an experimental impl for thrussh

Hi folks,

First of all, amazing work! Second, I am not sure if here is the right place to ask, since this is more a discussion than an issue. So forgive me if here is not the proper place.

A bit of context: thrussh is an implementation of the SSH 2 protocol, both server-side and client-side. It uses libsodium to provide chacha20, poly1305, ed25519 and scalarmult_curve25519 functionalities. Recently I wondered if one could add an experimental feature gate to test an alternative impl using RustCrypto.

What came up in the discussion was

  1. Are the RNGs robust to current computations (so a malicious agent cannot take advantage of them)?
  2. What you folks recommend to increase robustness, e.g., adding random timers around the crypto functions calls?

Finally, I would be thrilled to know your thoughts on this.

cc @P-E-Meunier

eax: allow variable length nonces

Similar to #62, except with EAX. I would like to be able to interoperate with an existing protocol that uses 32-bit nonces. Presumably this could be implemented similarly to #126, but I'm not familiar enough with the codebase to do it easily.

[doc] user specified associated data API

Currently documentation on trait aead::Aead and specific instantiation of AEAD suites only cover how to directly encrypt a message with (by default) an empty associated data field,

The Payload type can be used to provide Additional Associated Data (AAD) along with the message: this is an optional bytestring which is not encrypted, but is authenticated along with the message. Failure to pass the same AAD that was used during encryption will cause decryption to fail, which is useful if you would like to "bind" the ciphertext to some other identifier, like a digital signature key or other identifier.

If I construct my own Payload with msg and aad specified, then how to pass to the encrypt() function is not so clear to me, cuz Payload itself doesn't implement Into<Payload>.

I could be misunderstanding things, but maybe some examples in the documentation would be helpful.
Thanks!

Stream data to cipher

Hello,

Is it possible to stream in data to cipher to avoid having to have all the data in memory to pass it though the AEAD? Something like (in pseudocode)

 aead = AEAD::new(mode, nonce)
 while plaindata = plainfile.read(1024) {
  cipherfile.write(aead.encrypt(plaindata))
}
cipherfile.write(aead.close_and_flush())

How could I do this if the file is several gigs in size and I don't have that much mem?

Thanks in advance,

Use parallel block processing in CCM

Right now implementation in the ccm crate does not use encrypt_blocks/decrypt_blocks methods, even though the CTR part can win from it significantly. But unfortunately the variable nonce size makes it less trivial to do it efficiently (max nonce size is 13 bytes).

aes-gcm: Allow variable sized nonce at runtime

In Deno, WebCrypto nonces are coming from JavaScript at runtime and so generic compile-time nonces are not possible without setting a restriction on the user (Some packages in the Node ecosystem like cryptr use 128bit IVs instead of 96bit).

It would be nice to have a non-generic-array based API for use cases like this :-)

GCM: encrypt with `Read` / allow for several call

Hi RustCrypto team,

First, thanks for your AES-GCM implementation.
I run into an issue, and I would like to know if I'm missing something.

I would like to split my calls to the AES-GCM cipher, ie. beeing able to perform a AES-GCM("key", "nonce", "plaintext part1") + AES-GCM("key", "nonce", "plaintext part2") and obtain as a result the tag and the cipher corresponding to AES-GCM("key", "nonce", "plaintext part1plaintext part2").

The goal is to be able to consume a Read trait and produce the corresponding encrypted output as a stream. And, of course, once the source is closing, the tag can be finally added. It could also take the form of a seek like API, giving the CTR counter and the current tag.

Is it a behavior too custom for this lib (and then, I should implement it on my own), or am I missing something?

Crypto_Box doesn't compile on No_Std target

I am building a PoC on a STM32 Nucleo board and want to use the Crypto_Box crate. The problem is that when I include it like:
crypto_box = {version = "0.5", default-features = false, features = ["heapless","u64_backend"]}, I get the following error when I try to compile it:

Compiling getrandom v0.1.15
error[E0463]: can't find crate for `std`
 --> C:\Users\Tristan\.cargo\registry\src\github.com-1ecc6299db9ec823\getrandom-0.1.15\src\error_impls.rs:8:1
  |
8 | extern crate std;
  | ^^^^^^^^^^^^^^^^^ can't find crate

I'm not sure what features I need to include/exclude.

convert slice to GenericArray paniced

use aes_gcm_siv::aead::{generic_array::GenericArray, Aead, NewAead};
use aes_gcm_siv::Aes256GcmSiv;
use rand::{thread_rng, Rng};

pub const NONCE_LENGTH: usize = 12;

pub fn main() {
    let key = "secret-key".as_bytes();
    let msg = "message content".as_bytes();
    encrypt(key, msg);
}

pub fn encrypt(key: &[u8], plain_txt_msg: &[u8]) -> Result<Vec<u8>,String> {
    let key = GenericArray::from_slice(key);
    let cipher = Aes256GcmSiv::new(key);
    let random_bytes = generate_random_bytes();
    let nonce = GenericArray::from_slice(&random_bytes);
    let encrypt_msg = cipher
        .encrypt(nonce, plain_txt_msg)
        .map_err(|e| e.to_string())?;
    let mut cipher_msg = Vec::new();
    cipher_msg.extend_from_slice(&random_bytes);
    cipher_msg.extend(encrypt_msg);
    Ok(cipher_msg)
}

pub fn decrypt(key: &[u8], cipher_msg: &[u8]) -> Result<Vec<u8>,String> {
    if cipher_msg.len() <= NONCE_LENGTH {
        return Err("msg is invalid".into());
    }
    let key = GenericArray::from_slice(key);
    let cipher = Aes256GcmSiv::new(key);
    let nonce = GenericArray::from_slice(&cipher_msg[..NONCE_LENGTH]);
    let plain_txt_msg = cipher
        .decrypt(nonce, &cipher_msg[NONCE_LENGTH..])
        .map_err(|e| e.to_string())?;
    Ok(plain_txt_msg)
}

pub fn generate_random_bytes() -> [u8; NONCE_LENGTH] {
    thread_rng().gen::<[u8; NONCE_LENGTH]>()
}

thread 'main' panicked at 'assertion failed: (left == right)left:10, right: 32', /home/username/.cargo/registry/src/github.com-1ecc6299db9ec823/generic-array-0.14.4/src/lib.rs:559:9 note: run with RUST_BACKTRACE=1environment variable to display a backtrace

Missing algorithms

  • AEGIS
  • AES-GCM
    • XAES-256-GCM
  • Deoxys-II (#311)
  • Multilinear Galois Mode
  • OCB3 (#587)
  • Reduced round XChaChaPoly
    • XChaCha8Poly1305
    • XChaCha12Poly1305

crypto_box: move into a separate repository?

The crypto_box crate feels a bit out of place in this repository since it includes bits of public key cryptography.

It could be worth to move it into a separate repository. We could dedicate this repository to emulation of NaCl/libsodium APIs using our crates as a pure-Rust backend. In a certain sense it will be like ring-compat, but in reverse.

Key comitting AEADs

It's maybe too soon to consider this here, but..

There are a few recent standards that started including key committing AEADs, notable anything extremely low-entropy like OPAQUE.
https://eprint.iacr.org/2017/664.pdf
https://eprint.iacr.org/2020/1491.pdf
https://eprint.iacr.org/2020/1153.pdf

There remain some gaps in the literature, like encrypt-then-MAC with either a KDF or KEX that yields a common encryption and MAC key sounds more committing than any of those articles indicates, and is already fairly standard practice.

Encryption For ChaCha20 Fails With Nonce

Hi,

I was trying to encrypt text with ChaCha20-Poly1305 but it is giving me errors with the encryption function. Here is the code.

mod chacha20 {
    use crate::random::OSRandom;

    pub struct ChaCha20Encryption;

    use chacha20poly1305::{XChaCha20Poly1305, Key, Nonce}; // Or `XChaCha20Poly1305`
    use chacha20poly1305::aead::{Aead, NewAead};

    impl ChaCha20Encryption {
        pub fn encrypt(password: String, data: String){
            let mut bytes = [0u8; 64];

            hex::decode_to_slice(password, &mut bytes as &mut [u8]).expect("Failed To Decode Hexadecimal");

            let key = Key::from_slice(&bytes); // 32-bytes
            let cipher = XChaCha20Poly1305::new(key);

            let nonce = Nonce::from_slice(&OSRandom::rand_12().expect("Failed")); // 12-bytes; unique per message

            let ciphertext = cipher.encrypt(nonce,data.as_ref()).expect("Encryption Failure");
        }

    }
}

Hope you can fix this.

Traits in `ccm` are private

Hi,

I think it's intentional, but the traits in the ccm crate (i.e. this file) are private since the module they're in is not reexported in lib.rs.

I'd like to implement a function that is generic over CCMs, but would have to implement structs for each size, either manually or with a macro since I cannot use the traits to constrain my generics.

Is there any way around this?

Kind regards,

Jona

crypto_box rand version is lagging

rand 0.8.0 breaks the crypto_box examples.

This could potentially be resolved with pub extern crate rand to remove any ambiguity with the rand versioning and allow for let mut rng = crypto_box::rand::thread_rng();

blocked PRs from depend bot show the same errors I encountered myself, so I won't regurgitate them here.

Would you consider API without the Authentication part?

We have a use case where we would like to encrypt a user's private signing key with a symmetric cypher with Associated Data, but without the Authentication part.

In particular, and to support the argument for such API, the use case is as follows: every user in our app has a private signing key that is stored in a local database encrypted with a symmetric cypher (we're using your ChaCha20Poly1305 ATM). We also have a Merkle Tree like structure that lists public signing keys of users which have some special privilege.

What we'd like is for the user to have the plausible deniability argument when claiming they do not have that special privilege. That is, the user should be able to "decrypt" the private key with a bogus symmetric key. This "decryption" would then yield a bogus private signing key for which the corresponding public key is not present in the Merkle Tree structure. This - of course - can't be done with the Authentication in place.

With this issue I'm mainly trying to find out whether the maintainers of this repository would be willing to accept such API changes. Or perhaps there is a better suited library/cypher we should be using instead?

Feature request: authenticate without encrypting

Hi !
I would like to build a network protocol secured by AES GCM. I have to send the length of the payload before the payload itself so that the receiver knows how much data he should expect in the transmission. With your implementation, the problem is, as far as I know, I can't authenticate data without encrypting. I saw that the python PyCryptodome lib can do this with the AES.update() method. Does your lib provide such a method ?
If not, what can I do ? Do you plan to implement this method ?

Thanks

Fails To Encrypt With AES

Hi,

I have been receiving errors when running the aes and chacha20 encryption algorithms.

impl AESEncryption {
    pub fn encrypt(password: String, data: String){
        let pass = hex::decode(password).expect("Failed To Decode Hexadecimal");

        let key = Key::from_slice(&pass); // 32-bytes
        let cipher = Aes256Gcm::new(key);


        // Nonce (256 bits)
        let randomness = OSRandom::rand_32().expect("Failed");
        let nonce = Nonce::from_slice(&randomness); // 12-bytes; unique per message

        let text = b"plaintext message";
        let ciphertext = cipher.encrypt(nonce,text.as_ref()).expect("Encryption Failure");
    }

}

Here is the error

running 1 test
thread 'tests::aes_test' panicked at 'assertion failed: `(left == right)`
  left: `32`,
 right: `12`', /Users/0xsilene/.cargo/registry/src/github.com-1ecc6299db9ec823/generic-array-0.14.4/src/lib.rs:559:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14
   2: core::panicking::assert_failed_inner
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:160:17
   3: core::panicking::assert_failed
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:117:5
   4: <&generic_array::GenericArray<T,N> as core::convert::From<&[T]>>::from
             at /Users/0xsilene/.cargo/registry/src/github.com-1ecc6299db9ec823/generic-array-0.14.4/src/lib.rs:559:9
   5: <T as core::convert::Into<U>>::into
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/convert/mod.rs:538:9
   6: generic_array::GenericArray<T,N>::from_slice
             at /Users/0xsilene/.cargo/registry/src/github.com-1ecc6299db9ec823/generic-array-0.14.4/src/lib.rs:541:9
   7: EncryptMyFiles::aes::AESEncryption::encrypt
             at ./src/aes.rs:47:21
   8: aes::tests::aes_test
             at ./tests/aes.rs:7:9
   9: aes::tests::aes_test::{{closure}}
             at ./tests/aes.rs:6:5
  10: core::ops::function::FnOnce::call_once
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5
  11: core::ops::function::FnOnce::call_once
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test tests::aes_test ... FAILED

failures:

failures:
    tests::aes_test

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s

error: test failed, to rerun pass '--test aes'
The terminal process "/bin/bash '-c', 'cargo test -- --nocapture aes_test'" terminated with exit code: 101.

Thanks.

ChaCha20Poly1305 doesn't build with 'heapless' enabled when targetting riscv32i-unknown-none-elf

When I add ChaCha20Poly1305 (version 0.9.0) as a dependency:

[dependencies]
chacha20poly1305 = { version = "0.9.0", features = ["heapless"] }

and include it in the code (use chacha20poly1305) I get the following error:

   Compiling heapless v0.7.10
error[E0432]: unresolved import `atomic_polyfill`
  --> /home/kriskras99/.cargo/registry/src/github.com-1ecc6299db9ec823/heapless-0.7.10/src/spsc.rs:90:5
   |
90 | use atomic_polyfill::{AtomicUsize, Ordering};
   |     ^^^^^^^^^^^^^^^ use of undeclared crate or module `atomic_polyfill`

For more information about this error, try `rustc --explain E0432`.
error: could not compile `heapless` due to previous error

I think something is going wrong with heapless' features, but I'm not entirely sure.
I made an MVP repo where you can reproduce the issue by executing cargo build (assuming you have the riscv32i-unknown-none-elf target installed).

Outdated version of zeroize forced in aes-gcm-siv

Currently the version of zeroize is required to be < 1.4 which conflicts with the latest version of secrecy, which needs zeroice to be >= 1.4.

Is there a reason why zeroize is explicitly needed in that version, or can it be updated?

A constant-time version of aes-gcm decrypt-in-place-detached?

Hi, I have a use-case that is roughly the following (simplified):

  • A private key exists only in an SGX enclave
  • A stream of ciphertexts are passed to the enclave, which it attempts to decrypt
  • It must remain a secret which ones were decryptable by the enclave and which ones aren't, taking into account side-channel leakage via code and data access patterns.

Unfortunately I can't quite do that with the aes-gcm code as is:

    fn decrypt_in_place_detached(
        &self,
        nonce: &GenericArray<u8, NonceSize>,
        associated_data: &[u8],
        buffer: &mut [u8],
        tag: &Tag,
    ) -> Result<(), Error> {
        if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX {
            return Err(Error);
        }

        // TODO(tarcieri): interleave encryption with GHASH
        // See: <https://github.com/RustCrypto/AEADs/issues/74>
        let mut expected_tag = self.compute_tag(associated_data, buffer);
        let mut ctr = self.init_ctr(nonce);
        ctr.apply_keystream(&self.cipher, expected_tag.as_mut_slice());

        use subtle::ConstantTimeEq;
        if expected_tag.ct_eq(&tag).unwrap_u8() == 1 {
            ctr.apply_keystream(&self.cipher, buffer);
            Ok(())
        } else {
            Err(Error)
        }
    }

What I would really like is a version of this function that looks like this for example:

    fn ct_decrypt_in_place_detached(
        &self,
        nonce: &GenericArray<u8, NonceSize>,
        associated_data: &[u8],
        buffer: &mut [u8],
        tag: &Tag,
    ) -> bool {
        if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX {
            return false;
        }

        // TODO(tarcieri): interleave encryption with GHASH
        // See: <https://github.com/RustCrypto/AEADs/issues/74>
        let mut expected_tag = self.compute_tag(associated_data, buffer);
        let mut ctr = self.init_ctr(nonce);
        ctr.apply_keystream(&self.cipher, expected_tag.as_mut_slice());
        ctr.apply_keystream(&self.cipher, buffer);

        use subtle::ConstantTimeEq;
        bool::from(expected_tag.ct_eq(&tag))
    }

The key differences being:

  • ctr.apply_keystream(&self.cipher, buffer); happens unconditionally and we never branch on the outcome of mac check
  • Instead of returning Result, we return bool, or perhaps some subtle type. Because afaik there is no branchless way to access Result. (I don't know that I can assume that result.is_ok() won't contain a branch? I assume it boils down to a rust match against an enum, and would contain a branch unless the compiler optimized the branch away. I would hope that llvm can optimize this though.) But also, it's not clear that in rust, you can create Result type without branching?

What do you think? Would you take a patch that
(1) Adds ct_detached_in_place_decrypt to trait AeadInPlace in RustCrypto/traits? (and possibly, makes detached_in_place_decrypt chain to this by default?)
OR
(2) Adds a new trait AeadInPlaceCt or similar in RustCrypto/traits , and adds the function there, and implements it on AesGcm struct?

Slight preference for not putting subtle types in an API because it will ease versioning?

aes-gcm: performance is worse than OpenSSL

As my test via cargo bench, the aes-gcm-256's performance is much worse:

     Running target/release/deps/simple-75040055ea8811ad
Gnuplot not found, using plotters backend
encrypt 100M            time:   [174.63 ms 175.52 ms 176.60 ms]
                        change: [+128.80% +133.74% +138.22%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 1 outliers among 10 measurements (10.00%)
  1 (10.00%) high mild

decrypt 100M            time:   [137.44 ms 138.20 ms 138.90 ms]
                        change: [+291.03% +294.15% +297.13%] (p = 0.00 < 0.05)
                        Performance has regressed.

It was built with export RUSTFLAGS="-Ctarget-cpu=sandybridge -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3" as documented.

For OpenSSL:

     Running target/release/deps/simple-8072f89159d02aed
Gnuplot not found, using plotters backend
encrypt 100M            time:   [73.289 ms 73.619 ms 74.055 ms]
                        change: [-2.1748% -0.9188% +0.3013%] (p = 0.18 > 0.05)
                        No change in performance detected.
Found 1 outliers among 10 measurements (10.00%)
  1 (10.00%) high mild

decrypt 100M            time:   [35.428 ms 35.591 ms 35.757 ms]
                        change: [-0.3106% +0.1991% +0.7224%] (p = 0.47 > 0.05)
                        No change in performance detected.

Environment:

iMac (Retina 5K, 27-inch, 2019), 3.7 GHz 6-Core Intel Core i5

how to use diffrent length sample data

hey man i've tried everything but i still can t use any string other then "plaintext message" as bytes i am guessing it have something to do with block size of 128 bits and padding but please can you help my goal if to encrypt any length of message.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.