Which API to use

HACL* APIs are specialized for a given architecture revision and do not have any agility overhead. Consider, for instance, Chacha-Poly encryption from Hacl_Chacha20Poly1305_256.h:


void
Hacl_Chacha20Poly1305_256_aead_encrypt(
  uint8_t *k,
  uint8_t *n,
  uint32_t aadlen,
  uint8_t *aad,
  uint32_t mlen,
  uint8_t *m,
  uint8_t *cipher,
  uint8_t *mac
);

In order to use this function, you must ascertain that the architecture you’re running on supports 256-bit vector instructions (AVX2 + SSE4); furthermore, your code will have to be changed if you need another AEAD algorithm such as AES-GCM. This is an efficient API, as it does not require any extra API calls and does not allocate any intermediary state.

EverCrypt APIs, on the other hand, can do CPU detection for clients, via a helper function found in EverCrypt_AutoConfig2.h.


void EverCrypt_AutoConfig2_init();

EverCrypt APIs are generally agile, i.e. clients only need to change one argument to a function call in order to use a different algorithm; furthermore, those APIs are multiplexing, i.e. they automatically pick the most suitable implementation based on he results of target CPU detection.

This means that the EverCrypt API for Chacha-Poly is found in EverCrypt_AEAD.h; clients are expected to first allocate state, passing in the desired AEAD algorithm as a parameter (agility):


EverCrypt_Error_error_code
EverCrypt_AEAD_create_in(Spec_Agile_AEAD_alg a, EverCrypt_AEAD_state_s **dst, uint8_t *k);

Then, will clients be able to encrypt:


EverCrypt_Error_error_code
EverCrypt_AEAD_encrypt(
  EverCrypt_AEAD_state_s *s,
  uint8_t *iv,
  uint32_t iv_len,
  uint8_t *ad,
  uint32_t ad_len,
  uint8_t *plain,
  uint32_t plain_len,
  uint8_t *cipher,
  uint8_t *tag
);