Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Tiny benchmark program for picotls-fusion
/*
* Copyright (c) 2020 Fastly, Kazuho Oku
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include "picotls/fusion.h"
int main(int argc, char **argv)
{
static const uint8_t key[16] = {}, aad[13] = {};
size_t textlen = 16384;
ptls_aead_supplementary_encryption_t *supp = NULL;
int ch, non_temporal = 0, decrypt = 0, count = 1000000, split = 0;
while ((ch = getopt(argc, argv, "2b:dn:sSth")) != -1) {
switch (ch) {
case '2':
ptls_fusion_can_avx256 = 1;
break;
case 'b':
if (sscanf(optarg, "%zu", &textlen) != 1) {
fprintf(stderr, "failed to parse the number of bytes given by `-b`\n");
exit(1);
}
break;
case 'd':
decrypt = 1;
break;
case 'n':
if (sscanf(optarg, "%d", &count) != 1) {
fprintf(stderr, "failed to parse the number given by `-n`\n");
exit(1);
}
break;
case 's': {
static const uint8_t k[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
supp = malloc(sizeof(*supp));
supp->ctx = ptls_cipher_new(&ptls_fusion_aes128ctr, 1, k);
} break;
case 'S':
split = 1;
break;
case 't':
non_temporal = 1;
break;
default:
printf("Usage: %s -b <bytes> -s\n"
"Options:\n"
" -b <bytes> specifies the size of the AEAD payload\n"
" -d test decryption\n"
" -n <count> number of iterations\n"
" -s if set, runs the benchmark with supplemental vector\n"
" -t test non-temporal engine\n",
argv[0]);
return 0;
}
}
argc -= optind;
argv += optind;
uint8_t *text = malloc(textlen + 16), *encrypted = split ? aligned_alloc(64, (textlen + 16 + 63) / 64 * 64) : text;
memset(text, 0, textlen + 16);
if (supp != NULL)
supp->input = textlen >= 2 ? text + 2 : text + textlen;
if (!non_temporal) {
ptls_fusion_aesgcm_context_t *ctx = ptls_fusion_aesgcm_new(key, sizeof(key), sizeof(aad) + textlen);
if (!decrypt) {
for (int i = 0; i < count; ++i)
ptls_fusion_aesgcm_encrypt(ctx, encrypted, text, textlen, _mm_setzero_si128(), aad, sizeof(aad), supp);
} else {
uint8_t tag[16] = {};
for (int i = 0; i < count; ++i)
ptls_fusion_aesgcm_decrypt(ctx, text, text, textlen, _mm_setzero_si128(), aad, sizeof(aad), &tag);
}
} else {
uint8_t iv[PTLS_MAX_IV_SIZE] = {};
ptls_aead_context_t *ctx = ptls_aead_new_direct(&ptls_non_temporal_aes128gcm, !decrypt, key, iv);
if (!decrypt) {
for (int i = 0; i < count; ++i)
ptls_aead_encrypt(ctx, encrypted, text, textlen, 0, aad, sizeof(aad));
} else {
for (int i = 0; i < count; ++i)
ptls_aead_decrypt(ctx, encrypted, text, textlen, 0, aad, sizeof(aad));
}
}
for (int i = 0; i < 16; ++i)
printf("%02x", text[i]);
printf("\n");
for (int i = 0; i < 16; ++i)
printf("%02x", text[textlen + i]);
printf("\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment