int decrypt_final(riv_context_t* ctx, const unsigned char* ciphertext, const unsigned long long ciphertext_length, const unsigned char* header, const unsigned long long header_length, const unsigned char tag[TAGLEN], unsigned char* plaintext) { ALIGN(16) uint8_t iv[TAGLEN]; ALIGN(16) uint8_t iv_prime[TAGLEN]; clhash(&(ctx->prf_context), header, header_length, DOMAIN_1, ciphertext, ciphertext_length, iv); cdms(iv, iv, ctx->expanded_key); xor_bytes(iv, iv, tag, TAGLEN); cdms(iv_prime, iv, ctx->expanded_key); sct_mode(ctx, iv_prime, (const __m128i*)ciphertext, ciphertext_length, (__m128i*)plaintext); clhash(&(ctx->prf_context), header, header_length, DOMAIN_0, plaintext, ciphertext_length, iv_prime); cdms(iv_prime, iv_prime, ctx->expanded_key); return (_mm_testc_si128(load(iv), load(iv_prime)) - 1) | (_mm_testc_si128(load((iv+BLOCKLEN)), load((iv_prime+BLOCKLEN))) - 1); }
void encrypt_final(riv_context_t* ctx, const unsigned char* plaintext, const unsigned long long plaintext_length, const unsigned char* header, const unsigned long long header_length, unsigned char* ciphertext, unsigned char tag[TAGLEN]) { ALIGN(16) uint8_t iv[TAGLEN]; ALIGN(16) uint8_t s[TAGLEN]; clhash(&(ctx->prf_context), header, header_length, DOMAIN_0, plaintext, plaintext_length, iv); cdms(iv, iv, ctx->expanded_key); ALIGN(16) uint8_t iv_prime[TAGLEN]; cdms(iv_prime, iv, ctx->expanded_key); sct_mode(ctx, iv_prime, (const __m128i*)plaintext, plaintext_length, (__m128i*)ciphertext); clhash(&(ctx->prf_context), header, header_length, DOMAIN_1, ciphertext, plaintext_length, s); cdms(s, s, ctx->expanded_key); xor_bytes(tag, s, iv, TAGLEN); }
int main() { void * random = get_random_key_for_clhash(UINT64_C(0x23a23cf5033c3c81),UINT64_C(0xb3816f6a2c68e530)); uint64_t hashvalue1 = clhash(random,"my dog",6); uint64_t hashvalue2 = clhash(random,"my cat",6); uint64_t hashvalue3 = clhash(random,"my dog",6); assert(hashvalue1 == hashvalue3); assert(hashvalue1 != hashvalue2);// very likely to be true free(random); return 0; }
void encrypt_final(riv_context_t* ctx, const unsigned char* plaintext, const unsigned long long plaintext_length, const unsigned char* header, const unsigned long long header_length, unsigned char* ciphertext, unsigned char tag[TAGLEN]) { ALIGN(16) uint8_t iv[BLOCKLEN]; clhash(&(ctx->prf_context), header, header_length, DOMAIN_0, plaintext, plaintext_length, iv); const __m128i iv_ = aes_encrypt(load(iv), ctx->expanced_enc_key); encrypt(ctx, iv_, plaintext, plaintext_length, ciphertext); storeu(tag, iv_); }
int decrypt_final(riv_context_t* ctx, const unsigned char* ciphertext, const unsigned long long ciphertext_length, const unsigned char* header, const unsigned long long header_length, const unsigned char tag[TAGLEN], unsigned char* plaintext) { const __m128i iv = loadu(tag); decrypt(ctx, iv, plaintext, ciphertext_length, ciphertext); ALIGN(16) uint8_t iv_prime[BLOCKLEN]; clhash(&(ctx->prf_context), header, header_length, DOMAIN_0, plaintext, ciphertext_length, iv_prime); const __m128i iv_prime_ = aes_encrypt(load(iv_prime), ctx->expanced_enc_key); return _mm_testc_si128(iv, iv_prime_) - 1; }