Skip to content

Commit

Permalink
Call sodium_init(), skip AES-256-GCM benchmark if not supported
Browse files Browse the repository at this point in the history
--- Regarding sodium_init() ---

From https://libsodium.gitbook.io/doc/usage:

sodium_init() initializes the library and should be called before any other function provided by Sodium.

Interestingly, only the ChaCha20-Poly1305 benchmark was severely affected by the missing initialization: ~20 seconds instead of ~6.5 on my machine.

--- Regarding AES-256-GCM ---

From https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/aes-256-gcm:

The current implementation of this construction is hardware-accelerated and requires the Intel SSSE3 extensions, as well as the aesni and pclmul instructions.

Intel Westmere processors (introduced in 2010) and newer meet the requirements.

There are no plans to support non hardware-accelerated implementations of AES-GCM. If portability is a concern, use ChaCha20-Poly1305 instead.

Before using the functions below, hardware support for AES can be checked with:

int crypto_aead_aes256gcm_is_available(void);

The function returns 1 if the current CPU supports the AES256-GCM implementation, and 0 if it doesn't.

The library must have been initialized with sodium_init() prior to calling this function.
  • Loading branch information
davidebeatrici committed Dec 18, 2019
1 parent e105b22 commit 3e5ec2e
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions sodium.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@
#include <sodium.h>

bool sodium_main(const size_t message_size, const size_t iterations) {
if (sodium_init() == -1) {
printf("sodium_main(): sodium_init() failed!\n");
return false;
}

unsigned char message[message_size], out[message_size];
randombytes_buf(message, sizeof(message));

double elapsed;

if (!(elapsed = sodium_aes_256_gcm(iterations, out, sizeof(message), message))) {
printf("sodium_main(): sodium_aes_256_gcm() failed!\n");
return false;
}
if (crypto_aead_aes256gcm_is_available()) {
if (!(elapsed = sodium_aes_256_gcm(iterations, out, sizeof(message), message))) {
printf("sodium_main(): sodium_aes_256_gcm() failed!\n");
return false;
}

printf("[libsodium] AES-256-GCM took %f seconds for %zu iterations, %zu bytes message\n", elapsed, iterations, message_size);
printf("[libsodium] AES-256-GCM took %f seconds for %zu iterations, %zu bytes message\n", elapsed, iterations, message_size);
} else {
printf("[libsodium] skipping AES-256-GCM benchmark due to missing requirements. SSSE3 extensions, \"aesni\" and \"pclmul\" instructions are required.\n");
}

if (!(elapsed = sodium_chacha20_poly1305(iterations, out, sizeof(message), message))) {
printf("sodium_main(): sodium_chacha20_poly1305() failed!\n");
Expand Down

8 comments on commit 3e5ec2e

@jedisct1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If speed is a concern, you may want to use crypto_aead_aegis256_*() available in the current development code of libsodium.

@davidebeatrici
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you very much for your suggestion!

We're actually already quite happy with libsodium's results:

[OpenSSL] AES-256-GCM took 2.965976 seconds for 1000000 iterations, 4096 bytes message
[OpenSSL] AES-256-OCB took 2.413906 seconds for 1000000 iterations, 4096 bytes message
[OpenSSL] ChaCha20-Poly1305 took 4.417644 seconds for 1000000 iterations, 4096 bytes message
[libsodium] AES-256-GCM took 5.480515 seconds for 1000000 iterations, 4096 bytes message
[libsodium] ChaCha20-Poly1305 took 6.412273 seconds for 1000000 iterations, 4096 bytes message
[wolfCrypt] AES-256-GCM took 131.165997 seconds for 1000000 iterations, 4096 bytes message
[wolfCrypt] ChaCha20-Poly1305 took 28.554290 seconds for 1000000 iterations, 4096 bytes message

There's clearly something wrong with wolfCrypt's results, but right now we're definitely thinking about switching from OpenSSL to libsodium in Mumble.

crypto_aead_aegis256_*() is only for AES-256 (AEAD), correct? Is there something we can do in order to improve ChaCha20-Poly1305's performance?

@jedisct1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crypto_aead_aegis256 uses the AES core function in a mode that leverages the parallelism of modern CPUs. It's about 2 to 3 times faster than AES256-GCM on Intel and ARM CPUs.

@davidebeatrici
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's a huge improvement.

Can something similar be applied to ChaCha20-Poly1305 as well?

@jedisct1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not.

@davidebeatrici
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering that our packets are quite small (< 500 bytes), would you choose AES-256-GCM or ChaCha20-Poly1305?

@jedisct1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you need something that works on a wide range of platforms, use ChaChaPoly.

AES-GCM is also tricky to use correctly outside TLS.

AES-OCB has patents issues.

@davidebeatrici
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For anyone passing by, the discussion is at mumble-voip/mumble#3918.

Please sign in to comment.