// bcrypt-test.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <wincompat.h>
#include <bcrypt.h>
#include <stdio.h>
#include "picotls/ptlsbcrypt.h"
#include "picotls/minicrypto.h"

int KeyInit(BCRYPT_KEY_HANDLE *hKey, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz, const BYTE *proposedKey,
            DWORD proposedKeyLength, BYTE **ko, ULONG *ko_length)
{
    DWORD cbData = 0;
    HANDLE hAlgo = NULL;

    // Open an algorithm handle.
    NTSTATUS ret = BCryptOpenAlgorithmProvider(&hAlgo, name, NULL, 0);

    if (BCRYPT_SUCCESS(ret)) {
        // Set the properties to define the chaining mode
        ret = BCryptSetProperty(hAlgo, BCRYPT_CHAINING_MODE, (PBYTE)chain_mode, (ULONG)chain_mode_sz, 0);
    }

    *ko = NULL;
    *ko_length = 0;

    if (BCRYPT_SUCCESS(ret)) {
        DWORD ko_size = 0;
        ULONG cbResult = 0;

        ret = BCryptGetProperty(hAlgo, BCRYPT_OBJECT_LENGTH, (PUCHAR)&ko_size, (ULONG)sizeof(ko_size), &cbResult, 0);

        if (BCRYPT_SUCCESS(ret)) {
            *ko = (uint8_t *)malloc(ko_size);
            if (*ko == NULL) {
                ret = STATUS_NO_MEMORY;
            } else {
                *ko_length = ko_size;
                memset(*ko, 0, *ko_length);
            }
        }
    }

    if (BCRYPT_SUCCESS(ret)) {
        // Generate the key from supplied input key bytes.
        ret = BCryptGenerateSymmetricKey(hAlgo, hKey, *ko, *ko_length, (PBYTE)proposedKey, proposedKeyLength, 0);
    } else {
        if (*ko != NULL) {
            free(*ko);
            *ko = NULL;
            *ko_length = 0;
        }
    }

    if (hAlgo != NULL) {
        BCryptCloseAlgorithmProvider(hAlgo, 0);
    }

    return BCRYPT_SUCCESS(ret) ? 0 : -1;
}

void KeyRelease(BCRYPT_KEY_HANDLE *hKey, BYTE **ko, ULONG *ko_length)
{
    BCryptDestroyKey(*hKey);
    *hKey = NULL;
    if (*ko) {
        free(*ko);
    }
    *ko = NULL;
    *ko_length = 0;
}

int EncodeOneShot(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz, BYTE *key,
                  ULONG key_length,
    BYTE* iv, ULONG iv_length,
    BYTE *data, ULONG dataLength, uint64_t seq, BYTE *authData, ULONG authDataLength, ULONG authTagLength,
    BYTE *encrypted, ULONG encryptedLengthMax, ULONG *encryptedLength)
{

    BCRYPT_KEY_HANDLE hKey = NULL;
    BYTE *authTag = encrypted + dataLength;
    BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO bacmi;
    BYTE iv_nonce[PTLS_MAX_IV_SIZE];
    BYTE *ko = NULL;
    ULONG ko_length = 0;
    int ret = 0;

    *encryptedLength = 0;

    if (KeyInit(&hKey, name, chain_mode, chain_mode_sz, key, key_length, &ko, &ko_length) != 0) {
        return -1;
    }

    memset(authTag, 0, authTagLength);
    // Set the auth mode info for AEAD
    BCRYPT_INIT_AUTH_MODE_INFO(bacmi);
    ptls_aead__build_iv(aead, iv_nonce, iv, seq);
    bacmi.pbNonce = iv_nonce;
    bacmi.cbNonce = iv_length;
    bacmi.pbAuthData = authData;
    bacmi.cbAuthData = authDataLength;
    bacmi.pbTag = authTag;
    bacmi.cbTag = authTagLength;
    /* All other fields are set to NULL by the INIT macro. */

    /* If called with a NULL pointer for the data block, we will merely compute the block size. */
    DWORD cbCipherText = 0;
    NTSTATUS status = BCryptEncrypt(hKey, data, dataLength, &bacmi, NULL, 0, encrypted, encryptedLengthMax, &cbCipherText, 0);

    KeyRelease(&hKey, &ko, &ko_length);

    if (BCRYPT_SUCCESS(status)) {
        *encryptedLength = cbCipherText + authTagLength;
    } else {
        ret = -1;
    }

    return ret;
}

int DecodeOneShot(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz, 
    BYTE *key, ULONG key_length, BYTE * iv, ULONG iv_length, BYTE *encrypted,
                  ULONG encryptedLength, uint64_t seq, BYTE *authData, ULONG authDataLength,
                  ULONG authTagLength, BYTE *decrypted, ULONG decryptedLengthMax, ULONG *decryptedLength)
{

    BCRYPT_KEY_HANDLE hKey = NULL;
    BYTE *authTag = encrypted + (encryptedLength - authTagLength);
    BYTE iv_nonce[PTLS_MAX_IV_SIZE];
    BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO bacmi;
    BYTE *ko = NULL;
    ULONG ko_length = 0;
    int ret = 0;

    *decryptedLength = 0;

    if (KeyInit(&hKey, name, chain_mode, chain_mode_sz, key, key_length, &ko, &ko_length) != 0) {
        return -1;
    }

    // Set the auth mode info for AEAD
    BCRYPT_INIT_AUTH_MODE_INFO(bacmi);
    ptls_aead__build_iv(aead, iv_nonce, iv, seq);
    bacmi.pbNonce = iv_nonce;
    bacmi.cbNonce = iv_length;
    bacmi.pbAuthData = authData;
    bacmi.cbAuthData = authDataLength;
    bacmi.pbTag = authTag;
    bacmi.cbTag = authTagLength;
    /* All other fields are set to NULL by the INIT macro. */

    /* If called with a NULL pointer for the data block, we will merely compute the block size. */
    DWORD cbCipherText = 0;
    NTSTATUS status = BCryptDecrypt(hKey, encrypted, encryptedLength - authTagLength, &bacmi, NULL, 0, decrypted,
                                    decryptedLengthMax, &cbCipherText, 0);

    KeyRelease(&hKey, &ko, &ko_length);

    if (BCRYPT_SUCCESS(status)) {
        *decryptedLength = cbCipherText;
    } else {
        ret = -1;
    }

    return ret;
}

int test_oneshot(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE data[123];
    BYTE iv[PTLS_MAX_IV_SIZE];
    uint64_t nonce;
    BYTE authData[9];
    BYTE encrypted[256];
    ULONG encryptedLength;
    BYTE decrypted[256];
    ULONG decryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(iv) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(decrypted) >= sizeof(encrypted));

    memset(key, 'k', sizeof(key));
    memset(data, 'd', sizeof(data));
    memset(iv, 'n', sizeof(iv));
    nonce = 0;
    memset(authData, 'a', sizeof(authData));

    ret = EncodeOneShot(aead, name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, iv, (ULONG)aead->iv_size, data,
        123, nonce, authData, 9, authTagLength, encrypted, 256, &encryptedLength);

    printf("Encrypt one shot returns %d, l=%d\n", ret, encryptedLength);

    if (ret == 0) {
        ret = DecodeOneShot(aead, name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, 
            iv, (ULONG)aead->iv_size, encrypted, encryptedLength, nonce, authData, 9, 
            authTagLength, decrypted, 256, &decryptedLength);

        printf("Decrypt one shot returns %d, l=%d\n", ret, decryptedLength);

        if (ret == 0) {
            if (decryptedLength != 123) {
                printf("Wrong length, not %d\n", 123);
                ret = -1;
            } else if (memcmp(data, decrypted, 123) != 0) {
                printf("Data and decrypted don't match\n");
                ret = -1;
            } else {
                printf("One shot matches.\n");
            }
        }
    }

    return ret;
}

void delete_test_aead_context(ptls_aead_context_t *ctx)
{
    if (ctx != NULL) {
        ctx->dispose_crypto(ctx);
        free(ctx);
    }
}

ptls_aead_context_t *new_test_aead_context(ptls_aead_algorithm_t *aead, int is_enc, BYTE *key, BYTE *iv)
{
    int ret = 0;
    ptls_aead_context_t *ctx = (ptls_aead_context_t *)malloc(aead->context_size);

    if (ctx != NULL) {
        memset(ctx, 0, aead->context_size);
        *ctx = (ptls_aead_context_t){aead};
        if (aead->setup_crypto(ctx, is_enc, key, iv) != 0) {
            printf("For %s, setup returns %d\n", aead->name, ret);
            delete_test_aead_context(ctx);
            ctx = NULL;
        }
    } else {
        printf("For %s, memory error during setup\n", aead->name);
    }

    return (ctx);
}

int test_decrypt(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE iv[PTLS_MAX_IV_SIZE];
    BYTE data[123];
    uint64_t nonce;
    BYTE authData[9];
    BYTE encrypted[256];
    ULONG encryptedLength;
    BYTE decrypted[256];
    size_t decryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx = NULL;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(iv) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(decrypted) >= sizeof(encrypted));

    memset(key, 'k', sizeof(key));
    memset(iv, 'n', sizeof(iv));
    memset(data, 'd', sizeof(data));
    nonce = 0;
    memset(authData, 'a', sizeof(authData));

    /* Create a decryption context */
    ctx = new_test_aead_context(aead, 0, key, iv);
    if (ctx == NULL) {
        ret = -1;
    }

    /* Do a simple encrypt using one shot bcrypt */
    if (ret == 0) {
        ret = EncodeOneShot(aead, name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, 
            iv, (ULONG)aead->iv_size, data, 123, nonce,
            authData, 9, authTagLength, encrypted, 256, &encryptedLength);
    }

    /* Try decrypt with library procedure */
    if (ret == 0) {
        decryptedLength = ctx->do_decrypt(ctx, decrypted, encrypted, encryptedLength, nonce, authData, 9);
        if (decryptedLength >= encryptedLength) {
            printf("For %s, decrypt returns %d\n", aead->name, (int)decryptedLength);
            ret = -1;
        } else if (decryptedLength != 123) {
            printf("For %s, decrypt returns %d instead of %d\n", aead->name, (int)decryptedLength, 123);
            ret = -1;
        } else if (memcmp(data, decrypted, decryptedLength) != 0) {
            printf("For %s, decrypted does not match clear text\n", aead->name);
            ret = -1;
        } else {
            printf("For %s, decrypting test passes.\n", aead->name);
        }
    }

    delete_test_aead_context(ctx);

    return ret;
}

int test_encrypt(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE iv[PTLS_MAX_IV_SIZE];
    BYTE data[123];
    uint64_t nonce;
    BYTE authData[9];
    BYTE encryptedRef[256];
    ULONG encryptedRefLength;
    BYTE encrypted[256];
    size_t encryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx = NULL;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(iv) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(data) + authTagLength <= sizeof(encryptedRef));

    memset(key, 'k', sizeof(key));
    memset(iv, 'n', sizeof(iv));
    memset(data, 'd', sizeof(data));
    nonce = 0;
    memset(authData, 'a', sizeof(authData));

    /* Create an encryption context */
    ctx = new_test_aead_context(aead, 1, key, iv);
    if (ctx == NULL) {
        ret = -1;
    }

    /* Do a simple encrypt using one shot bcrypt */
    if (ret == 0) {
        ret = EncodeOneShot(aead, name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, 
            iv, (ULONG)aead->iv_size, data, 123, nonce,
            authData, 9, authTagLength, encryptedRef, 256, &encryptedRefLength);
    }

    /* Try encrypt with library procedure */
    if (ret == 0) {
        ctx->do_encrypt_init(ctx, nonce, authData, 9);
        encryptedLength = ctx->do_encrypt_update(ctx, encrypted, data, 123);
        encryptedLength += ctx->do_encrypt_final(ctx, &encrypted[encryptedLength]);

        if (encryptedLength != encryptedRefLength) {
            printf("For %s, encrypt returns %d instead of %d\n", aead->name, (int)encryptedLength, encryptedRefLength);
            ret = -1;
        } else if (memcmp(encryptedRef, encrypted, encryptedRefLength) != 0) {
            printf("For %s, encrypted does not match ref\n", aead->name);
            for (ULONG i = 0; i < encryptedRefLength; i++) {
                if (encryptedRef[i] != encrypted[i]) {
                    printf("For %s, encrypted[%d] = 0x%02x vs encryptedRef[%d] = 0x%02x\n", aead->name, i, encrypted[i], i,
                           encryptedRef[i]);
                    break;
                }
            }
            ret = -1;
        } else {
            printf("For %s, encrypting test passes.\n", aead->name);
        }
    }

    delete_test_aead_context(ctx);

    return ret;
}

int test_encrypt_vector(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE iv[PTLS_MAX_IV_SIZE];
    BYTE data[123];
    uint64_t nonce;
    BYTE authData[9];
    BYTE encryptedRef[256];
    ULONG encryptedRefLength;
    BYTE encrypted[256];
    size_t encryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx = NULL;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(iv) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(data) + authTagLength <= sizeof(encryptedRef));

    memset(key, 'k', sizeof(key));
    memset(iv, 'n', sizeof(iv));
    memset(data, 'd', sizeof(data));
    nonce = 0;
    memset(authData, 'a', sizeof(authData));

    /* Create an encryption context */
    ctx = new_test_aead_context(aead, 1, key, iv);
    if (ctx == NULL) {
        ret = -1;
    }

    if (ret == 0) {
        ret = EncodeOneShot(aead, name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, iv, (ULONG)aead->iv_size, data, 123,
                            nonce, authData, 9, authTagLength, encryptedRef, 256, &encryptedRefLength);
    }

    /* Try encrypt with vector procedure */
    if (ret == 0) {
        ptls_iovec_t input_vec[2];

        input_vec[0].base = data;
        input_vec[0].len = 23;
        input_vec[1].base = data + 23;
        input_vec[1].len = 100;

        ptls_aead_encrypt_v(ctx, encrypted, input_vec, 2, nonce, authData, 9);
        encryptedLength = 123 + authTagLength;

        if (encryptedLength != encryptedRefLength) {
            printf("For %s, encrypt_v returns %d instead of %d\n", aead->name, (int)encryptedLength, encryptedRefLength);
            ret = -1;
        } else if (memcmp(encryptedRef, encrypted, encryptedRefLength) != 0) {
            printf("For %s, vector encrypted does not match ref\n", aead->name);
            for (ULONG i = 0; i < encryptedRefLength; i++) {
                if (encryptedRef[i] != encrypted[i]) {
                    printf("For %s, vector encrypted[%d] = 0x%02x vs encryptedRef[%d] = 0x%02x\n", aead->name, i, encrypted[i], i,
                           encryptedRef[i]);
                    break;
                }
            }
            ret = -1;
        } else {
            printf("For %s, vector encrypting test passes.\n", aead->name);
        }
    }

    delete_test_aead_context(ctx);

    return ret;
}

int test_for_size(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE iv[PTLS_MAX_IV_SIZE];
    uint64_t nonce;
    BYTE authData[9];
    BYTE *data = NULL;
    BYTE *encrypted = NULL;
    BYTE *decrypted = NULL;
    size_t encryptedLength;
    size_t decryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx_e = NULL;
    ptls_aead_context_t *ctx_d = NULL;
    ULONG packet_size[] = {1500, 128, 3, 0};
    ULONG nb_packet_size = (ULONG)(sizeof(packet_size) / sizeof(ULONG));
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(iv) >= aead->iv_size);

    memset(key, 'k', sizeof(key));
    memset(key, 'n', sizeof(iv));
    nonce = 0;
    memset(authData, 'a', sizeof(authData));

    /* Create the encryption contexts */
    ctx_e = new_test_aead_context(aead, 1, key, iv);
    ctx_d = new_test_aead_context(aead, 0, key, iv);

    if (ctx_e == NULL || ctx_d == NULL) {
        ret = -1;
    }

    /* Test a variety of packet sizes */
    for (ULONG i = 0; ret == 0 && i < nb_packet_size; i++) {
        ULONG data_size = (packet_size[i] > 0) ? packet_size[i] : 128;
        ULONG encrypted_size = packet_size[i] + authTagLength;

        data = (BYTE *)malloc(data_size);
        encrypted = (BYTE *)malloc(encrypted_size);
        decrypted = (BYTE *)malloc(data_size);

        if (data == NULL || encrypted == NULL || decrypted == NULL) {
            printf("For %s: cannot allocate memory for packet size[%d] = %d\n", aead->name, i, packet_size[i]);
        } else {
            memset(data, 'd', data_size);

            ctx_e->do_encrypt_init(ctx_e, nonce, authData, 9);
            encryptedLength = ctx_e->do_encrypt_update(ctx_e, encrypted, data, packet_size[i]);
            encryptedLength += ctx_e->do_encrypt_final(ctx_e, &encrypted[encryptedLength]);
            decryptedLength = ctx_d->do_decrypt(ctx_d, decrypted, encrypted, encryptedLength, nonce, authData, 9);

            if (decryptedLength >= encryptedLength) {
                printf("For %s, decrypt returns %d\n", aead->name, (int)decryptedLength);
                ret = -1;
            } else if (decryptedLength != packet_size[i]) {
                printf("For %s, decrypt returns %d instead of %d\n", aead->name, (int)decryptedLength, packet_size[i]);
                ret = -1;
            } else if (memcmp(data, decrypted, decryptedLength) != 0) {
                printf("For %s, decrypted does not match clear text\n", aead->name);
                ret = -1;
            } else {
                printf("For %s, test packet size[%d] = %d passes.\n", aead->name, i, packet_size[i]);
            }
        }

        if (data != NULL) {
            free(data);
            data = NULL;
        }

        if (encrypted != NULL) {
            free(encrypted);
            encrypted = NULL;
        }

        if (decrypted != NULL) {
            free(decrypted);
            decrypted = NULL;
        }
    }

    delete_test_aead_context(ctx_e);
    delete_test_aead_context(ctx_d);

    return ret;
}

int test_one_aead(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    int ret = test_oneshot(aead, name, chain_mode, chain_mode_sz);

    printf("For %s, test one shot returns %d\n", aead->name, ret);

    if (ret == 0) {
        ret = test_decrypt(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test decrypt returns %d\n", aead->name, ret);
    }

    if (ret == 0) {
        ret = test_encrypt(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test encrypt returns %d\n", aead->name, ret);
    }

    if (ret == 0) {
        ret = test_encrypt_vector(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test encrypt returns %d\n", aead->name, ret);
    }


    if (ret == 0) {
        ret = test_for_size(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test packet sizes returns %d\n", aead->name, ret);
    }

    return ret;
}

/* Test of cipher functions.
 * The test verifies that a message encode with a bcrypt function can be
 * decoded with a minicrypto function, and vice versa.
 */

int test_cipher_one_way(char const *name1, char const *name2, ptls_cipher_algorithm_t *b1, ptls_cipher_algorithm_t *b2,
                        unsigned int nb_blocks)
{
    BYTE key[32];
    BYTE nonce[16];
    BYTE data[128];
    BYTE encrypted[128];
    BYTE decrypted[128];
    size_t data_size = b1->block_size * nb_blocks;
    ptls_cipher_context_t *ctx1 = NULL;
    ptls_cipher_context_t *ctx2 = NULL;
    int ret = 0;

    assert(sizeof(key) >= b1->key_size);
    assert(sizeof(data) >= data_size);
    assert(sizeof(nonce) >= b1->iv_size);

    memset(key, 'k', sizeof(key));
    memset(data, 'd', data_size);

    ctx1 = ptls_cipher_new(b1, 1, key);
    ctx2 = ptls_cipher_new(b2, 0, key);

    if (ctx1 == NULL || ctx2 == NULL) {
        ret = -1;
    } else {
        memset(nonce, 0, sizeof(nonce));
        if (ctx1->do_init != NULL) {
            ctx1->do_init(ctx1, nonce);
        }

        if (ctx2->do_init != NULL) {
            ctx2->do_init(ctx2, nonce);
        }

        ctx1->do_transform(ctx1, encrypted, data, data_size);
        ctx2->do_transform(ctx2, decrypted, encrypted, data_size);

        if (memcmp(data, decrypted, data_size) != 0) {
            printf("For %s -> %s, decrypted does not match clear text\n", name1, name2);
            ret = -1;
        } else {
            printf("For %s -> %s, test passes.\n", name1, name2);
        }
    }

    if (ctx1 != NULL) {
        ptls_cipher_free(ctx1);
    }

    if (ctx2 != NULL) {
        ptls_cipher_free(ctx2);
    }

    return ret;
}

int test_cipher_pair(char const *name1, char const *name2, ptls_cipher_algorithm_t *b1, ptls_cipher_algorithm_t *b2,
                     unsigned int nb_blocks)
{
    int ret = test_cipher_one_way(name1, name2, b1, b2, nb_blocks);

    if (ret == 0) {
        ret = test_cipher_one_way(name2, name1, b2, b1, nb_blocks);
    }

    return ret;
}

/* Test of the hash functions
 */

int test_hash_calc(char const *name1, char const *name2, ptls_hash_algorithm_t *h1, ptls_hash_algorithm_t *h2)
{
    BYTE data[123];
    BYTE tag1[128];
    BYTE tag2[128];
    ptls_hash_context_t *ctx1 = NULL;
    ptls_hash_context_t *ctx2 = NULL;
    int ret = 0;

    assert(sizeof(tag1) >= h1->digest_size);
    assert(sizeof(tag2) >= h2->digest_size);
    assert(h1->digest_size == h2->digest_size);

    memset(data, 'd', sizeof(data));
    memset(tag1, '1', sizeof(tag1));
    memset(tag2, '2', sizeof(tag2));

    if (h1->digest_size != h2->digest_size) {
        ret = -1;
    }
    if (ret == 0) {
        ret = ptls_calc_hash(h1, tag1, data, sizeof(data));
    }

    if (ret == 0) {
        ret = ptls_calc_hash(h2, tag2, data, sizeof(data));
    }

    if (ret == 0){
        if (memcmp(tag1, tag2, h1->digest_size) != 0) {
            printf("For %s -> %s, hash1 does not match hash2\n", name1, name2);
            ret = -1;
        } else {
            printf("For %s -> %s, hash test passes.\n", name1, name2);
        }
    }

    return ret;
}

/* Minimal test program for the bcrypt functions.
 * Need to add tests for the SHA256 and SHA384 implementations.
 */

int main()
{
    int ret = 0;

    ret |= test_cipher_pair("bcrypt aes128ecb", "minicrypto aes128ecb", &ptls_bcrypt_aes128ecb, &ptls_minicrypto_aes128ecb, 1);
    ret |= test_cipher_pair("bcrypt aes256ecb", "minicrypto aes256ecb", &ptls_bcrypt_aes256ecb, &ptls_minicrypto_aes256ecb, 1);

    ret |= test_cipher_pair("bcrypt aes128ctr", "minicrypto aes128ctr", &ptls_bcrypt_aes128ctr, &ptls_minicrypto_aes128ctr, 4);
    ret |= test_cipher_pair("bcrypt aes256ctr", "minicrypto aes256ctr", &ptls_bcrypt_aes256ctr, &ptls_minicrypto_aes256ctr, 4);
        
    ret |= test_one_aead(&ptls_bcrypt_aes128gcm, BCRYPT_AES_ALGORITHM, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));

    ret |= test_one_aead(&ptls_bcrypt_aes256gcm, BCRYPT_AES_ALGORITHM, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));

    ret |= test_hash_calc("bcrypt sha256", "minicrypto sha256", &ptls_bcrypt_sha256, &ptls_minicrypto_sha256);
    ret |= test_hash_calc("bcrypt sha384", "minicrypto sha384", &ptls_bcrypt_sha384, &ptls_minicrypto_sha384);

    exit(ret);
}
