diff mbox series

[RFC,v2,09/12] crypto: nhpoly1305 - add NHPoly1305 support

Message ID 20181015175424.97147-10-ebiggers@kernel.org (mailing list archive)
State RFC
Delegated to: Herbert Xu
Headers show
Series crypto: Adiantum support | expand

Commit Message

Eric Biggers Oct. 15, 2018, 5:54 p.m. UTC
From: Eric Biggers <ebiggers@google.com>

Add a generic implementation of NHPoly1305, an ε-almost-∆-universal hash
function used in the Adiantum encryption mode.

CONFIG_NHPOLY1305 is not selectable by itself since there won't be any
real reason to enable it without also enabling Adiantum support.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 crypto/Kconfig              |    5 +
 crypto/Makefile             |    1 +
 crypto/nhpoly1305.c         |  288 ++++++++
 crypto/testmgr.c            |    6 +
 crypto/testmgr.h            | 1240 ++++++++++++++++++++++++++++++++++-
 include/crypto/nhpoly1305.h |   74 +++
 6 files changed, 1610 insertions(+), 4 deletions(-)
 create mode 100644 crypto/nhpoly1305.c
 create mode 100644 include/crypto/nhpoly1305.h

Comments

Ard Biesheuvel Oct. 20, 2018, 4 a.m. UTC | #1
On 16 October 2018 at 01:54, Eric Biggers <ebiggers@kernel.org> wrote:
> From: Eric Biggers <ebiggers@google.com>
>
> Add a generic implementation of NHPoly1305, an ε-almost-∆-universal hash
> function used in the Adiantum encryption mode.
>
> CONFIG_NHPOLY1305 is not selectable by itself since there won't be any
> real reason to enable it without also enabling Adiantum support.
>
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> ---
>  crypto/Kconfig              |    5 +
>  crypto/Makefile             |    1 +
>  crypto/nhpoly1305.c         |  288 ++++++++
>  crypto/testmgr.c            |    6 +
>  crypto/testmgr.h            | 1240 ++++++++++++++++++++++++++++++++++-
>  include/crypto/nhpoly1305.h |   74 +++
>  6 files changed, 1610 insertions(+), 4 deletions(-)
>  create mode 100644 crypto/nhpoly1305.c
>  create mode 100644 include/crypto/nhpoly1305.h
>
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index 4fa0a4a0e8615..431beca903623 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -493,6 +493,11 @@ config CRYPTO_KEYWRAP
>           Support for key wrapping (NIST SP800-38F / RFC3394) without
>           padding.
>
> +config CRYPTO_NHPOLY1305
> +       tristate
> +       select CRYPTO_HASH
> +       select CRYPTO_POLY1305
> +
>  comment "Hash modes"
>
>  config CRYPTO_CMAC
> diff --git a/crypto/Makefile b/crypto/Makefile
> index 7e673f7c71107..87b86f221a2a2 100644
> --- a/crypto/Makefile
> +++ b/crypto/Makefile
> @@ -84,6 +84,7 @@ obj-$(CONFIG_CRYPTO_LRW) += lrw.o
>  obj-$(CONFIG_CRYPTO_XTS) += xts.o
>  obj-$(CONFIG_CRYPTO_CTR) += ctr.o
>  obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
> +obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
>  obj-$(CONFIG_CRYPTO_GCM) += gcm.o
>  obj-$(CONFIG_CRYPTO_CCM) += ccm.o
>  obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
> diff --git a/crypto/nhpoly1305.c b/crypto/nhpoly1305.c
> new file mode 100644
> index 0000000000000..087ad7680dd62
> --- /dev/null
> +++ b/crypto/nhpoly1305.c
> @@ -0,0 +1,288 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * NHPoly1305 - ε-almost-∆-universal hash function for Adiantum
> + *
> + * Copyright 2018 Google LLC
> + */
> +
> +/*
> + * "NHPoly1305" is the main component of Adiantum hashing.
> + * Specifically, it is the calculation
> + *
> + *     H_M ← Poly1305_{K_M}(NH_{K_N}(pad_{128}(M)))
> + *
> + * from the procedure in section A.5 of the Adiantum paper [1].  It is an
> + * ε-almost-∆-universal (εA∆U) hash function for equal-length inputs over
> + * Z/(2^{128}Z), where the "∆" operation is addition.  It hashes 1024-byte
> + * chunks of the input with the NH hash function [2], reducing the input length
> + * by 32x.  The resulting NH digests are evaluated as a polynomial in
> + * GF(2^{130}-5), like in the Poly1305 MAC [3].  Note that the polynomial
> + * evaluation by itself would suffice to achieve the εA∆U property; NH is used
> + * for performance since it's over twice as fast as Poly1305.
> + *
> + * This is *not* a cryptographic hash function; do not use it as such!
> + *
> + * [1] Adiantum: length-preserving encryption for entry-level processors
> + *     (https://eprint.iacr.org/2018/720.pdf)
> + * [2] UMAC: Fast and Secure Message Authentication
> + *     (https://fastcrypto.org/umac/umac_proc.pdf)
> + * [3] The Poly1305-AES message-authentication code
> + *     (https://cr.yp.to/mac/poly1305-20050329.pdf)
> + */
> +
> +#include <asm/unaligned.h>
> +#include <crypto/algapi.h>
> +#include <crypto/internal/hash.h>
> +#include <crypto/nhpoly1305.h>
> +#include <linux/crypto.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#define NH_STRIDE(K0, K1, K2, K3)                              \
> +({                                                             \
> +       m_A = get_unaligned_le32(src); src += 4;                \
> +       m_B = get_unaligned_le32(src); src += 4;                \
> +       m_C = get_unaligned_le32(src); src += 4;                \
> +       m_D = get_unaligned_le32(src); src += 4;                \
> +       K3##_A = *key++;                                        \
> +       K3##_B = *key++;                                        \
> +       K3##_C = *key++;                                        \
> +       K3##_D = *key++;                                        \
> +       sum0 += (u64)(u32)(m_A + K0##_A) * (u32)(m_C + K0##_C); \
> +       sum1 += (u64)(u32)(m_A + K1##_A) * (u32)(m_C + K1##_C); \
> +       sum2 += (u64)(u32)(m_A + K2##_A) * (u32)(m_C + K2##_C); \
> +       sum3 += (u64)(u32)(m_A + K3##_A) * (u32)(m_C + K3##_C); \
> +       sum0 += (u64)(u32)(m_B + K0##_B) * (u32)(m_D + K0##_D); \
> +       sum1 += (u64)(u32)(m_B + K1##_B) * (u32)(m_D + K1##_D); \
> +       sum2 += (u64)(u32)(m_B + K2##_B) * (u32)(m_D + K2##_D); \
> +       sum3 += (u64)(u32)(m_B + K3##_B) * (u32)(m_D + K3##_D); \
> +})
> +
> +static void nh_generic(const u32 *key, const u8 *src, size_t srclen,
> +                      __le64 hash[NH_NUM_PASSES])
> +{
> +       u64 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
> +       u32 k0_A = *key++;
> +       u32 k0_B = *key++;
> +       u32 k0_C = *key++;
> +       u32 k0_D = *key++;
> +       u32 k1_A = *key++;
> +       u32 k1_B = *key++;
> +       u32 k1_C = *key++;
> +       u32 k1_D = *key++;
> +       u32 k2_A = *key++;
> +       u32 k2_B = *key++;
> +       u32 k2_C = *key++;
> +       u32 k2_D = *key++;
> +       u32 k3_A, k3_B, k3_C, k3_D;
> +       u32 m_A, m_B, m_C, m_D;
> +       size_t n = srclen / NH_MESSAGE_UNIT;
> +
> +       BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
> +       BUILD_BUG_ON(NH_NUM_PASSES != 4);
> +
> +       while (n >= 4) {
> +               NH_STRIDE(k0, k1, k2, k3);
> +               NH_STRIDE(k1, k2, k3, k0);
> +               NH_STRIDE(k2, k3, k0, k1);
> +               NH_STRIDE(k3, k0, k1, k2);
> +               n -= 4;
> +       }
> +       if (n) {
> +               NH_STRIDE(k0, k1, k2, k3);
> +               if (--n) {
> +                       NH_STRIDE(k1, k2, k3, k0);
> +                       if (--n)
> +                               NH_STRIDE(k2, k3, k0, k1);
> +               }
> +       }
> +

This all looks a bit clunky to me, with the macro, the *key++s in the
initializers and these conditionals.

Was it written in this particular way to get GCC to optimize it in the
right way?

> +       hash[0] = cpu_to_le64(sum0);
> +       hash[1] = cpu_to_le64(sum1);
> +       hash[2] = cpu_to_le64(sum2);
> +       hash[3] = cpu_to_le64(sum3);
> +}
> +
> +/* Pass the next NH hash value through Poly1305 */
> +static void process_nh_hash_value(struct nhpoly1305_state *state,
> +                                 const struct nhpoly1305_key *key)
> +{
> +       BUILD_BUG_ON(NH_HASH_BYTES % POLY1305_BLOCK_SIZE != 0);
> +
> +       poly1305_core_blocks(&state->poly_state, &key->poly_key, state->nh_hash,
> +                            NH_HASH_BYTES / POLY1305_BLOCK_SIZE);
> +}
> +
> +/*
> + * Feed the next portion of the source data, as a whole number of 16-byte
> + * "NH message units", through NH and Poly1305.  Each NH hash is taken over
> + * 1024 bytes, except possibly the final one which is taken over a multiple of
> + * 16 bytes up to 1024.  Also, in the case where data is passed in misaligned
> + * chunks, we combine partial hashes; the end result is the same either way.
> + */
> +static void nhpoly1305_units(struct nhpoly1305_state *state,
> +                            const struct nhpoly1305_key *key,
> +                            const u8 *src, unsigned int srclen, nh_t nh_fn)

Since indirect calls are going out of style: can we get rid of the
function pointer? Or is the compiler already inferring that it always
refers to nh_generic()?

> +{
> +       do {
> +               unsigned int bytes;
> +
> +               if (state->nh_remaining == 0) {
> +                       /* Starting a new NH message */
> +                       bytes = min_t(unsigned int, srclen, NH_MESSAGE_BYTES);
> +                       nh_fn(key->nh_key, src, bytes, state->nh_hash);
> +                       state->nh_remaining = NH_MESSAGE_BYTES - bytes;
> +               } else {
> +                       /* Continuing a previous NH message */
> +                       __le64 tmp_hash[NH_NUM_PASSES];
> +                       unsigned int pos;
> +                       int i;
> +
> +                       pos = NH_MESSAGE_BYTES - state->nh_remaining;
> +                       bytes = min(srclen, state->nh_remaining);
> +                       nh_fn(&key->nh_key[pos / 4], src, bytes, tmp_hash);
> +                       for (i = 0; i < NH_NUM_PASSES; i++)
> +                               le64_add_cpu(&state->nh_hash[i],
> +                                            le64_to_cpu(tmp_hash[i]));
> +                       state->nh_remaining -= bytes;
> +               }
> +               if (state->nh_remaining == 0)
> +                       process_nh_hash_value(state, key);
> +               src += bytes;
> +               srclen -= bytes;
> +       } while (srclen);
> +}
> +
> +int crypto_nhpoly1305_setkey(struct crypto_shash *tfm,
> +                            const u8 *key, unsigned int keylen)
> +{
> +       struct nhpoly1305_key *ctx = crypto_shash_ctx(tfm);
> +       int i;
> +
> +       if (keylen != NHPOLY1305_KEY_SIZE)
> +               return -EINVAL;
> +
> +       poly1305_core_setkey(&ctx->poly_key, key);
> +       key += POLY1305_BLOCK_SIZE;
> +
> +       for (i = 0; i < NH_KEY_WORDS; i++)
> +               ctx->nh_key[i] = get_unaligned_le32(key + i * sizeof(u32));
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(crypto_nhpoly1305_setkey);
> +
> +int crypto_nhpoly1305_init(struct shash_desc *desc)
> +{
> +       struct nhpoly1305_state *state = shash_desc_ctx(desc);
> +
> +       poly1305_core_init(&state->poly_state);
> +       state->buflen = 0;
> +       state->nh_remaining = 0;
> +       return 0;
> +}
> +EXPORT_SYMBOL(crypto_nhpoly1305_init);
> +
> +int crypto_nhpoly1305_update_helper(struct shash_desc *desc,
> +                                   const u8 *src, unsigned int srclen,
> +                                   nh_t nh_fn)
> +{
> +       struct nhpoly1305_state *state = shash_desc_ctx(desc);
> +       const struct nhpoly1305_key *key = crypto_shash_ctx(desc->tfm);
> +       unsigned int bytes;
> +
> +       if (state->buflen) {
> +               bytes = min(srclen, (int)NH_MESSAGE_UNIT - state->buflen);
> +               memcpy(&state->buffer[state->buflen], src, bytes);
> +               state->buflen += bytes;
> +               if (state->buflen < NH_MESSAGE_UNIT)
> +                       return 0;
> +               nhpoly1305_units(state, key, state->buffer, NH_MESSAGE_UNIT,
> +                                nh_fn);
> +               state->buflen = 0;
> +               src += bytes;
> +               srclen -= bytes;
> +       }
> +
> +       if (srclen >= NH_MESSAGE_UNIT) {
> +               bytes = round_down(srclen, NH_MESSAGE_UNIT);
> +               nhpoly1305_units(state, key, src, bytes, nh_fn);
> +               src += bytes;
> +               srclen -= bytes;
> +       }
> +
> +       if (srclen) {
> +               memcpy(state->buffer, src, srclen);
> +               state->buflen = srclen;
> +       }
> +       return 0;
> +}
> +EXPORT_SYMBOL(crypto_nhpoly1305_update_helper);
> +
> +int crypto_nhpoly1305_update(struct shash_desc *desc,
> +                            const u8 *src, unsigned int srclen)
> +{
> +       return crypto_nhpoly1305_update_helper(desc, src, srclen, nh_generic);
> +}
> +EXPORT_SYMBOL(crypto_nhpoly1305_update);
> +
> +int crypto_nhpoly1305_final_helper(struct shash_desc *desc, u8 *dst, nh_t nh_fn)
> +{
> +       struct nhpoly1305_state *state = shash_desc_ctx(desc);
> +       const struct nhpoly1305_key *key = crypto_shash_ctx(desc->tfm);
> +
> +       if (state->buflen) {
> +               memset(&state->buffer[state->buflen], 0,
> +                      NH_MESSAGE_UNIT - state->buflen);
> +               nhpoly1305_units(state, key, state->buffer, NH_MESSAGE_UNIT,
> +                                nh_fn);
> +       }
> +
> +       if (state->nh_remaining)
> +               process_nh_hash_value(state, key);
> +
> +       poly1305_core_emit(&state->poly_state, dst);
> +       return 0;
> +}
> +EXPORT_SYMBOL(crypto_nhpoly1305_final_helper);
> +
> +int crypto_nhpoly1305_final(struct shash_desc *desc, u8 *dst)
> +{
> +       return crypto_nhpoly1305_final_helper(desc, dst, nh_generic);
> +}
> +EXPORT_SYMBOL(crypto_nhpoly1305_final);
> +
> +static struct shash_alg nhpoly1305_alg = {
> +       .digestsize     = POLY1305_DIGEST_SIZE,
> +       .init           = crypto_nhpoly1305_init,
> +       .update         = crypto_nhpoly1305_update,
> +       .final          = crypto_nhpoly1305_final,
> +       .setkey         = crypto_nhpoly1305_setkey,
> +       .descsize       = sizeof(struct nhpoly1305_state),
> +       .base           = {
> +               .cra_name               = "nhpoly1305",
> +               .cra_driver_name        = "nhpoly1305-generic",
> +               .cra_priority           = 100,
> +               .cra_ctxsize            = sizeof(struct nhpoly1305_key),
> +               .cra_module             = THIS_MODULE,
> +       },

Could we use the .base.xxxx idiom here instead of the separately indented block?

> +};
> +
> +static int __init nhpoly1305_mod_init(void)
> +{
> +       return crypto_register_shash(&nhpoly1305_alg);
> +}
> +
> +static void __exit nhpoly1305_mod_exit(void)
> +{
> +       crypto_unregister_shash(&nhpoly1305_alg);
> +}
> +
> +module_init(nhpoly1305_mod_init);
> +module_exit(nhpoly1305_mod_exit);
> +
> +MODULE_DESCRIPTION("NHPoly1305 ε-almost-∆-universal hash function");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
> +MODULE_ALIAS_CRYPTO("nhpoly1305");
> +MODULE_ALIAS_CRYPTO("nhpoly1305-generic");
> diff --git a/crypto/testmgr.c b/crypto/testmgr.c
> index 3ff70ebc745cb..039a5d850a29c 100644
> --- a/crypto/testmgr.c
> +++ b/crypto/testmgr.c
> @@ -3291,6 +3291,12 @@ static const struct alg_test_desc alg_test_descs[] = {
>                                 .dec = __VECS(morus640_dec_tv_template),
>                         }
>                 }
> +       }, {
> +               .alg = "nhpoly1305",
> +               .test = alg_test_hash,
> +               .suite = {
> +                       .hash = __VECS(nhpoly1305_tv_template)
> +               }
>         }, {
>                 .alg = "ofb(aes)",
>                 .test = alg_test_skcipher,
> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index 3b57b2701fcb2..40197d74b3d56 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -27,7 +27,7 @@
>  #define MAX_DIGEST_SIZE                64
>  #define MAX_TAP                        8
>
> -#define MAX_KEYLEN             160
> +#define MAX_KEYLEN             1088
>  #define MAX_IVLEN              32
>
>  struct hash_testvec {
> @@ -35,10 +35,10 @@ struct hash_testvec {
>         const char *key;
>         const char *plaintext;
>         const char *digest;
> -       unsigned char tap[MAX_TAP];
> +       unsigned short tap[MAX_TAP];
> +       unsigned short np;
>         unsigned short psize;
> -       unsigned char np;
> -       unsigned char ksize;
> +       unsigned short ksize;
>  };
>
>  /*
> @@ -5593,6 +5593,1238 @@ static const struct hash_testvec poly1305_tv_template[] = {
>         },
>  };
>
> +/* NHPoly1305 test vectors from https://github.com/google/adiantum */
> +static const struct hash_testvec nhpoly1305_tv_template[] = {
> +       {
> +               .key    = "\xd2\x5d\x4c\xdd\x8d\x2b\x7f\x7a"
> +                         "\xd9\xbe\x71\xec\xd1\x83\x52\xe3"
> +                         "\xe1\xad\xd7\x5c\x0a\x75\x9d\xec"
> +                         "\x1d\x13\x7e\x5d\x71\x07\xc9\xe4"
> +                         "\x57\x2d\x44\x68\xcf\xd8\xd6\xc5"
> +                         "\x39\x69\x7d\x32\x75\x51\x4f\x7e"
> +                         "\xb2\x4c\xc6\x90\x51\x6e\xd9\xd6"
> +                         "\xa5\x8b\x2d\xf1\x94\xf9\xf7\x5e"
> +                         "\x2c\x84\x7b\x41\x0f\x88\x50\x89"
> +                         "\x30\xd9\xa1\x38\x46\x6c\xc0\x4f"
> +                         "\xe8\xdf\xdc\x66\xab\x24\x43\x41"
> +                         "\x91\x55\x29\x65\x86\x28\x5e\x45"
> +                         "\xd5\x2d\xb7\x80\x08\x9a\xc3\xd4"
> +                         "\x9a\x77\x0a\xd4\xef\x3e\xe6\x3f"
> +                         "\x6f\x2f\x9b\x3a\x7d\x12\x1e\x80"
> +                         "\x6c\x44\xa2\x25\xe1\xf6\x60\xe9"
> +                         "\x0d\xaf\xc5\x3c\xa5\x79\xae\x64"
> +                         "\xbc\xa0\x39\xa3\x4d\x10\xe5\x4d"
> +                         "\xd5\xe7\x89\x7a\x13\xee\x06\x78"
> +                         "\xdc\xa4\xdc\x14\x27\xe6\x49\x38"
> +                         "\xd0\xe0\x45\x25\x36\xc5\xf4\x79"
> +                         "\x2e\x9a\x98\x04\xe4\x2b\x46\x52"
> +                         "\x7c\x33\xca\xe2\x56\x51\x50\xe2"
> +                         "\xa5\x9a\xae\x18\x6a\x13\xf8\xd2"
> +                         "\x21\x31\x66\x02\xe2\xda\x8d\x7e"
> +                         "\x41\x19\xb2\x61\xee\x48\x8f\xf1"
> +                         "\x65\x24\x2e\x1e\x68\xce\x05\xd9"
> +                         "\x2a\xcf\xa5\x3a\x57\xdd\x35\x91"
> +                         "\x93\x01\xca\x95\xfc\x2b\x36\x04"
> +                         "\xe6\x96\x97\x28\xf6\x31\xfe\xa3"
> +                         "\x9d\xf6\x6a\x1e\x80\x8d\xdc\xec"
> +                         "\xaf\x66\x11\x13\x02\x88\xd5\x27"
> +                         "\x33\xb4\x1a\xcd\xa3\xf6\xde\x31"
> +                         "\x8e\xc0\x0e\x6c\xd8\x5a\x97\x5e"
> +                         "\xdd\xfd\x60\x69\x38\x46\x3f\x90"
> +                         "\x5e\x97\xd3\x32\x76\xc7\x82\x49"
> +                         "\xfe\xba\x06\x5f\x2f\xa2\xfd\xff"
> +                         "\x80\x05\x40\xe4\x33\x03\xfb\x10"
> +                         "\xc0\xde\x65\x8c\xc9\x8d\x3a\x9d"
> +                         "\xb5\x7b\x36\x4b\xb5\x0c\xcf\x00"
> +                         "\x9c\x87\xe4\x49\xad\x90\xda\x4a"
> +                         "\xdd\xbd\xff\xe2\x32\x57\xd6\x78"
> +                         "\x36\x39\x6c\xd3\x5b\x9b\x88\x59"
> +                         "\x2d\xf0\x46\xe4\x13\x0e\x2b\x35"
> +                         "\x0d\x0f\x73\x8a\x4f\x26\x84\x75"
> +                         "\x88\x3c\xc5\x58\x66\x18\x1a\xb4"
> +                         "\x64\x51\x34\x27\x1b\xa4\x11\xc9"
> +                         "\x6d\x91\x8a\xfa\x32\x60\x9d\xd7"
> +                         "\x87\xe5\xaa\x43\x72\xf8\xda\xd1"
> +                         "\x48\x44\x13\x61\xdc\x8c\x76\x17"
> +                         "\x0c\x85\x4e\xf3\xdd\xa2\x42\xd2"
> +                         "\x74\xc1\x30\x1b\xeb\x35\x31\x29"
> +                         "\x5b\xd7\x4c\x94\x46\x35\xa1\x23"
> +                         "\x50\xf2\xa2\x8e\x7e\x4f\x23\x4f"
> +                         "\x51\xff\xe2\xc9\xa3\x7d\x56\x8b"
> +                         "\x41\xf2\xd0\xc5\x57\x7e\x59\xac"
> +                         "\xbb\x65\xf3\xfe\xf7\x17\xef\x63"
> +                         "\x7c\x6f\x23\xdd\x22\x8e\xed\x84"
> +                         "\x0e\x3b\x09\xb3\xf3\xf4\x8f\xcd"
> +                         "\x37\xa8\xe1\xa7\x30\xdb\xb1\xa2"
> +                         "\x9c\xa2\xdf\x34\x17\x3e\x68\x44"
> +                         "\xd0\xde\x03\x50\xd1\x48\x6b\x20"
> +                         "\xe2\x63\x45\xa5\xea\x87\xc2\x42"
> +                         "\x95\x03\x49\x05\xed\xe0\x90\x29"
> +                         "\x1a\xb8\xcf\x9b\x43\xcf\x29\x7a"
> +                         "\x63\x17\x41\x9f\xe0\xc9\x10\xfd"
> +                         "\x2c\x56\x8c\x08\x55\xb4\xa9\x27"
> +                         "\x0f\x23\xb1\x05\x6a\x12\x46\xc7"
> +                         "\xe1\xfe\x28\x93\x93\xd7\x2f\xdc"
> +                         "\x98\x30\xdb\x75\x8a\xbe\x97\x7a"
> +                         "\x02\xfb\x8c\xba\xbe\x25\x09\xbe"
> +                         "\xce\xcb\xa2\xef\x79\x4d\x0e\x9d"
> +                         "\x1b\x9d\xb6\x39\x34\x38\xfa\x07"
> +                         "\xec\xe8\xfc\x32\x85\x1d\xf7\x85"
> +                         "\x63\xc3\x3c\xc0\x02\x75\xd7\x3f"
> +                         "\xb2\x68\x60\x66\x65\x81\xc6\xb1"
> +                         "\x42\x65\x4b\x4b\x28\xd7\xc7\xaa"
> +                         "\x9b\xd2\xdc\x1b\x01\xe0\x26\x39"
> +                         "\x01\xc1\x52\x14\xd1\x3f\xb7\xe6"
> +                         "\x61\x41\xc7\x93\xd2\xa2\x67\xc6"
> +                         "\xf7\x11\xb5\xf5\xea\xdd\x19\xfb"
> +                         "\x4d\x21\x12\xd6\x7d\xf1\x10\xb0"
> +                         "\x89\x07\xc7\x5a\x52\x73\x70\x2f"
> +                         "\x32\xef\x65\x2b\x12\xb2\xf0\xf5"
> +                         "\x20\xe0\x90\x59\x7e\x64\xf1\x4c"
> +                         "\x41\xb3\xa5\x91\x08\xe6\x5e\x5f"
> +                         "\x05\x56\x76\xb4\xb0\xcd\x70\x53"
> +                         "\x10\x48\x9c\xff\xc2\x69\x55\x24"
> +                         "\x87\xef\x84\xea\xfb\xa7\xbf\xa0"
> +                         "\x91\x04\xad\x4f\x8b\x57\x54\x4b"
> +                         "\xb6\xe9\xd1\xac\x37\x2f\x1d\x2e"
> +                         "\xab\xa5\xa4\xe8\xff\xfb\xd9\x39"
> +                         "\x2f\xb7\xac\xd1\xfe\x0b\x9a\x80"
> +                         "\x0f\xb6\xf4\x36\x39\x90\x51\xe3"
> +                         "\x0a\x2f\xb6\x45\x76\x89\xcd\x61"
> +                         "\xfe\x48\x5f\x75\x1d\x13\x00\x62"
> +                         "\x80\x24\x47\xe7\xbc\x37\xd7\xe3"
> +                         "\x15\xe8\x68\x22\xaf\x80\x6f\x4b"
> +                         "\xa8\x9f\x01\x10\x48\x14\xc3\x02"
> +                         "\x52\xd2\xc7\x75\x9b\x52\x6d\x30"
> +                         "\xac\x13\x85\xc8\xf7\xa3\x58\x4b"
> +                         "\x49\xf7\x1c\x45\x55\x8c\x39\x9a"
> +                         "\x99\x6d\x97\x27\x27\xe6\xab\xdd"
> +                         "\x2c\x42\x1b\x35\xdd\x9d\x73\xbb"
> +                         "\x6c\xf3\x64\xf1\xfb\xb9\xf7\xe6"
> +                         "\x4a\x3c\xc0\x92\xc0\x2e\xb7\x1a"
> +                         "\xbe\xab\xb3\x5a\xe5\xea\xb1\x48"
> +                         "\x58\x13\x53\x90\xfd\xc3\x8e\x54"
> +                         "\xf9\x18\x16\x73\xe8\xcb\x6d\x39"
> +                         "\x0e\xd7\xe0\xfe\xb6\x9f\x43\x97"
> +                         "\xe8\xd0\x85\x56\x83\x3e\x98\x68"
> +                         "\x7f\xbd\x95\xa8\x9a\x61\x21\x8f"
> +                         "\x06\x98\x34\xa6\xc8\xd6\x1d\xf3"
> +                         "\x3d\x43\xa4\x9a\x8c\xe5\xd3\x5a"
> +                         "\x32\xa2\x04\x22\xa4\x19\x1a\x46"
> +                         "\x42\x7e\x4d\xe5\xe0\xe6\x0e\xca"
> +                         "\xd5\x58\x9d\x2c\xaf\xda\x33\x5c"
> +                         "\xb0\x79\x9e\xc9\xfc\xca\xf0\x2f"
> +                         "\xa8\xb2\x77\xeb\x7a\xa2\xdd\x37"
> +                         "\x35\x83\x07\xd6\x02\x1a\xb6\x6c"
> +                         "\x24\xe2\x59\x08\x0e\xfd\x3e\x46"
> +                         "\xec\x40\x93\xf4\x00\x26\x4f\x2a"
> +                         "\xff\x47\x2f\xeb\x02\x92\x26\x5b"
> +                         "\x53\x17\xc2\x8d\x2a\xc7\xa3\x1b"
> +                         "\xcd\xbc\xa7\xe8\xd1\x76\xe3\x80"
> +                         "\x21\xca\x5d\x3b\xe4\x9c\x8f\xa9"
> +                         "\x5b\x7f\x29\x7f\x7c\xd8\xed\x6d"
> +                         "\x8c\xb2\x86\x85\xe7\x77\xf2\x85"
> +                         "\xab\x38\xa9\x9d\xc1\x4e\xc5\x64"
> +                         "\x33\x73\x8b\x59\x03\xad\x05\xdf"
> +                         "\x25\x98\x31\xde\xef\x13\xf1\x9b"
> +                         "\x3c\x91\x9d\x7b\xb1\xfa\xe6\xbf"
> +                         "\x5b\xed\xa5\x55\xe6\xea\x6c\x74"
> +                         "\xf4\xb9\xe4\x45\x64\x72\x81\xc2"
> +                         "\x4c\x28\xd4\xcd\xac\xe2\xde\xf9"
> +                         "\xeb\x5c\xeb\x61\x60\x5a\xe5\x28",
> +               .ksize  = 1088,
> +               .plaintext      = "",
> +               .psize  = 0,
> +               .digest = "\x00\x00\x00\x00\x00\x00\x00\x00"
> +                         "\x00\x00\x00\x00\x00\x00\x00\x00",
> +       }, {
> +               .key    = "\x29\x21\x43\xcb\xcb\x13\x07\xde"
> +                         "\xbf\x48\xdf\x8a\x7f\xa2\x84\xde"
> +                         "\x72\x23\x9d\xf5\xf0\x07\xf2\x4c"
> +                         "\x20\x3a\x93\xb9\xcd\x5d\xfe\xcb"
> +                         "\x99\x2c\x2b\x58\xc6\x50\x5f\x94"
> +                         "\x56\xc3\x7c\x0d\x02\x3f\xb8\x5e"
> +                         "\x7b\xc0\x6c\x51\x34\x76\xc0\x0e"
> +                         "\xc6\x22\xc8\x9e\x92\xa0\x21\xc9"
> +                         "\x85\x5c\x7c\xf8\xe2\x64\x47\xc9"
> +                         "\xe4\xa2\x57\x93\xf8\xa2\x69\xcd"
> +                         "\x62\x98\x99\xf4\xd7\x7b\x14\xb1"
> +                         "\xd8\x05\xff\x04\x15\xc9\xe1\x6e"
> +                         "\x9b\xe6\x50\x6b\x0b\x3f\x22\x1f"
> +                         "\x08\xde\x0c\x5b\x08\x7e\xc6\x2f"
> +                         "\x6c\xed\xd6\xb2\x15\xa4\xb3\xf9"
> +                         "\xa7\x46\x38\x2a\xea\x69\xa5\xde"
> +                         "\x02\xc3\x96\x89\x4d\x55\x3b\xed"
> +                         "\x3d\x3a\x85\x77\xbf\x97\x45\x5c"
> +                         "\x9e\x02\x69\xe2\x1b\x68\xbe\x96"
> +                         "\xfb\x64\x6f\x0f\xf6\x06\x40\x67"
> +                         "\xfa\x04\xe3\x55\xfa\xbe\xa4\x60"
> +                         "\xef\x21\x66\x97\xe6\x9d\x5c\x1f"
> +                         "\x62\x37\xaa\x31\xde\xe4\x9c\x28"
> +                         "\x95\xe0\x22\x86\xf4\x4d\xf3\x07"
> +                         "\xfd\x5f\x3a\x54\x2c\x51\x80\x71"
> +                         "\xba\x78\x69\x5b\x65\xab\x1f\x81"
> +                         "\xed\x3b\xff\x34\xa3\xfb\xbc\x73"
> +                         "\x66\x7d\x13\x7f\xdf\x6e\xe2\xe2"
> +                         "\xeb\x4f\x6c\xda\x7d\x33\x57\xd0"
> +                         "\xd3\x7c\x95\x4f\x33\x58\x21\xc7"
> +                         "\xc0\xe5\x6f\x42\x26\xc6\x1f\x5e"
> +                         "\x85\x1b\x98\x9a\xa2\x1e\x55\x77"
> +                         "\x23\xdf\x81\x5e\x79\x55\x05\xfc"
> +                         "\xfb\xda\xee\xba\x5a\xba\xf7\x77"
> +                         "\x7f\x0e\xd3\xe1\x37\xfe\x8d\x2b"
> +                         "\xd5\x3f\xfb\xd0\xc0\x3c\x0b\x3f"
> +                         "\xcf\x3c\x14\xcf\xfb\x46\x72\x4c"
> +                         "\x1f\x39\xe2\xda\x03\x71\x6d\x23"
> +                         "\xef\x93\xcd\x39\xd9\x37\x80\x4d"
> +                         "\x65\x61\xd1\x2c\x03\xa9\x47\x72"
> +                         "\x4d\x1e\x0e\x16\x33\x0f\x21\x17"
> +                         "\xec\x92\xea\x6f\x37\x22\xa4\xd8"
> +                         "\x03\x33\x9e\xd8\x03\x69\x9a\xe8"
> +                         "\xb2\x57\xaf\x78\x99\x05\x12\xab"
> +                         "\x48\x90\x80\xf0\x12\x9b\x20\x64"
> +                         "\x7a\x1d\x47\x5f\xba\x3c\xf9\xc3"
> +                         "\x0a\x0d\x8d\xa1\xf9\x1b\x82\x13"
> +                         "\x3e\x0d\xec\x0a\x83\xc0\x65\xe1"
> +                         "\xe9\x95\xff\x97\xd6\xf2\xe4\xd5"
> +                         "\x86\xc0\x1f\x29\x27\x63\xd7\xde"
> +                         "\xb7\x0a\x07\x99\x04\x2d\xa3\x89"
> +                         "\xa2\x43\xcf\xf3\xe1\x43\xac\x4a"
> +                         "\x06\x97\xd0\x05\x4f\x87\xfa\xf9"
> +                         "\x9b\xbf\x52\x70\xbd\xbc\x6c\xf3"
> +                         "\x03\x13\x60\x41\x28\x09\xec\xcc"
> +                         "\xb1\x1a\xec\xd6\xfb\x6f\x2a\x89"
> +                         "\x5d\x0b\x53\x9c\x59\xc1\x84\x21"
> +                         "\x33\x51\x47\x19\x31\x9c\xd4\x0a"
> +                         "\x4d\x04\xec\x50\x90\x61\xbd\xbc"
> +                         "\x7e\xc8\xd9\x6c\x98\x1d\x45\x41"
> +                         "\x17\x5e\x97\x1c\xc5\xa8\xe8\xea"
> +                         "\x46\x58\x53\xf7\x17\xd5\xad\x11"
> +                         "\xc8\x54\xf5\x7a\x33\x90\xf5\x19"
> +                         "\xba\x36\xb4\xfc\x52\xa5\x72\x3d"
> +                         "\x14\xbb\x55\xa7\xe9\xe3\x12\xf7"
> +                         "\x1c\x30\xa2\x82\x03\xbf\x53\x91"
> +                         "\x2e\x60\x41\x9f\x5b\x69\x39\xf6"
> +                         "\x4d\xc8\xf8\x46\x7a\x7f\xa4\x98"
> +                         "\x36\xff\x06\xcb\xca\xe7\x33\xf2"
> +                         "\xc0\x4a\xf4\x3c\x14\x44\x5f\x6b"
> +                         "\x75\xef\x02\x36\x75\x08\x14\xfd"
> +                         "\x10\x8e\xa5\x58\xd0\x30\x46\x49"
> +                         "\xaf\x3a\xf8\x40\x3d\x35\xdb\x84"
> +                         "\x11\x2e\x97\x6a\xb7\x87\x7f\xad"
> +                         "\xf1\xfa\xa5\x63\x60\xd8\x5e\xbf"
> +                         "\x41\x78\x49\xcf\x77\xbb\x56\xbb"
> +                         "\x7d\x01\x67\x05\x22\xc8\x8f\x41"
> +                         "\xba\x81\xd2\xca\x2c\x38\xac\x76"
> +                         "\x06\xc1\x1a\xc2\xce\xac\x90\x67"
> +                         "\x57\x3e\x20\x12\x5b\xd9\x97\x58"
> +                         "\x65\x05\xb7\x04\x61\x7e\xd8\x3a"
> +                         "\xbf\x55\x3b\x13\xe9\x34\x5a\x37"
> +                         "\x36\xcb\x94\x45\xc5\x32\xb3\xa0"
> +                         "\x0c\x3e\x49\xc5\xd3\xed\xa7\xf0"
> +                         "\x1c\x69\xcc\xea\xcc\x83\xc9\x16"
> +                         "\x95\x72\x4b\xf4\x89\xd5\xb9\x10"
> +                         "\xf6\x2d\x60\x15\xea\x3c\x06\x66"
> +                         "\x9f\x82\xad\x17\xce\xd2\xa4\x48"
> +                         "\x7c\x65\xd9\xf8\x02\x4d\x9b\x4c"
> +                         "\x89\x06\x3a\x34\x85\x48\x89\x86"
> +                         "\xf9\x24\xa9\x54\x72\xdb\x44\x95"
> +                         "\xc7\x44\x1c\x19\x11\x4c\x04\xdc"
> +                         "\x13\xb9\x67\xc8\xc3\x3a\x6a\x50"
> +                         "\xfa\xd1\xfb\xe1\x88\xb6\xf1\xa3"
> +                         "\xc5\x3b\xdc\x38\x45\x16\x26\x02"
> +                         "\x3b\xb8\x8f\x8b\x58\x7d\x23\x04"
> +                         "\x50\x6b\x81\x9f\xae\x66\xac\x6f"
> +                         "\xcf\x2a\x9d\xf1\xfd\x1d\x57\x07"
> +                         "\xbe\x58\xeb\x77\x0c\xe3\xc2\x19"
> +                         "\x14\x74\x1b\x51\x1c\x4f\x41\xf3"
> +                         "\x32\x89\xb3\xe7\xde\x62\xf6\x5f"
> +                         "\xc7\x6a\x4a\x2a\x5b\x0f\x5f\x87"
> +                         "\x9c\x08\xb9\x02\x88\xc8\x29\xb7"
> +                         "\x94\x52\xfa\x52\xfe\xaa\x50\x10"
> +                         "\xba\x48\x75\x5e\x11\x1b\xe6\x39"
> +                         "\xd7\x82\x2c\x87\xf1\x1e\xa4\x38"
> +                         "\x72\x3e\x51\xe7\xd8\x3e\x5b\x7b"
> +                         "\x31\x16\x89\xba\xd6\xad\x18\x5e"
> +                         "\xba\xf8\x12\xb3\xf4\x6c\x47\x30"
> +                         "\xc0\x38\x58\xb3\x10\x8d\x58\x5d"
> +                         "\xb4\xfb\x19\x7e\x41\xc3\x66\xb8"
> +                         "\xd6\x72\x84\xe1\x1a\xc2\x71\x4c"
> +                         "\x0d\x4a\x21\x7a\xab\xa2\xc0\x36"
> +                         "\x15\xc5\xe9\x46\xd7\x29\x17\x76"
> +                         "\x5e\x47\x36\x7f\x72\x05\xa7\xcc"
> +                         "\x36\x63\xf9\x47\x7d\xe6\x07\x3c"
> +                         "\x8b\x79\x1d\x96\x61\x8d\x90\x65"
> +                         "\x7c\xf5\xeb\x4e\x6e\x09\x59\x6d"
> +                         "\x62\x50\x1b\x0f\xe0\xdc\x78\xf2"
> +                         "\x5b\x83\x1a\xa1\x11\x75\xfd\x18"
> +                         "\xd7\xe2\x8d\x65\x14\x21\xce\xbe"
> +                         "\xb5\x87\xe3\x0a\xda\x24\x0a\x64"
> +                         "\xa9\x9f\x03\x8d\x46\x5d\x24\x1a"
> +                         "\x8a\x0c\x42\x01\xca\xb1\x5f\x7c"
> +                         "\xa5\xac\x32\x4a\xb8\x07\x91\x18"
> +                         "\x6f\xb0\x71\x3c\xc9\xb1\xa8\xf8"
> +                         "\x5f\x69\xa5\xa1\xca\x9e\x7a\xaa"
> +                         "\xac\xe9\xc7\x47\x41\x75\x25\xc3"
> +                         "\x73\xe2\x0b\xdd\x6d\x52\x71\xbe"
> +                         "\xc5\xdc\xb4\xe7\x01\x26\x53\x77"
> +                         "\x86\x90\x85\x68\x6b\x7b\x03\x53"
> +                         "\xda\x52\x52\x51\x68\xc8\xf3\xec"
> +                         "\x6c\xd5\x03\x7a\xa3\x0e\xb4\x02"
> +                         "\x5f\x1a\xab\xee\xca\x67\x29\x7b"
> +                         "\xbd\x96\x59\xb3\x8b\x32\x7a\x92"
> +                         "\x9f\xd8\x25\x2b\xdf\xc0\x4c\xda",
> +               .ksize  = 1088,
> +               .plaintext      = "\xbc\xda\x81\xa8\x78\x79\x1c\xbf"
> +                         "\x77\x53\xba\x4c\x30\x5b\xb8\x33",
> +               .psize  = 16,
> +               .digest = "\x04\xbf\x7f\x6a\xce\x72\xea\x6a"
> +                         "\x79\xdb\xb0\xc9\x60\xf6\x12\xcc",
> +               .np     = 6,
> +               .tap    = { 4, 4, 1, 1, 1, 5 },
> +       }, {
> +               .key    = "\x65\x4d\xe3\xf8\xd2\x4c\xac\x28"
> +                         "\x68\xf5\xb3\x81\x71\x4b\xa1\xfa"
> +                         "\x04\x0e\xd3\x81\x36\xbe\x0c\x81"
> +                         "\x5e\xaf\xbc\x3a\xa4\xc0\x8e\x8b"
> +                         "\x55\x63\xd3\x52\x97\x88\xd6\x19"
> +                         "\xbc\x96\xdf\x49\xff\x04\x63\xf5"
> +                         "\x0c\x11\x13\xaa\x9e\x1f\x5a\xf7"
> +                         "\xdd\xbd\x37\x80\xc3\xd0\xbe\xa7"
> +                         "\x05\xc8\x3c\x98\x1e\x05\x3c\x84"
> +                         "\x39\x61\xc4\xed\xed\x71\x1b\xc4"
> +                         "\x74\x45\x2c\xa1\x56\x70\x97\xfd"
> +                         "\x44\x18\x07\x7d\xca\x60\x1f\x73"
> +                         "\x3b\x6d\x21\xcb\x61\x87\x70\x25"
> +                         "\x46\x21\xf1\x1f\x21\x91\x31\x2d"
> +                         "\x5d\xcc\xb7\xd1\x84\x3e\x3d\xdb"
> +                         "\x03\x53\x2a\x82\xa6\x9a\x95\xbc"
> +                         "\x1a\x1e\x0a\x5e\x07\x43\xab\x43"
> +                         "\xaf\x92\x82\x06\x91\x04\x09\xf4"
> +                         "\x17\x0a\x9a\x2c\x54\xdb\xb8\xf4"
> +                         "\xd0\xf0\x10\x66\x24\x8d\xcd\xda"
> +                         "\xfe\x0e\x45\x9d\x6f\xc4\x4e\xf4"
> +                         "\x96\xaf\x13\xdc\xa9\xd4\x8c\xc4"
> +                         "\xc8\x57\x39\x3c\xc2\xd3\x0a\x76"
> +                         "\x4a\x1f\x75\x83\x44\xc7\xd1\x39"
> +                         "\xd8\xb5\x41\xba\x73\x87\xfa\x96"
> +                         "\xc7\x18\x53\xfb\x9b\xda\xa0\x97"
> +                         "\x1d\xee\x60\x85\x9e\x14\xc3\xce"
> +                         "\xc4\x05\x29\x3b\x95\x30\xa3\xd1"
> +                         "\x9f\x82\x6a\x04\xf5\xa7\x75\x57"
> +                         "\x82\x04\xfe\x71\x51\x71\xb1\x49"
> +                         "\x50\xf8\xe0\x96\xf1\xfa\xa8\x88"
> +                         "\x3f\xa0\x86\x20\xd4\x60\x79\x59"
> +                         "\x17\x2d\xd1\x09\xf4\xec\x05\x57"
> +                         "\xcf\x62\x7e\x0e\x7e\x60\x78\xe6"
> +                         "\x08\x60\x29\xd8\xd5\x08\x1a\x24"
> +                         "\xc4\x6c\x24\xe7\x92\x08\x3d\x8a"
> +                         "\x98\x7a\xcf\x99\x0a\x65\x0e\xdc"
> +                         "\x8c\x8a\xbe\x92\x82\x91\xcc\x62"
> +                         "\x30\xb6\xf4\x3f\xc6\x8a\x7f\x12"
> +                         "\x4a\x8a\x49\xfa\x3f\x5c\xd4\x5a"
> +                         "\xa6\x82\xa3\xe6\xaa\x34\x76\xb2"
> +                         "\xab\x0a\x30\xef\x6c\x77\x58\x3f"
> +                         "\x05\x6b\xcc\x5c\xae\xdc\xd7\xb9"
> +                         "\x51\x7e\x8d\x32\x5b\x24\x25\xbe"
> +                         "\x2b\x24\x01\xcf\x80\xda\x16\xd8"
> +                         "\x90\x72\x2c\xad\x34\x8d\x0c\x74"
> +                         "\x02\xcb\xfd\xcf\x6e\xef\x97\xb5"
> +                         "\x4c\xf2\x68\xca\xde\x43\x9e\x8a"
> +                         "\xc5\x5f\x31\x7f\x14\x71\x38\xec"
> +                         "\xbd\x98\xe5\x71\xc4\xb5\xdb\xef"
> +                         "\x59\xd2\xca\xc0\xc1\x86\x75\x01"
> +                         "\xd4\x15\x0d\x6f\xa4\xf7\x7b\x37"
> +                         "\x47\xda\x18\x93\x63\xda\xbe\x9e"
> +                         "\x07\xfb\xb2\x83\xd5\xc4\x34\x55"
> +                         "\xee\x73\xa1\x42\x96\xf9\x66\x41"
> +                         "\xa4\xcc\xd2\x93\x6e\xe1\x0a\xbb"
> +                         "\xd2\xdd\x18\x23\xe6\x6b\x98\x0b"
> +                         "\x8a\x83\x59\x2c\xc3\xa6\x59\x5b"
> +                         "\x01\x22\x59\xf7\xdc\xb0\x87\x7e"
> +                         "\xdb\x7d\xf4\x71\x41\xab\xbd\xee"
> +                         "\x79\xbe\x3c\x01\x76\x0b\x2d\x0a"
> +                         "\x42\xc9\x77\x8c\xbb\x54\x95\x60"
> +                         "\x43\x2e\xe0\x17\x52\xbd\x90\xc9"
> +                         "\xc2\x2c\xdd\x90\x24\x22\x76\x40"
> +                         "\x5c\xb9\x41\xc9\xa1\xd5\xbd\xe3"
> +                         "\x44\xe0\xa4\xab\xcc\xb8\xe2\x32"
> +                         "\x02\x15\x04\x1f\x8c\xec\x5d\x14"
> +                         "\xac\x18\xaa\xef\x6e\x33\x19\x6e"
> +                         "\xde\xfe\x19\xdb\xeb\x61\xca\x18"
> +                         "\xad\xd8\x3d\xbf\x09\x11\xc7\xa5"
> +                         "\x86\x0b\x0f\xe5\x3e\xde\xe8\xd9"
> +                         "\x0a\x69\x9e\x4c\x20\xff\xf9\xc5"
> +                         "\xfa\xf8\xf3\x7f\xa5\x01\x4b\x5e"
> +                         "\x0f\xf0\x3b\x68\xf0\x46\x8c\x2a"
> +                         "\x7a\xc1\x8f\xa0\xfe\x6a\x5b\x44"
> +                         "\x70\x5c\xcc\x92\x2c\x6f\x0f\xbd"
> +                         "\x25\x3e\xb7\x8e\x73\x58\xda\xc9"
> +                         "\xa5\xaa\x9e\xf3\x9b\xfd\x37\x3e"
> +                         "\xe2\x88\xa4\x7b\xc8\x5c\xa8\x93"
> +                         "\x0e\xe7\x9a\x9c\x2e\x95\x18\x9f"
> +                         "\xc8\x45\x0c\x88\x9e\x53\x4f\x3a"
> +                         "\x76\xc1\x35\xfa\x17\xd8\xac\xa0"
> +                         "\x0c\x2d\x47\x2e\x4f\x69\x9b\xf7"
> +                         "\xd0\xb6\x96\x0c\x19\xb3\x08\x01"
> +                         "\x65\x7a\x1f\xc7\x31\x86\xdb\xc8"
> +                         "\xc1\x99\x8f\xf8\x08\x4a\x9d\x23"
> +                         "\x22\xa8\xcf\x27\x01\x01\x88\x93"
> +                         "\x9c\x86\x45\xbd\xe0\x51\xca\x52"
> +                         "\x84\xba\xfe\x03\xf7\xda\xc5\xce"
> +                         "\x3e\x77\x75\x86\xaf\x84\xc8\x05"
> +                         "\x44\x01\x0f\x02\xf3\x58\xb0\x06"
> +                         "\x5a\xd7\x12\x30\x8d\xdf\x1f\x1f"
> +                         "\x0a\xe6\xd2\xea\xf6\x3a\x7a\x99"
> +                         "\x63\xe8\xd2\xc1\x4a\x45\x8b\x40"
> +                         "\x4d\x0a\xa9\x76\x92\xb3\xda\x87"
> +                         "\x36\x33\xf0\x78\xc3\x2f\x5f\x02"
> +                         "\x1a\x6a\x2c\x32\xcd\x76\xbf\xbd"
> +                         "\x5a\x26\x20\x28\x8c\x8c\xbc\x52"
> +                         "\x3d\x0a\xc9\xcb\xab\xa4\x21\xb0"
> +                         "\x54\x40\x81\x44\xc7\xd6\x1c\x11"
> +                         "\x44\xc6\x02\x92\x14\x5a\xbf\x1a"
> +                         "\x09\x8a\x18\xad\xcd\x64\x3d\x53"
> +                         "\x4a\xb6\xa5\x1b\x57\x0e\xef\xe0"
> +                         "\x8c\x44\x5f\x7d\xbd\x6c\xfd\x60"
> +                         "\xae\x02\x24\xb6\x99\xdd\x8c\xaf"
> +                         "\x59\x39\x75\x3c\xd1\x54\x7b\x86"
> +                         "\xcc\x99\xd9\x28\x0c\xb0\x94\x62"
> +                         "\xf9\x51\xd1\x19\x96\x2d\x66\xf5"
> +                         "\x55\xcf\x9e\x59\xe2\x6b\x2c\x08"
> +                         "\xc0\x54\x48\x24\x45\xc3\x8c\x73"
> +                         "\xea\x27\x6e\x66\x7d\x1d\x0e\x6e"
> +                         "\x13\xe8\x56\x65\x3a\xb0\x81\x5c"
> +                         "\xf0\xe8\xd8\x00\x6b\xcd\x8f\xad"
> +                         "\xdd\x53\xf3\xa4\x6c\x43\xd6\x31"
> +                         "\xaf\xd2\x76\x1e\x91\x12\xdb\x3c"
> +                         "\x8c\xc2\x81\xf0\x49\xdb\xe2\x6b"
> +                         "\x76\x62\x0a\x04\xe4\xaa\x8a\x7c"
> +                         "\x08\x0b\x5d\xd0\xee\x1d\xfb\xc4"
> +                         "\x02\x75\x42\xd6\xba\xa7\x22\xa8"
> +                         "\x47\x29\xb7\x85\x6d\x93\x3a\xdb"
> +                         "\x00\x53\x0b\xa2\xeb\xf8\xfe\x01"
> +                         "\x6f\x8a\x31\xd6\x17\x05\x6f\x67"
> +                         "\x88\x95\x32\xfe\x4f\xa6\x4b\xf8"
> +                         "\x03\xe4\xcd\x9a\x18\xe8\x4e\x2d"
> +                         "\xf7\x97\x9a\x0c\x7d\x9f\x7e\x44"
> +                         "\x69\x51\xe0\x32\x6b\x62\x86\x8f"
> +                         "\xa6\x8e\x0b\x21\x96\xe5\xaf\x77"
> +                         "\xc0\x83\xdf\xa5\x0e\xd0\xa1\x04"
> +                         "\xaf\xc1\x10\xcb\x5a\x40\xe4\xe3"
> +                         "\x38\x7e\x07\xe8\x4d\xfa\xed\xc5"
> +                         "\xf0\x37\xdf\xbb\x8a\xcf\x3d\xdc"
> +                         "\x61\xd2\xc6\x2b\xff\x07\xc9\x2f"
> +                         "\x0c\x2d\x5c\x07\xa8\x35\x6a\xfc"
> +                         "\xae\x09\x03\x45\x74\x51\x4d\xc4"
> +                         "\xb8\x23\x87\x4a\x99\x27\x20\x87"
> +                         "\x62\x44\x0a\x4a\xce\x78\x47\x22",
> +               .ksize  = 1088,
> +               .plaintext      = "\x8e\xb0\x4c\xde\x9c\x4a\x04\x5a"
> +                         "\xf6\xa9\x7f\x45\x25\xa5\x7b\x3a"
> +                         "\xbc\x4d\x73\x39\x81\xb5\xbd\x3d"
> +                         "\x21\x6f\xd7\x37\x50\x3c\x7b\x28"
> +                         "\xd1\x03\x3a\x17\xed\x7b\x7c\x2a"
> +                         "\x16\xbc\xdf\x19\x89\x52\x71\x31"
> +                         "\xb6\xc0\xfd\xb5\xd3\xba\x96\x99"
> +                         "\xb6\x34\x0b\xd0\x99\x93\xfc\x1a"
> +                         "\x01\x3c\x85\xc6\x9b\x78\x5c\x8b"
> +                         "\xfe\xae\xd2\xbf\xb2\x6f\xf9\xed"
> +                         "\xc8\x25\x17\xfe\x10\x3b\x7d\xda"
> +                         "\xf4\x8d\x35\x4b\x7c\x7b\x82\xe7"
> +                         "\xc2\xb3\xee\x60\x4a\x03\x86\xc9"
> +                         "\x4e\xb5\xc4\xbe\xd2\xbd\x66\xf1"
> +                         "\x13\xf1\x09\xab\x5d\xca\x63\x1f"
> +                         "\xfc\xfb\x57\x2a\xfc\xca\x66\xd8"
> +                         "\x77\x84\x38\x23\x1d\xac\xd3\xb3"
> +                         "\x7a\xad\x4c\x70\xfa\x9c\xc9\x61"
> +                         "\xa6\x1b\xba\x33\x4b\x4e\x33\xec"
> +                         "\xa0\xa1\x64\x39\x40\x05\x1c\xc2"
> +                         "\x3f\x49\x9d\xae\xf2\xc5\xf2\xc5"
> +                         "\xfe\xe8\xf4\xc2\xf9\x96\x2d\x28"
> +                         "\x92\x30\x44\xbc\xd2\x7f\xe1\x6e"
> +                         "\x62\x02\x8f\x3d\x1c\x80\xda\x0e"
> +                         "\x6a\x90\x7e\x75\xff\xec\x3e\xc4"
> +                         "\xcd\x16\x34\x3b\x05\x6d\x4d\x20"
> +                         "\x1c\x7b\xf5\x57\x4f\xfa\x3d\xac"
> +                         "\xd0\x13\x55\xe8\xb3\xe1\x1b\x78"
> +                         "\x30\xe6\x9f\x84\xd4\x69\xd1\x08"
> +                         "\x12\x77\xa7\x4a\xbd\xc0\xf2\xd2"
> +                         "\x78\xdd\xa3\x81\x12\xcb\x6c\x14"
> +                         "\x90\x61\xe2\x84\xc6\x2b\x16\xcc"
> +                         "\x40\x99\x50\x88\x01\x09\x64\x4f"
> +                         "\x0a\x80\xbe\x61\xae\x46\xc9\x0a"
> +                         "\x5d\xe0\xfb\x72\x7a\x1a\xdd\x61"
> +                         "\x63\x20\x05\xa0\x4a\xf0\x60\x69"
> +                         "\x7f\x92\xbc\xbf\x4e\x39\x4d\xdd"
> +                         "\x74\xd1\xb7\xc0\x5a\x34\xb7\xae"
> +                         "\x76\x65\x2e\xbc\x36\xb9\x04\x95"
> +                         "\x42\xe9\x6f\xca\x78\xb3\x72\x07"
> +                         "\xa3\xba\x02\x94\x67\x4c\xb1\xd7"
> +                         "\xe9\x30\x0d\xf0\x3b\xb8\x10\x6d"
> +                         "\xea\x2b\x21\xbf\x74\x59\x82\x97"
> +                         "\x85\xaa\xf1\xd7\x54\x39\xeb\x05"
> +                         "\xbd\xf3\x40\xa0\x97\xe6\x74\xfe"
> +                         "\xb4\x82\x5b\xb1\x36\xcb\xe8\x0d"
> +                         "\xce\x14\xd9\xdf\xf1\x94\x22\xcd"
> +                         "\xd6\x00\xba\x04\x4c\x05\x0c\xc0"
> +                         "\xd1\x5a\xeb\x52\xd5\xa8\x8e\xc8"
> +                         "\x97\xa1\xaa\xc1\xea\xc1\xbe\x7c"
> +                         "\x36\xb3\x36\xa0\xc6\x76\x66\xc5"
> +                         "\xe2\xaf\xd6\x5c\xe2\xdb\x2c\xb3"
> +                         "\x6c\xb9\x99\x7f\xff\x9f\x03\x24"
> +                         "\xe1\x51\x44\x66\xd8\x0c\x5d\x7f"
> +                         "\x5c\x85\x22\x2a\xcf\x6d\x79\x28"
> +                         "\xab\x98\x01\x72\xfe\x80\x87\x5f"
> +                         "\x46\xba\xef\x81\x24\xee\xbf\xb0"
> +                         "\x24\x74\xa3\x65\x97\x12\xc4\xaf"
> +                         "\x8b\xa0\x39\xda\x8a\x7e\x74\x6e"
> +                         "\x1b\x42\xb4\x44\x37\xfc\x59\xfd"
> +                         "\x86\xed\xfb\x8c\x66\x33\xda\x63"
> +                         "\x75\xeb\xe1\xa4\x85\x4f\x50\x8f"
> +                         "\x83\x66\x0d\xd3\x37\xfa\xe6\x9c"
> +                         "\x4f\x30\x87\x35\x18\xe3\x0b\xb7"
> +                         "\x6e\x64\x54\xcd\x70\xb3\xde\x54"
> +                         "\xb7\x1d\xe6\x4c\x4d\x55\x12\x12"
> +                         "\xaf\x5f\x7f\x5e\xee\x9d\xe8\x8e"
> +                         "\x32\x9d\x4e\x75\xeb\xc6\xdd\xaa"
> +                         "\x48\x82\xa4\x3f\x3c\xd7\xd3\xa8"
> +                         "\x63\x9e\x64\xfe\xe3\x97\x00\x62"
> +                         "\xe5\x40\x5d\xc3\xad\x72\xe1\x28"
> +                         "\x18\x50\xb7\x75\xef\xcd\x23\xbf"
> +                         "\x3f\xc0\x51\x36\xf8\x41\xc3\x08"
> +                         "\xcb\xf1\x8d\x38\x34\xbd\x48\x45"
> +                         "\x75\xed\xbc\x65\x7b\xb5\x0c\x9b"
> +                         "\xd7\x67\x7d\x27\xb4\xc4\x80\xd7"
> +                         "\xa9\xb9\xc7\x4a\x97\xaa\xda\xc8"
> +                         "\x3c\x74\xcf\x36\x8f\xe4\x41\xe3"
> +                         "\xd4\xd3\x26\xa7\xf3\x23\x9d\x8f"
> +                         "\x6c\x20\x05\x32\x3e\xe0\xc3\xc8"
> +                         "\x56\x3f\xa7\x09\xb7\xfb\xc7\xf7"
> +                         "\xbe\x2a\xdd\x0f\x06\x7b\x0d\xdd"
> +                         "\xb0\xb4\x86\x17\xfd\xb9\x04\xe5"
> +                         "\xc0\x64\x5d\xad\x2a\x36\x38\xdb"
> +                         "\x24\xaf\x5b\xff\xca\xf9\x41\xe8"
> +                         "\xf9\x2f\x1e\x5e\xf9\xf5\xd5\xf2"
> +                         "\xb2\x88\xca\xc9\xa1\x31\xe2\xe8"
> +                         "\x10\x95\x65\xbf\xf1\x11\x61\x7a"
> +                         "\x30\x1a\x54\x90\xea\xd2\x30\xf6"
> +                         "\xa5\xad\x60\xf9\x4d\x84\x21\x1b"
> +                         "\xe4\x42\x22\xc8\x12\x4b\xb0\x58"
> +                         "\x3e\x9c\x2d\x32\x95\x0a\x8e\xb0"
> +                         "\x0a\x7e\x77\x2f\xe8\x97\x31\x6a"
> +                         "\xf5\x59\xb4\x26\xe6\x37\x12\xc9"
> +                         "\xcb\xa0\x58\x33\x6f\xd5\x55\x55"
> +                         "\x3c\xa1\x33\xb1\x0b\x7e\x2e\xb4"
> +                         "\x43\x2a\x84\x39\xf0\x9c\xf4\x69"
> +                         "\x4f\x1e\x79\xa6\x15\x1b\x87\xbb"
> +                         "\xdb\x9b\xe0\xf1\x0b\xba\xe3\x6e"
> +                         "\xcc\x2f\x49\x19\x22\x29\xfc\x71"
> +                         "\xbb\x77\x38\x18\x61\xaf\x85\x76"
> +                         "\xeb\xd1\x09\xcc\x86\x04\x20\x9a"
> +                         "\x66\x53\x2f\x44\x8b\xc6\xa3\xd2"
> +                         "\x5f\xc7\x79\x82\x66\xa8\x6e\x75"
> +                         "\x7d\x94\xd1\x86\x75\x0f\xa5\x4f"
> +                         "\x3c\x7a\x33\xce\xd1\x6e\x9d\x7b"
> +                         "\x1f\x91\x37\xb8\x37\x80\xfb\xe0"
> +                         "\x52\x26\xd0\x9a\xd4\x48\x02\x41"
> +                         "\x05\xe3\x5a\x94\xf1\x65\x61\x19"
> +                         "\xb8\x88\x4e\x2b\xea\xba\x8b\x58"
> +                         "\x8b\x42\x01\x00\xa8\xfe\x00\x5c"
> +                         "\xfe\x1c\xee\x31\x15\x69\xfa\xb3"
> +                         "\x9b\x5f\x22\x8e\x0d\x2c\xe3\xa5"
> +                         "\x21\xb9\x99\x8a\x8e\x94\x5a\xef"
> +                         "\x13\x3e\x99\x96\x79\x6e\xd5\x42"
> +                         "\x36\x03\xa9\xe2\xca\x65\x4e\x8a"
> +                         "\x8a\x30\xd2\x7d\x74\xe7\xf0\xaa"
> +                         "\x23\x26\xdd\xcb\x82\x39\xfc\x9d"
> +                         "\x51\x76\x21\x80\xa2\xbe\x93\x03"
> +                         "\x47\xb0\xc1\xb6\xdc\x63\xfd\x9f"
> +                         "\xca\x9d\xa5\xca\x27\x85\xe2\xd8"
> +                         "\x15\x5b\x7e\x14\x7a\xc4\x89\xcc"
> +                         "\x74\x14\x4b\x46\xd2\xce\xac\x39"
> +                         "\x6b\x6a\x5a\xa4\x0e\xe3\x7b\x15"
> +                         "\x94\x4b\x0f\x74\xcb\x0c\x7f\xa9"
> +                         "\xbe\x09\x39\xa3\xdd\x56\x5c\xc7"
> +                         "\x99\x56\x65\x39\xf4\x0b\x7d\x87"
> +                         "\xec\xaa\xe3\x4d\x22\x65\x39\x4e",
> +               .psize  = 1024,
> +               .digest = "\x64\x3a\xbc\xc3\x3f\x74\x40\x51"
> +                         "\x6e\x56\x01\x1a\x51\xec\x36\xde",
> +               .np     = 8,
> +               .tap    = { 64, 203, 267, 28, 263, 62, 54, 83 },
> +       }, {
> +               .key    = "\x1b\x82\x2e\x1b\x17\x23\xb9\x6d"
> +                         "\xdc\x9c\xda\x99\x07\xe3\x5f\xd8"
> +                         "\xd2\xf8\x43\x80\x8d\x86\x7d\x80"
> +                         "\x1a\xd0\xcc\x13\xb9\x11\x05\x3f"
> +                         "\x7e\xcf\x7e\x80\x0e\xd8\x25\x48"
> +                         "\x8b\xaa\x63\x83\x92\xd0\x72\xf5"
> +                         "\x4f\x67\x7e\x50\x18\x25\xa4\xd1"
> +                         "\xe0\x7e\x1e\xba\xd8\xa7\x6e\xdb"
> +                         "\x1a\xcc\x0d\xfe\x9f\x6d\x22\x35"
> +                         "\xe1\xe6\xe0\xa8\x7b\x9c\xb1\x66"
> +                         "\xa3\xf8\xff\x4d\x90\x84\x28\xbc"
> +                         "\xdc\x19\xc7\x91\x49\xfc\xf6\x33"
> +                         "\xc9\x6e\x65\x7f\x28\x6f\x68\x2e"
> +                         "\xdf\x1a\x75\xe9\xc2\x0c\x96\xb9"
> +                         "\x31\x22\xc4\x07\xc6\x0a\x2f\xfd"
> +                         "\x36\x06\x5f\x5c\xc5\xb1\x3a\xf4"
> +                         "\x5e\x48\xa4\x45\x2b\x88\xa7\xee"
> +                         "\xa9\x8b\x52\xcc\x99\xd9\x2f\xb8"
> +                         "\xa4\x58\x0a\x13\xeb\x71\x5a\xfa"
> +                         "\xe5\x5e\xbe\xf2\x64\xad\x75\xbc"
> +                         "\x0b\x5b\x34\x13\x3b\x23\x13\x9a"
> +                         "\x69\x30\x1e\x9a\xb8\x03\xb8\x8b"
> +                         "\x3e\x46\x18\x6d\x38\xd9\xb3\xd8"
> +                         "\xbf\xf1\xd0\x28\xe6\x51\x57\x80"
> +                         "\x5e\x99\xfb\xd0\xce\x1e\x83\xf7"
> +                         "\xe9\x07\x5a\x63\xa9\xef\xce\xa5"
> +                         "\xfb\x3f\x37\x17\xfc\x0b\x37\x0e"
> +                         "\xbb\x4b\x21\x62\xb7\x83\x0e\xa9"
> +                         "\x9e\xb0\xc4\xad\x47\xbe\x35\xe7"
> +                         "\x51\xb2\xf2\xac\x2b\x65\x7b\x48"
> +                         "\xe3\x3f\x5f\xb6\x09\x04\x0c\x58"
> +                         "\xce\x99\xa9\x15\x2f\x4e\xc1\xf2"
> +                         "\x24\x48\xc0\xd8\x6c\xd3\x76\x17"
> +                         "\x83\x5d\xe6\xe3\xfd\x01\x8e\xf7"
> +                         "\x42\xa5\x04\x29\x30\xdf\xf9\x00"
> +                         "\x4a\xdc\x71\x22\x1a\x33\x15\xb6"
> +                         "\xd7\x72\xfb\x9a\xb8\xeb\x2b\x38"
> +                         "\xea\xa8\x61\xa8\x90\x11\x9d\x73"
> +                         "\x2e\x6c\xce\x81\x54\x5a\x9f\xcd"
> +                         "\xcf\xd5\xbd\x26\x5d\x66\xdb\xfb"
> +                         "\xdc\x1e\x7c\x10\xfe\x58\x82\x10"
> +                         "\x16\x24\x01\xce\x67\x55\x51\xd1"
> +                         "\xdd\x6b\x44\xa3\x20\x8e\xa9\xa6"
> +                         "\x06\xa8\x29\x77\x6e\x00\x38\x5b"
> +                         "\xde\x4d\x58\xd8\x1f\x34\xdf\xf9"
> +                         "\x2c\xac\x3e\xad\xfb\x92\x0d\x72"
> +                         "\x39\xa4\xac\x44\x10\xc0\x43\xc4"
> +                         "\xa4\x77\x3b\xfc\xc4\x0d\x37\xd3"
> +                         "\x05\x84\xda\x53\x71\xf8\x80\xd3"
> +                         "\x34\x44\xdb\x09\xb4\x2b\x8e\xe3"
> +                         "\x00\x75\x50\x9e\x43\x22\x00\x0b"
> +                         "\x7c\x70\xab\xd4\x41\xf1\x93\xcd"
> +                         "\x25\x2d\x84\x74\xb5\xf2\x92\xcd"
> +                         "\x0a\x28\xea\x9a\x49\x02\x96\xcb"
> +                         "\x85\x9e\x2f\x33\x03\x86\x1d\xdc"
> +                         "\x1d\x31\xd5\xfc\x9d\xaa\xc5\xe9"
> +                         "\x9a\xc4\x57\xf5\x35\xed\xf4\x4b"
> +                         "\x3d\x34\xc2\x29\x13\x86\x36\x42"
> +                         "\x5d\xbf\x90\x86\x13\x77\xe5\xc3"
> +                         "\x62\xb4\xfe\x0b\x70\x39\x35\x65"
> +                         "\x02\xea\xf6\xce\x57\x0c\xbb\x74"
> +                         "\x29\xe3\xfd\x60\x90\xfd\x10\x38"
> +                         "\xd5\x4e\x86\xbd\x37\x70\xf0\x97"
> +                         "\xa6\xab\x3b\x83\x64\x52\xca\x66"
> +                         "\x2f\xf9\xa4\xca\x3a\x55\x6b\xb0"
> +                         "\xe8\x3a\x34\xdb\x9e\x48\x50\x2f"
> +                         "\x3b\xef\xfd\x08\x2d\x5f\xc1\x37"
> +                         "\x5d\xbe\x73\xe4\xd8\xe9\xac\xca"
> +                         "\x8a\xaa\x48\x7c\x5c\xf4\xa6\x96"
> +                         "\x5f\xfa\x70\xa6\xb7\x8b\x50\xcb"
> +                         "\xa6\xf5\xa9\xbd\x7b\x75\x4c\x22"
> +                         "\x0b\x19\x40\x2e\xc9\x39\x39\x32"
> +                         "\x83\x03\xa8\xa4\x98\xe6\x8e\x16"
> +                         "\xb9\xde\x08\xc5\xfc\xbf\xad\x39"
> +                         "\xa8\xc7\x93\x6c\x6f\x23\xaf\xc1"
> +                         "\xab\xe1\xdf\xbb\x39\xae\x93\x29"
> +                         "\x0e\x7d\x80\x8d\x3e\x65\xf3\xfd"
> +                         "\x96\x06\x65\x90\xa1\x28\x64\x4b"
> +                         "\x69\xf9\xa8\x84\x27\x50\xfc\x87"
> +                         "\xf7\xbf\x55\x8e\x56\x13\x58\x7b"
> +                         "\x85\xb4\x6a\x72\x0f\x40\xf1\x4f"
> +                         "\x83\x81\x1f\x76\xde\x15\x64\x7a"
> +                         "\x7a\x80\xe4\xc7\x5e\x63\x01\x91"
> +                         "\xd7\x6b\xea\x0b\x9b\xa2\x99\x3b"
> +                         "\x6c\x88\xd8\xfd\x59\x3c\x8d\x22"
> +                         "\x86\x56\xbe\xab\xa1\x37\x08\x01"
> +                         "\x50\x85\x69\x29\xee\x9f\xdf\x21"
> +                         "\x3e\x20\x20\xf5\xb0\xbb\x6b\xd0"
> +                         "\x9c\x41\x38\xec\x54\x6f\x2d\xbd"
> +                         "\x0f\xe1\xbd\xf1\x2b\x6e\x60\x56"
> +                         "\x29\xe5\x7a\x70\x1c\xe2\xfc\x97"
> +                         "\x82\x68\x67\xd9\x3d\x1f\xfb\xd8"
> +                         "\x07\x9f\xbf\x96\x74\xba\x6a\x0e"
> +                         "\x10\x48\x20\xd8\x13\x1e\xb5\x44"
> +                         "\xf2\xcc\xb1\x8b\xfb\xbb\xec\xd7"
> +                         "\x37\x70\x1f\x7c\x55\xd2\x4b\xb9"
> +                         "\xfd\x70\x5e\xa3\x91\x73\x63\x52"
> +                         "\x13\x47\x5a\x06\xfb\x01\x67\xa5"
> +                         "\xc0\xd0\x49\x19\x56\x66\x9a\x77"
> +                         "\x64\xaf\x8c\x25\x91\x52\x87\x0e"
> +                         "\x18\xf3\x5f\x97\xfd\x71\x13\xf8"
> +                         "\x05\xa5\x39\xcc\x65\xd3\xcc\x63"
> +                         "\x5b\xdb\x5f\x7e\x5f\x6e\xad\xc4"
> +                         "\xf4\xa0\xc5\xc2\x2b\x4d\x97\x38"
> +                         "\x4f\xbc\xfa\x33\x17\xb4\x47\xb9"
> +                         "\x43\x24\x15\x8d\xd2\xed\x80\x68"
> +                         "\x84\xdb\x04\x80\xca\x5e\x6a\x35"
> +                         "\x2c\x2c\xe7\xc5\x03\x5f\x54\xb0"
> +                         "\x5e\x4f\x1d\x40\x54\x3d\x78\x9a"
> +                         "\xac\xda\x80\x27\x4d\x15\x4c\x1a"
> +                         "\x6e\x80\xc9\xc4\x3b\x84\x0e\xd9"
> +                         "\x2e\x93\x01\x8c\xc3\xc8\x91\x4b"
> +                         "\xb3\xaa\x07\x04\x68\x5b\x93\xa5"
> +                         "\xe7\xc4\x9d\xe7\x07\xee\xf5\x3b"
> +                         "\x40\x89\xcc\x60\x34\x9d\xb4\x06"
> +                         "\x1b\xef\x92\xe6\xc1\x2a\x7d\x0f"
> +                         "\x81\xaa\x56\xe3\xd7\xed\xa7\xd4"
> +                         "\xa7\x3a\x49\xc4\xad\x81\x5c\x83"
> +                         "\x55\x8e\x91\x54\xb7\x7d\x65\xa5"
> +                         "\x06\x16\xd5\x9a\x16\xc1\xb0\xa2"
> +                         "\x06\xd8\x98\x47\x73\x7e\x73\xa0"
> +                         "\xb8\x23\xb1\x52\xbf\x68\x74\x5d"
> +                         "\x0b\xcb\xfa\x8c\x46\xe3\x24\xe6"
> +                         "\xab\xd4\x69\x8d\x8c\xf2\x8a\x59"
> +                         "\xbe\x48\x46\x50\x8c\x9a\xe8\xe3"
> +                         "\x31\x55\x0a\x06\xed\x4f\xf8\xb7"
> +                         "\x4f\xe3\x85\x17\x30\xbd\xd5\x20"
> +                         "\xe7\x5b\xb2\x32\xcf\x6b\x16\x44"
> +                         "\xd2\xf5\x7e\xd7\xd1\x2f\xee\x64"
> +                         "\x3e\x9d\x10\xef\x27\x35\x43\x64"
> +                         "\x67\xfb\x7a\x7b\xe0\x62\x31\x9a"
> +                         "\x4d\xdf\xa5\xab\xc0\x20\xbb\x01"
> +                         "\xe9\x7b\x54\xf1\xde\xb2\x79\x50"
> +                         "\x6c\x4b\x91\xdb\x7f\xbb\x50\xc1"
> +                         "\x55\x44\x38\x9a\xe0\x9f\xe8\x29"
> +                         "\x6f\x15\xf8\x4e\xa6\xec\xa0\x60",
> +               .ksize  = 1088,
> +               .plaintext      = "\x15\x68\x9e\x2f\xad\x15\x52\xdf"
> +                         "\xf0\x42\x62\x24\x2a\x2d\xea\xbf"
> +                         "\xc7\xf3\xb4\x1a\xf5\xed\xb2\x08"
> +                         "\x15\x60\x1c\x00\x77\xbf\x0b\x0e"
> +                         "\xb7\x2c\xcf\x32\x3a\xc7\x01\x77"
> +                         "\xef\xa6\x75\xd0\x29\xc7\x68\x20"
> +                         "\xb2\x92\x25\xbf\x12\x34\xe9\xa4"
> +                         "\xfd\x32\x7b\x3f\x7c\xbd\xa5\x02"
> +                         "\x38\x41\xde\xc9\xc1\x09\xd9\xfc"
> +                         "\x6e\x78\x22\x83\x18\xf7\x50\x8d"
> +                         "\x8f\x9c\x2d\x02\xa5\x30\xac\xff"
> +                         "\xea\x63\x2e\x80\x37\x83\xb0\x58"
> +                         "\xda\x2f\xef\x21\x55\xba\x7b\xb1"
> +                         "\xb6\xed\xf5\xd2\x4d\xaa\x8c\xa9"
> +                         "\xdd\xdb\x0f\xb4\xce\xc1\x9a\xb1"
> +                         "\xc1\xdc\xbd\xab\x86\xc2\xdf\x0b"
> +                         "\xe1\x2c\xf9\xbe\xf6\xd8\xda\x62"
> +                         "\x72\xdd\x98\x09\x52\xc0\xc4\xb6"
> +                         "\x7b\x17\x5c\xf5\xd8\x4b\x88\xd6"
> +                         "\x6b\xbf\x84\x4a\x3f\xf5\x4d\xd2"
> +                         "\x94\xe2\x9c\xff\xc7\x3c\xd9\xc8"
> +                         "\x37\x38\xbc\x8c\xf3\xe7\xb7\xd0"
> +                         "\x1d\x78\xc4\x39\x07\xc8\x5e\x79"
> +                         "\xb6\x5a\x90\x5b\x6e\x97\xc9\xd4"
> +                         "\x82\x9c\xf3\x83\x7a\xe7\x97\xfc"
> +                         "\x1d\xbb\xef\xdb\xce\xe0\x82\xad"
> +                         "\xca\x07\x6c\x54\x62\x6f\x81\xe6"
> +                         "\x7a\x5a\x96\x6e\x80\x3a\xa2\x37"
> +                         "\x6f\xc6\xa4\x29\xc3\x9e\x19\x94"
> +                         "\x9f\xb0\x3e\x38\xfb\x3c\x2b\x7d"
> +                         "\xaa\xb8\x74\xda\x54\x23\x51\x12"
> +                         "\x4b\x96\x36\x8f\x91\x4f\x19\x37"
> +                         "\x83\xc9\xdd\xc7\x1a\x32\x2d\xab"
> +                         "\xc7\x89\xe2\x07\x47\x6c\xe8\xa6"
> +                         "\x70\x6b\x8e\x0c\xda\x5c\x6a\x59"
> +                         "\x27\x33\x0e\xe1\xe1\x20\xe8\xc8"
> +                         "\xae\xdc\xd0\xe3\x6d\xa8\xa6\x06"
> +                         "\x41\xb4\xd4\xd4\xcf\x91\x3e\x06"
> +                         "\xb0\x9a\xf7\xf1\xaa\xa6\x23\x92"
> +                         "\x10\x86\xf0\x94\xd1\x7c\x2e\x07"
> +                         "\x30\xfb\xc5\xd8\xf3\x12\xa9\xe8"
> +                         "\x22\x1c\x97\x1a\xad\x96\xb0\xa1"
> +                         "\x72\x6a\x6b\xb4\xfd\xf7\xe8\xfa"
> +                         "\xe2\x74\xd8\x65\x8d\x35\x17\x4b"
> +                         "\x00\x23\x5c\x8c\x70\xad\x71\xa2"
> +                         "\xca\xc5\x6c\x59\xbf\xb4\xc0\x6d"
> +                         "\x86\x98\x3e\x19\x5a\x90\x92\xb1"
> +                         "\x66\x57\x6a\x91\x68\x7c\xbc\xf3"
> +                         "\xf1\xdb\x94\xf8\x48\xf1\x36\xd8"
> +                         "\x78\xac\x1c\xa9\xcc\xd6\x27\xba"
> +                         "\x91\x54\x22\xf5\xe6\x05\x3f\xcc"
> +                         "\xc2\x8f\x2c\x3b\x2b\xc3\x2b\x2b"
> +                         "\x3b\xb8\xb6\x29\xb7\x2f\x94\xb6"
> +                         "\x7b\xfc\x94\x3e\xd0\x7a\x41\x59"
> +                         "\x7b\x1f\x9a\x09\xa6\xed\x4a\x82"
> +                         "\x9d\x34\x1c\xbd\x4e\x1c\x3a\x66"
> +                         "\x80\x74\x0e\x9a\x4f\x55\x54\x47"
> +                         "\x16\xba\x2a\x0a\x03\x35\x99\xa3"
> +                         "\x5c\x63\x8d\xa2\x72\x8b\x17\x15"
> +                         "\x68\x39\x73\xeb\xec\xf2\xe8\xf5"
> +                         "\x95\x32\x27\xd6\xc4\xfe\xb0\x51"
> +                         "\xd5\x0c\x50\xc5\xcd\x6d\x16\xb3"
> +                         "\xa3\x1e\x95\x69\xad\x78\x95\x06"
> +                         "\xb9\x46\xf2\x6d\x24\x5a\x99\x76"
> +                         "\x73\x6a\x91\xa6\xac\x12\xe1\x28"
> +                         "\x79\xbc\x08\x4e\x97\x00\x98\x63"
> +                         "\x07\x1c\x4e\xd1\x68\xf3\xb3\x81"
> +                         "\xa8\xa6\x5f\xf1\x01\xc9\xc1\xaf"
> +                         "\x3a\x96\xf9\x9d\xb5\x5a\x5f\x8f"
> +                         "\x7e\xc1\x7e\x77\x0a\x40\xc8\x8e"
> +                         "\xfc\x0e\xed\xe1\x0d\xb0\xe5\x5e"
> +                         "\x5e\x6f\xf5\x7f\xab\x33\x7d\xcd"
> +                         "\xf0\x09\x4b\xb2\x11\x37\xdc\x65"
> +                         "\x97\x32\x62\x71\x3a\x29\x54\xb9"
> +                         "\xc7\xa4\xbf\x75\x0f\xf9\x40\xa9"
> +                         "\x8d\xd7\x8b\xa7\xe0\x9a\xbe\x15"
> +                         "\xc6\xda\xd8\x00\x14\x69\x1a\xaf"
> +                         "\x5f\x79\xc3\xf5\xbb\x6c\x2a\x9d"
> +                         "\xdd\x3c\x5f\x97\x21\xe1\x3a\x03"
> +                         "\x84\x6a\xe9\x76\x11\x1f\xd3\xd5"
> +                         "\xf0\x54\x20\x4d\xc2\x91\xc3\xa4"
> +                         "\x36\x25\xbe\x1b\x2a\x06\xb7\xf3"
> +                         "\xd1\xd0\x55\x29\x81\x4c\x83\xa3"
> +                         "\xa6\x84\x1e\x5c\xd1\xd0\x6c\x90"
> +                         "\xa4\x11\xf0\xd7\x63\x6a\x48\x05"
> +                         "\xbc\x48\x18\x53\xcd\xb0\x8d\xdb"
> +                         "\xdc\xfe\x55\x11\x5c\x51\xb3\xab"
> +                         "\xab\x63\x3e\x31\x5a\x8b\x93\x63"
> +                         "\x34\xa9\xba\x2b\x69\x1a\xc0\xe3"
> +                         "\xcb\x41\xbc\xd7\xf5\x7f\x82\x3e"
> +                         "\x01\xa3\x3c\x72\xf4\xfe\xdf\xbe"
> +                         "\xb1\x67\x17\x2b\x37\x60\x0d\xca"
> +                         "\x6f\xc3\x94\x2c\xd2\x92\x6d\x9d"
> +                         "\x75\x18\x77\xaa\x29\x38\x96\xed"
> +                         "\x0e\x20\x70\x92\xd5\xd0\xb4\x00"
> +                         "\xc0\x31\xf2\xc9\x43\x0e\x75\x1d"
> +                         "\x4b\x64\xf2\x1f\xf2\x29\x6c\x7b"
> +                         "\x7f\xec\x59\x7d\x8c\x0d\xd4\xd3"
> +                         "\xac\x53\x4c\xa3\xde\x42\x92\x95"
> +                         "\x6d\xa3\x4f\xd0\xe6\x3d\xe7\xec"
> +                         "\x7a\x4d\x68\xf1\xfe\x67\x66\x09"
> +                         "\x83\x22\xb1\x98\x43\x8c\xab\xb8"
> +                         "\x45\xe6\x6d\xdf\x5e\x50\x71\xce"
> +                         "\xf5\x4e\x40\x93\x2b\xfa\x86\x0e"
> +                         "\xe8\x30\xbd\x82\xcc\x1c\x9c\x5f"
> +                         "\xad\xfd\x08\x31\xbe\x52\xe7\xe6"
> +                         "\xf2\x06\x01\x62\x25\x15\x99\x74"
> +                         "\x33\x51\x52\x57\x3f\x57\x87\x61"
> +                         "\xb9\x7f\x29\x3d\xcd\x92\x5e\xa6"
> +                         "\x5c\x3b\xf1\xed\x5f\xeb\x82\xed"
> +                         "\x56\x7b\x61\xe7\xfd\x02\x47\x0e"
> +                         "\x2a\x15\xa4\xce\x43\x86\x9b\xe1"
> +                         "\x2b\x4c\x2a\xd9\x42\x97\xf7\x9a"
> +                         "\xe5\x47\x46\x48\xd3\x55\x6f\x4d"
> +                         "\xd9\xeb\x4b\xdd\x7b\x21\x2f\xb3"
> +                         "\xa8\x36\x28\xdf\xca\xf1\xf6\xd9"
> +                         "\x10\xf6\x1c\xfd\x2e\x0c\x27\xe0"
> +                         "\x01\xb3\xff\x6d\x47\x08\x4d\xd4"
> +                         "\x00\x25\xee\x55\x4a\xe9\xe8\x5b"
> +                         "\xd8\xf7\x56\x12\xd4\x50\xb2\xe5"
> +                         "\x51\x6f\x34\x63\x69\xd2\x4e\x96"
> +                         "\x4e\xbc\x79\xbf\x18\xae\xc6\x13"
> +                         "\x80\x92\x77\xb0\xb4\x0f\x29\x94"
> +                         "\x6f\x4c\xbb\x53\x11\x36\xc3\x9f"
> +                         "\x42\x8e\x96\x8a\x91\xc8\xe9\xfc"
> +                         "\xfe\xbf\x7c\x2d\x6f\xf9\xb8\x44"
> +                         "\x89\x1b\x09\x53\x0a\x2a\x92\xc3"
> +                         "\x54\x7a\x3a\xf9\xe2\xe4\x75\x87"
> +                         "\xa0\x5e\x4b\x03\x7a\x0d\x8a\xf4"
> +                         "\x55\x59\x94\x2b\x63\x96\x0e\xf5",
> +               .psize  = 1040,
> +               .digest = "\xb5\xb9\x08\xb3\x24\x3e\x03\xf0"
> +                         "\xd6\x0b\x57\xbc\x0a\x6d\x89\x59",
> +       }, {
> +               .key    = "\xf6\x34\x42\x71\x35\x52\x8b\x58"
> +                         "\x02\x3a\x8e\x4a\x8d\x41\x13\xe9"
> +                         "\x7f\xba\xb9\x55\x9d\x73\x4d\xf8"
> +                         "\x3f\x5d\x73\x15\xff\xd3\x9e\x7f"
> +                         "\x20\x2a\x6a\xa8\xd1\xf0\x8f\x12"
> +                         "\x6b\x02\xd8\x6c\xde\xba\x80\x22"
> +                         "\x19\x37\xc8\xd0\x4e\x89\x17\x7c"
> +                         "\x7c\xdd\x88\xfd\x41\xc0\x04\xb7"
> +                         "\x1d\xac\x19\xe3\x20\xc7\x16\xcf"
> +                         "\x58\xee\x1d\x7a\x61\x69\xa9\x12"
> +                         "\x4b\xef\x4f\xb6\x38\xdd\x78\xf8"
> +                         "\x28\xee\x70\x08\xc7\x7c\xcc\xc8"
> +                         "\x1e\x41\xf5\x80\x86\x70\xd0\xf0"
> +                         "\xa3\x87\x6b\x0a\x00\xd2\x41\x28"
> +                         "\x74\x26\xf1\x24\xf3\xd0\x28\x77"
> +                         "\xd7\xcd\xf6\x2d\x61\xf4\xa2\x13"
> +                         "\x77\xb4\x6f\xa0\xf4\xfb\xd6\xb5"
> +                         "\x38\x9d\x5a\x0c\x51\xaf\xad\x63"
> +                         "\x27\x67\x8c\x01\xea\x42\x1a\x66"
> +                         "\xda\x16\x7c\x3c\x30\x0c\x66\x53"
> +                         "\x1c\x88\xa4\x5c\xb2\xe3\x78\x0a"
> +                         "\x13\x05\x6d\xe2\xaf\xb3\xe4\x75"
> +                         "\x00\x99\x58\xee\x76\x09\x64\xaa"
> +                         "\xbb\x2e\xb1\x81\xec\xd8\x0e\xd3"
> +                         "\x0c\x33\x5d\xb7\x98\xef\x36\xb6"
> +                         "\xd2\x65\x69\x41\x70\x12\xdc\x25"
> +                         "\x41\x03\x99\x81\x41\x19\x62\x13"
> +                         "\xd1\x0a\x29\xc5\x8c\xe0\x4c\xf3"
> +                         "\xd6\xef\x4c\xf4\x1d\x83\x2e\x6d"
> +                         "\x8e\x14\x87\xed\x80\xe0\xaa\xd3"
> +                         "\x08\x04\x73\x1a\x84\x40\xf5\x64"
> +                         "\xbd\x61\x32\x65\x40\x42\xfb\xb0"
> +                         "\x40\xf6\x40\x8d\xc7\x7f\x14\xd0"
> +                         "\x83\x99\xaa\x36\x7e\x60\xc6\xbf"
> +                         "\x13\x8a\xf9\x21\xe4\x7e\x68\x87"
> +                         "\xf3\x33\x86\xb4\xe0\x23\x7e\x0a"
> +                         "\x21\xb1\xf5\xad\x67\x3c\x9c\x9d"
> +                         "\x09\xab\xaf\x5f\xba\xe0\xd0\x82"
> +                         "\x48\x22\x70\xb5\x6d\x53\xd6\x0e"
> +                         "\xde\x64\x92\x41\xb0\xd3\xfb\xda"
> +                         "\x21\xfe\xab\xea\x20\xc4\x03\x58"
> +                         "\x18\x2e\x7d\x2f\x03\xa9\x47\x66"
> +                         "\xdf\x7b\xa4\x6b\x34\x6b\x55\x9c"
> +                         "\x4f\xd7\x9c\x47\xfb\xa9\x42\xec"
> +                         "\x5a\x12\xfd\xfe\x76\xa0\x92\x9d"
> +                         "\xfe\x1e\x16\xdd\x24\x2a\xe4\x27"
> +                         "\xd5\xa9\xf2\x05\x4f\x83\xa2\xaf"
> +                         "\xfe\xee\x83\x7a\xad\xde\xdf\x9a"
> +                         "\x80\xd5\x81\x14\x93\x16\x7e\x46"
> +                         "\x47\xc2\x14\xef\x49\x6e\xb9\xdb"
> +                         "\x40\xe8\x06\x6f\x9c\x2a\xfd\x62"
> +                         "\x06\x46\xfd\x15\x1d\x36\x61\x6f"
> +                         "\x77\x77\x5e\x64\xce\x78\x1b\x85"
> +                         "\xbf\x50\x9a\xfd\x67\xa6\x1a\x65"
> +                         "\xad\x5b\x33\x30\xf1\x71\xaa\xd9"
> +                         "\x23\x0d\x92\x24\x5f\xae\x57\xb0"
> +                         "\x24\x37\x0a\x94\x12\xfb\xb5\xb1"
> +                         "\xd3\xb8\x1d\x12\x29\xb0\x80\x24"
> +                         "\x2d\x47\x9f\x96\x1f\x95\xf1\xb1"
> +                         "\xda\x35\xf6\x29\xe0\xe1\x23\x96"
> +                         "\xc7\xe8\x22\x9b\x7c\xac\xf9\x41"
> +                         "\x39\x01\xe5\x73\x15\x5e\x99\xec"
> +                         "\xb4\xc1\xf4\xe7\xa7\x97\x6a\xd5"
> +                         "\x90\x9a\xa0\x1d\xf3\x5a\x8b\x5f"
> +                         "\xdf\x01\x52\xa4\x93\x31\x97\xb0"
> +                         "\x93\x24\xb5\xbc\xb2\x14\x24\x98"
> +                         "\x4a\x8f\x19\x85\xc3\x2d\x0f\x74"
> +                         "\x9d\x16\x13\x80\x5e\x59\x62\x62"
> +                         "\x25\xe0\xd1\x2f\x64\xef\xba\xac"
> +                         "\xcd\x09\x07\x15\x8a\xcf\x73\xb5"
> +                         "\x8b\xc9\xd8\x24\xb0\x53\xd5\x6f"
> +                         "\xe1\x2b\x77\xb1\xc5\xe4\xa7\x0e"
> +                         "\x18\x45\xab\x36\x03\x59\xa8\xbd"
> +                         "\x43\xf0\xd8\x2c\x1a\x69\x96\xbb"
> +                         "\x13\xdf\x6c\x33\x77\xdf\x25\x34"
> +                         "\x5b\xa5\x5b\x8c\xf9\x51\x05\xd4"
> +                         "\x8b\x8b\x44\x87\x49\xfc\xa0\x8f"
> +                         "\x45\x15\x5b\x40\x42\xc4\x09\x92"
> +                         "\x98\x0c\x4d\xf4\x26\x37\x1b\x13"
> +                         "\x76\x01\x93\x8d\x4f\xe6\xed\x18"
> +                         "\xd0\x79\x7b\x3f\x44\x50\xcb\xee"
> +                         "\xf7\x4a\xc9\x9e\xe0\x96\x74\xa7"
> +                         "\xe6\x93\xb2\x53\xca\x55\xa8\xdc"
> +                         "\x1e\x68\x07\x87\xb7\x2e\xc1\x08"
> +                         "\xb2\xa4\x5b\xaf\xc6\xdb\x5c\x66"
> +                         "\x41\x1c\x51\xd9\xb0\x07\x00\x0d"
> +                         "\xf0\x4c\xdc\x93\xde\xa9\x1e\x8e"
> +                         "\xd3\x22\x62\xd8\x8b\x88\x2c\xea"
> +                         "\x5e\xf1\x6e\x14\x40\xc7\xbe\xaa"
> +                         "\x42\x28\xd0\x26\x30\x78\x01\x9b"
> +                         "\x83\x07\xbc\x94\xc7\x57\xa2\x9f"
> +                         "\x03\x07\xff\x16\xff\x3c\x6e\x48"
> +                         "\x0a\xd0\xdd\x4c\xf6\x64\x9a\xf1"
> +                         "\xcd\x30\x12\x82\x2c\x38\xd3\x26"
> +                         "\x83\xdb\xab\x3e\xc6\xf8\xe6\xfa"
> +                         "\x77\x0a\x78\x82\x75\xf8\x63\x51"
> +                         "\x59\xd0\x8d\x24\x9f\x25\xe6\xa3"
> +                         "\x4c\xbc\x34\xfc\xe3\x10\xc7\x62"
> +                         "\xd4\x23\xc8\x3d\xa7\xc6\xa6\x0a"
> +                         "\x4f\x7e\x29\x9d\x6d\xbe\xb5\xf1"
> +                         "\xdf\xa4\x53\xfa\xc0\x23\x0f\x37"
> +                         "\x84\x68\xd0\xb5\xc8\xc6\xae\xf8"
> +                         "\xb7\x8d\xb3\x16\xfe\x8f\x87\xad"
> +                         "\xd0\xc1\x08\xee\x12\x1c\x9b\x1d"
> +                         "\x90\xf8\xd1\x63\xa4\x92\x3c\xf0"
> +                         "\xc7\x34\xd8\xf1\x14\xed\xa3\xbc"
> +                         "\x17\x7e\xd4\x62\x42\x54\x57\x2c"
> +                         "\x3e\x7a\x35\x35\x17\x0f\x0b\x7f"
> +                         "\x81\xa1\x3f\xd0\xcd\xc8\x3b\x96"
> +                         "\xe9\xe0\x4a\x04\xe1\xb6\x3c\xa1"
> +                         "\xd6\xca\xc4\xbd\xb6\xb5\x95\x34"
> +                         "\x12\x9d\xc5\x96\xf2\xdf\xba\x54"
> +                         "\x76\xd1\xb2\x6b\x3b\x39\xe0\xb9"
> +                         "\x18\x62\xfb\xf7\xfc\x12\xf1\x5f"
> +                         "\x7e\xc7\xe3\x59\x4c\xa6\xc2\x3d"
> +                         "\x40\x15\xf9\xa3\x95\x64\x4c\x74"
> +                         "\x8b\x73\x77\x33\x07\xa7\x04\x1d"
> +                         "\x33\x5a\x7e\x8f\xbd\x86\x01\x4f"
> +                         "\x3e\xb9\x27\x6f\xe2\x41\xf7\x09"
> +                         "\x67\xfd\x29\x28\xc5\xe4\xf6\x18"
> +                         "\x4c\x1b\x49\xb2\x9c\x5b\xf6\x81"
> +                         "\x4f\xbb\x5c\xcc\x0b\xdf\x84\x23"
> +                         "\x58\xd6\x28\x34\x93\x3a\x25\x97"
> +                         "\xdf\xb2\xc3\x9e\x97\x38\x0b\x7d"
> +                         "\x10\xb3\x54\x35\x23\x8c\x64\xee"
> +                         "\xf0\xd8\x66\xff\x8b\x22\xd2\x5b"
> +                         "\x05\x16\x3c\x89\xf7\xb1\x75\xaf"
> +                         "\xc0\xae\x6a\x4f\x3f\xaf\x9a\xf4"
> +                         "\xf4\x9a\x24\xd9\x80\x82\xc0\x12"
> +                         "\xde\x96\xd1\xbe\x15\x0b\x8d\x6a"
> +                         "\xd7\x12\xe4\x85\x9f\x83\xc9\xc3"
> +                         "\xff\x0b\xb5\xaf\x3b\xd8\x6d\x67"
> +                         "\x81\x45\xe6\xac\xec\xc1\x7b\x16"
> +                         "\x18\x0a\xce\x4b\xc0\x2e\x76\xbc"
> +                         "\x1b\xfa\xb4\x34\xb8\xfc\x3e\xc8"
> +                         "\x5d\x90\x71\x6d\x7a\x79\xef\x06",
> +               .ksize  = 1088,
> +               .plaintext      = "\xaa\x5d\x54\xcb\xea\x1e\x46\x0f"
> +                         "\x45\x87\x70\x51\x8a\x66\x7a\x33"
> +                         "\xb4\x18\xff\xa9\x82\xf9\x45\x4b"
> +                         "\x93\xae\x2e\x7f\xab\x98\xfe\xbf"
> +                         "\x01\xee\xe5\xa0\x37\x8f\x57\xa6"
> +                         "\xb0\x76\x0d\xa4\xd6\x28\x2b\x5d"
> +                         "\xe1\x03\xd6\x1c\x6f\x34\x0d\xe7"
> +                         "\x61\x2d\x2e\xe5\xae\x5d\x47\xc7"
> +                         "\x80\x4b\x18\x8f\xa8\x99\xbc\x28"
> +                         "\xed\x1d\x9d\x86\x7d\xd7\x41\xd1"
> +                         "\xe0\x2b\xe1\x8c\x93\x2a\xa7\x80"
> +                         "\xe1\x07\xa0\xa9\x9f\x8c\x8d\x1a"
> +                         "\x55\xfc\x6b\x24\x7a\xbd\x3e\x51"
> +                         "\x68\x4b\x26\x59\xc8\xa7\x16\xd9"
> +                         "\xb9\x61\x13\xde\x8b\x63\x1c\xf6"
> +                         "\x60\x01\xfb\x08\xb3\x5b\x0a\xbf"
> +                         "\x34\x73\xda\x87\x87\x3d\x6f\x97"
> +                         "\x4a\x0c\xa3\x58\x20\xa2\xc0\x81"
> +                         "\x5b\x8c\xef\xa9\xc2\x01\x1e\x64"
> +                         "\x83\x8c\xbc\x03\xb6\xd0\x29\x9f"
> +                         "\x54\xe2\xce\x8b\xc2\x07\x85\x78"
> +                         "\x25\x38\x96\x4c\xb4\xbe\x17\x4a"
> +                         "\x65\xa6\xfa\x52\x9d\x66\x9d\x65"
> +                         "\x4a\xd1\x01\x01\xf0\xcb\x13\xcc"
> +                         "\xa5\x82\xf3\xf2\x66\xcd\x3f\x9d"
> +                         "\xd1\xaa\xe4\x67\xea\xf2\xad\x88"
> +                         "\x56\x76\xa7\x9b\x59\x3c\xb1\x5d"
> +                         "\x78\xfd\x69\x79\x74\x78\x43\x26"
> +                         "\x7b\xde\x3f\xf1\xf5\x4e\x14\xd9"
> +                         "\x15\xf5\x75\xb5\x2e\x19\xf3\x0c"
> +                         "\x48\x72\xd6\x71\x6d\x03\x6e\xaa"
> +                         "\xa7\x08\xf9\xaa\x70\xa3\x0f\x4d"
> +                         "\x12\x8a\xdd\xe3\x39\x73\x7e\xa7"
> +                         "\xea\x1f\x6d\x06\x26\x2a\xf2\xc5"
> +                         "\x52\xb4\xbf\xfd\x52\x0c\x06\x60"
> +                         "\x90\xd1\xb2\x7b\x56\xae\xac\x58"
> +                         "\x5a\x6b\x50\x2a\xf5\xe0\x30\x3c"
> +                         "\x2a\x98\x0f\x1b\x5b\x0a\x84\x6c"
> +                         "\x31\xae\x92\xe2\xd4\xbb\x7f\x59"
> +                         "\x26\x10\xb9\x89\x37\x68\x26\xbf"
> +                         "\x41\xc8\x49\xc4\x70\x35\x7d\xff"
> +                         "\x2d\x7f\xf6\x8a\x93\x68\x8c\x78"
> +                         "\x0d\x53\xce\x7d\xff\x7d\xfb\xae"
> +                         "\x13\x1b\x75\xc4\x78\xd7\x71\xd8"
> +                         "\xea\xd3\xf4\x9d\x95\x64\x8e\xb4"
> +                         "\xde\xb8\xe4\xa6\x68\xc8\xae\x73"
> +                         "\x58\xaf\xa8\xb0\x5a\x20\xde\x87"
> +                         "\x43\xb9\x0f\xe3\xad\x41\x4b\xd5"
> +                         "\xb7\xad\x16\x00\xa6\xff\xf6\x74"
> +                         "\xbf\x8c\x9f\xb3\x58\x1b\xb6\x55"
> +                         "\xa9\x90\x56\x28\xf0\xb5\x13\x4e"
> +                         "\x9e\xf7\x25\x86\xe0\x07\x7b\x98"
> +                         "\xd8\x60\x5d\x38\x95\x3c\xe4\x22"
> +                         "\x16\x2f\xb2\xa2\xaf\xe8\x90\x17"
> +                         "\xec\x11\x83\x1a\xf4\xa9\x26\xda"
> +                         "\x39\x72\xf5\x94\x61\x05\x51\xec"
> +                         "\xa8\x30\x8b\x2c\x13\xd0\x72\xac"
> +                         "\xb9\xd2\xa0\x4c\x4b\x78\xe8\x6e"
> +                         "\x04\x85\xe9\x04\x49\x82\x91\xff"
> +                         "\x89\xe5\xab\x4c\xaa\x37\x03\x12"
> +                         "\xca\x8b\x74\x10\xfd\x9e\xd9\x7b"
> +                         "\xcb\xdb\x82\x6e\xce\x2e\x33\x39"
> +                         "\xce\xd2\x84\x6e\x34\x71\x51\x6e"
> +                         "\x0d\xd6\x01\x87\xc7\xfa\x0a\xd3"
> +                         "\xad\x36\xf3\x4c\x9f\x96\x5e\x62"
> +                         "\x62\x54\xc3\x03\x78\xd6\xab\xdd"
> +                         "\x89\x73\x55\x25\x30\xf8\xa7\xe6"
> +                         "\x4f\x11\x0c\x7c\x0a\xa1\x2b\x7b"
> +                         "\x3d\x0d\xde\x81\xd4\x9d\x0b\xae"
> +                         "\xdf\x00\xf9\x4c\xb6\x90\x8e\x16"
> +                         "\xcb\x11\xc8\xd1\x2e\x73\x13\x75"
> +                         "\x75\x3e\xaa\xf5\xee\x02\xb3\x18"
> +                         "\xa6\x2d\xf5\x3b\x51\xd1\x1f\x47"
> +                         "\x6b\x2c\xdb\xc4\x10\xe0\xc8\xba"
> +                         "\x9d\xac\xb1\x9d\x75\xd5\x41\x0e"
> +                         "\x7e\xbe\x18\x5b\xa4\x1f\xf8\x22"
> +                         "\x4c\xc1\x68\xda\x6d\x51\x34\x6c"
> +                         "\x19\x59\xec\xb5\xb1\xec\xa7\x03"
> +                         "\xca\x54\x99\x63\x05\x6c\xb1\xac"
> +                         "\x9c\x31\xd6\xdb\xba\x7b\x14\x12"
> +                         "\x7a\xc3\x2f\xbf\x8d\xdc\x37\x46"
> +                         "\xdb\xd2\xbc\xd4\x2f\xab\x30\xd5"
> +                         "\xed\x34\x99\x8e\x83\x3e\xbe\x4c"
> +                         "\x86\x79\x58\xe0\x33\x8d\x9a\xb8"
> +                         "\xa9\xa6\x90\x46\xa2\x02\xb8\xdd"
> +                         "\xf5\xf9\x1a\x5c\x8c\x01\xaa\x6e"
> +                         "\xb4\x22\x12\xf5\x0c\x1b\x9b\x7a"
> +                         "\xc3\x80\xf3\x06\x00\x5f\x30\xd5"
> +                         "\x06\xdb\x7d\x82\xc2\xd4\x0b\x4c"
> +                         "\x5f\xe9\xc5\xf5\xdf\x97\x12\xbf"
> +                         "\x56\xaf\x9b\x69\xcd\xee\x30\xb4"
> +                         "\xa8\x71\xff\x3e\x7d\x73\x7a\xb4"
> +                         "\x0d\xa5\x46\x7a\xf3\xf4\x15\x87"
> +                         "\x5d\x93\x2b\x8c\x37\x64\xb5\xdd"
> +                         "\x48\xd1\xe5\x8c\xae\xd4\xf1\x76"
> +                         "\xda\xf4\xba\x9e\x25\x0e\xad\xa3"
> +                         "\x0d\x08\x7c\xa8\x82\x16\x8d\x90"
> +                         "\x56\x40\x16\x84\xe7\x22\x53\x3a"
> +                         "\x58\xbc\xb9\x8f\x33\xc8\xc2\x84"
> +                         "\x22\xe6\x0d\xe7\xb3\xdc\x5d\xdf"
> +                         "\xd7\x2a\x36\xe4\x16\x06\x07\xd2"
> +                         "\x97\x60\xb2\xf5\x5e\x14\xc9\xfd"
> +                         "\x8b\x05\xd1\xce\xee\x9a\x65\x99"
> +                         "\xb7\xae\x19\xb7\xc8\xbc\xd5\xa2"
> +                         "\x7b\x95\xe1\xcc\xba\x0d\xdc\x8a"
> +                         "\x1d\x59\x52\x50\xaa\x16\x02\x82"
> +                         "\xdf\x61\x33\x2e\x44\xce\x49\xc7"
> +                         "\xe5\xc6\x2e\x76\xcf\x80\x52\xf0"
> +                         "\x3d\x17\x34\x47\x3f\xd3\x80\x48"
> +                         "\xa2\xba\xd5\xc7\x7b\x02\x28\xdb"
> +                         "\xac\x44\xc7\x6e\x05\x5c\xc2\x79"
> +                         "\xb3\x7d\x6a\x47\x77\x66\xf1\x38"
> +                         "\xf0\xf5\x4f\x27\x1a\x31\xca\x6c"
> +                         "\x72\x95\x92\x8e\x3f\xb0\xec\x1d"
> +                         "\xc7\x2a\xff\x73\xee\xdf\x55\x80"
> +                         "\x93\xd2\xbd\x34\xd3\x9f\x00\x51"
> +                         "\xfb\x2e\x41\xba\x6c\x5a\x7c\x17"
> +                         "\x7f\xe6\x70\xac\x8d\x39\x3f\x77"
> +                         "\xe2\x23\xac\x8f\x72\x4e\xe4\x53"
> +                         "\xcc\xf1\x1b\xf1\x35\xfe\x52\xa4"
> +                         "\xd6\xb8\x40\x6b\xc1\xfd\xa0\xa1"
> +                         "\xf5\x46\x65\xc2\x50\xbb\x43\xe2"
> +                         "\xd1\x43\x28\x34\x74\xf5\x87\xa0"
> +                         "\xf2\x5e\x27\x3b\x59\x2b\x3e\x49"
> +                         "\xdf\x46\xee\xaf\x71\xd7\x32\x36"
> +                         "\xc7\x14\x0b\x58\x6e\x3e\x2d\x41"
> +                         "\xfa\x75\x66\x3a\x54\xe0\xb2\xb9"
> +                         "\xaf\xdd\x04\x80\x15\x19\x3f\x6f"
> +                         "\xce\x12\xb4\xd8\xe8\x89\x3c\x05"
> +                         "\x30\xeb\xf3\x3d\xcd\x27\xec\xdc"
> +                         "\x56\x70\x12\xcf\x78\x2b\x77\xbf"
> +                         "\x22\xf0\x1b\x17\x9c\xcc\xd6\x1b"
> +                         "\x2d\x3d\xa0\x3b\xd8\xc9\x70\xa4"
> +                         "\x7a\x3e\x07\xb9\x06\xc3\xfa\xb0"
> +                         "\x33\xee\xc1\xd8\xf6\xe0\xf0\xb2"
> +                         "\x61\x12\x69\xb0\x5f\x28\x99\xda"
> +                         "\xc3\x61\x48\xfa\x07\x16\x03\xc4"
> +                         "\xa8\xe1\x3c\xe8\x0e\x64\x15\x30"
> +                         "\xc1\x9d\x84\x2f\x73\x98\x0e\x3a"
> +                         "\xf2\x86\x21\xa4\x9e\x1d\xb5\x86"
> +                         "\x16\xdb\x2b\x9a\x06\x64\x8e\x79"
> +                         "\x8d\x76\x3e\xc3\xc2\x64\x44\xe3"
> +                         "\xda\xbc\x1a\x52\xd7\x61\x03\x65"
> +                         "\x54\x32\x77\x01\xed\x9d\x8a\x43"
> +                         "\x25\x24\xe3\xc1\xbe\xb8\x2f\xcb"
> +                         "\x89\x14\x64\xab\xf6\xa0\x6e\x02"
> +                         "\x57\xe4\x7d\xa9\x4e\x9a\x03\x36"
> +                         "\xad\xf1\xb1\xfc\x0b\xe6\x79\x51"
> +                         "\x9f\x81\x77\xc4\x14\x78\x9d\xbf"
> +                         "\xb6\xd6\xa3\x8c\xba\x0b\x26\xe7"
> +                         "\xc8\xb9\x5c\xcc\xe1\x5f\xd5\xc6"
> +                         "\xc4\xca\xc2\xa3\x45\xba\x94\x13"
> +                         "\xb2\x8f\xc3\x54\x01\x09\xe7\x8b"
> +                         "\xda\x2a\x0a\x11\x02\x43\xcb\x57"
> +                         "\xc9\xcc\xb5\x5c\xab\xc4\xec\x54"
> +                         "\x00\x06\x34\xe1\x6e\x03\x89\x7c"
> +                         "\xc6\xfb\x6a\xc7\x60\x43\xd6\xc5"
> +                         "\xb5\x68\x72\x89\x8f\x42\xc3\x74"
> +                         "\xbd\x25\xaa\x9f\x67\xb5\xdf\x26"
> +                         "\x20\xe8\xb7\x01\x3c\xe4\x77\xce"
> +                         "\xc4\x65\xa7\x23\x79\xea\x33\xc7"
> +                         "\x82\x14\x5c\x82\xf2\x4e\x3d\xf6"
> +                         "\xc6\x4a\x0e\x29\xbb\xec\x44\xcd"
> +                         "\x2f\xd1\x4f\x21\x71\xa9\xce\x0f"
> +                         "\x5c\xf2\x72\x5c\x08\x2e\x21\xd2"
> +                         "\xc3\x29\x13\xd8\xac\xc3\xda\x13"
> +                         "\x1a\x9d\xa7\x71\x1d\x27\x1d\x27"
> +                         "\x1d\xea\xab\x44\x79\xad\xe5\xeb"
> +                         "\xef\x1f\x22\x0a\x44\x4f\xcb\x87"
> +                         "\xa7\x58\x71\x0e\x66\xf8\x60\xbf"
> +                         "\x60\x74\x4a\xb4\xec\x2e\xfe\xd3"
> +                         "\xf5\xb8\xfe\x46\x08\x50\x99\x6c"
> +                         "\x66\xa5\xa8\x34\x44\xb5\xe5\xf0"
> +                         "\xdd\x2c\x67\x4e\x35\x96\x8e\x67"
> +                         "\x48\x3f\x5f\x37\x44\x60\x51\x2e"
> +                         "\x14\x91\x5e\x57\xc3\x0e\x79\x77"
> +                         "\x2f\x03\xf4\xe2\x1c\x72\xbf\x85"
> +                         "\x5d\xd3\x17\xdf\x6c\xc5\x70\x24"
> +                         "\x42\xdf\x51\x4e\x2a\xb2\xd2\x5b"
> +                         "\x9e\x69\x83\x41\x11\xfe\x73\x22"
> +                         "\xde\x8a\x9e\xd8\x8a\xfb\x20\x38"
> +                         "\xd8\x47\x6f\xd5\xed\x8f\x41\xfd"
> +                         "\x13\x7a\x18\x03\x7d\x0f\xcd\x7d"
> +                         "\xa6\x7d\x31\x9e\xf1\x8f\x30\xa3"
> +                         "\x8b\x4c\x24\xb7\xf5\x48\xd7\xd9"
> +                         "\x12\xe7\x84\x97\x5c\x31\x6d\xfb"
> +                         "\xdf\xf3\xd3\xd1\xd5\x0c\x30\x06"
> +                         "\x01\x6a\xbc\x6c\x78\x7b\xa6\x50"
> +                         "\xfa\x0f\x3c\x42\x2d\xa5\xa3\x3b"
> +                         "\xcf\x62\x50\xff\x71\x6d\xe7\xda"
> +                         "\x27\xab\xc6\x67\x16\x65\x68\x64"
> +                         "\xc7\xd5\x5f\x81\xa9\xf6\x65\xb3"
> +                         "\x5e\x43\x91\x16\xcd\x3d\x55\x37"
> +                         "\x55\xb3\xf0\x28\xc5\x54\x19\xc0"
> +                         "\xe0\xd6\x2a\x61\xd4\xc8\x72\x51"
> +                         "\xe9\xa1\x7b\x48\x21\xad\x44\x09"
> +                         "\xe4\x01\x61\x3c\x8a\x5b\xf9\xa1"
> +                         "\x6e\x1b\xdf\xc0\x04\xa8\x8b\xf2"
> +                         "\x21\xbe\x34\x7b\xfc\xa1\xcd\xc9"
> +                         "\xa9\x96\xf4\xa4\x4c\xf7\x4e\x8f"
> +                         "\x84\xcc\xd3\xa8\x92\x77\x8f\x36"
> +                         "\xe2\x2e\x8c\x33\xe8\x84\xa6\x0c"
> +                         "\x6c\x8a\xda\x14\x32\xc2\x96\xff"
> +                         "\xc6\x4a\xc2\x9b\x30\x7f\xd1\x29"
> +                         "\xc0\xd5\x78\x41\x00\x80\x80\x03"
> +                         "\x2a\xb1\xde\x26\x03\x48\x49\xee"
> +                         "\x57\x14\x76\x51\x3c\x36\x5d\x0a"
> +                         "\x5c\x9f\xe8\xd8\x53\xdb\x4f\xd4"
> +                         "\x38\xbf\x66\xc9\x75\x12\x18\x75"
> +                         "\x34\x2d\x93\x22\x96\x51\x24\x6e"
> +                         "\x4e\xd9\x30\xea\x67\xff\x92\x1c"
> +                         "\x16\x26\xe9\xb5\x33\xab\x8c\x22"
> +                         "\x47\xdb\xa0\x2c\x08\xf0\x12\x69"
> +                         "\x7e\x93\x52\xda\xa5\xe5\xca\xc1"
> +                         "\x0f\x55\x2a\xbd\x09\x30\x88\x1b"
> +                         "\x9c\xc6\x9f\xe6\xdb\xa6\x92\xeb"
> +                         "\xf4\xbd\x5c\xc4\xdb\xc6\x71\x09"
> +                         "\xab\x5e\x48\x0c\xed\x6f\xda\x8e"
> +                         "\x8d\x0c\x98\x71\x7d\x10\xd0\x9c"
> +                         "\x20\x9b\x79\x53\x26\x5d\xb9\x85"
> +                         "\x8a\x31\xb8\xc5\x1c\x97\xde\x88"
> +                         "\x61\x55\x7f\x7c\x21\x06\xea\xc4"
> +                         "\x5f\xaf\xf2\xf0\xd5\x5e\x7d\xb4"
> +                         "\x6e\xcf\xe9\xae\x1b\x0e\x11\x80"
> +                         "\xc1\x9a\x74\x7e\x52\x6f\xa0\xb7"
> +                         "\x24\xcd\x8d\x0a\x11\x40\x63\x72"
> +                         "\xfa\xe2\xc5\xb3\x94\xef\x29\xa2"
> +                         "\x1a\x23\x43\x04\x37\x55\x0d\xe9"
> +                         "\x83\xb2\x29\x51\x49\x64\xa0\xbd"
> +                         "\xde\x73\xfd\xa5\x7c\x95\x70\x62"
> +                         "\x58\xdc\xe2\xd0\xbf\x98\xf5\x8a"
> +                         "\x6a\xfd\xce\xa8\x0e\x42\x2a\xeb"
> +                         "\xd2\xff\x83\x27\x53\x5c\xa0\x6e"
> +                         "\x93\xef\xe2\xb9\x5d\x35\xd6\x98"
> +                         "\xf6\x71\x19\x7a\x54\xa1\xa7\xe8"
> +                         "\x09\xfe\xf6\x9e\xc7\xbd\x3e\x29"
> +                         "\xbd\x6b\x17\xf4\xe7\x3e\x10\x5c"
> +                         "\xc1\xd2\x59\x4f\x4b\x12\x1a\x5b"
> +                         "\x50\x80\x59\xb9\xec\x13\x66\xa8"
> +                         "\xd2\x31\x7b\x6a\x61\x22\xdd\x7d"
> +                         "\x61\xee\x87\x16\x46\x9f\xf9\xc7"
> +                         "\x41\xee\x74\xf8\xd0\x96\x2c\x76"
> +                         "\x2a\xac\x7d\x6e\x9f\x0e\x7f\x95"
> +                         "\xfe\x50\x16\xb2\x23\xca\x62\xd5"
> +                         "\x68\xcf\x07\x3f\x3f\x97\x85\x2a"
> +                         "\x0c\x25\x45\xba\xdb\x32\xcb\x83"
> +                         "\x8c\x4f\xe0\x6d\x9a\x99\xf9\xc9"
> +                         "\xda\xd4\x19\x31\xc1\x7c\x6d\xd9"
> +                         "\x9c\x56\xd3\xec\xc1\x81\x4c\xed"
> +                         "\x28\x9d\x87\xeb\x19\xd7\x1a\x4f"
> +                         "\x04\x6a\xcb\x1f\xcf\x1f\xa2\x16"
> +                         "\xfc\x2a\x0d\xa1\x14\x2d\xfa\xc5"
> +                         "\x5a\xd2\xc5\xf9\x19\x7c\x20\x1f"
> +                         "\x2d\x10\xc0\x66\x7c\xd9\x2d\xe5"
> +                         "\x88\x70\x59\xa7\x85\xd5\x2e\x7c"
> +                         "\x5c\xe3\xb7\x12\xd6\x97\x3f\x29",
> +               .psize  = 2048,
> +               .digest = "\x37\x90\x92\xc2\xeb\x01\x87\xd9"
> +                         "\x95\xc7\x91\xc3\x17\x8b\x38\x52",
> +       }
> +};
> +
> +
>  /*
>   * DES test vectors.
>   */
> diff --git a/include/crypto/nhpoly1305.h b/include/crypto/nhpoly1305.h
> new file mode 100644
> index 0000000000000..06bfb876a1563
> --- /dev/null
> +++ b/include/crypto/nhpoly1305.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Common values and helper functions for the NHPoly1305 hash function.
> + */
> +
> +#ifndef _NHPOLY1305_H
> +#define _NHPOLY1305_H
> +
> +#include <crypto/hash.h>
> +#include <crypto/poly1305.h>
> +
> +/* NH parameterization: */
> +
> +/* Endianness: little */
> +/* Word size: 32 bits (works well on NEON, SSE2, AVX2) */
> +
> +/* Stride: 2 words (optimal on ARM32 NEON; works okay on other CPUs too) */
> +#define NH_PAIR_STRIDE         2
> +#define NH_MESSAGE_UNIT                (NH_PAIR_STRIDE * 2 * sizeof(u32))
> +
> +/* Num passes (Toeplitz iteration count): 4, to give ε = 2^{-128} */
> +#define NH_NUM_PASSES          4
> +#define NH_HASH_BYTES          (NH_NUM_PASSES * sizeof(u64))
> +
> +/* Max message size: 1024 bytes (32x compression factor) */
> +#define NH_NUM_STRIDES         64
> +#define NH_MESSAGE_WORDS       (NH_PAIR_STRIDE * 2 * NH_NUM_STRIDES)
> +#define NH_MESSAGE_BYTES       (NH_MESSAGE_WORDS * sizeof(u32))
> +#define NH_KEY_WORDS           (NH_MESSAGE_WORDS + \
> +                                NH_PAIR_STRIDE * 2 * (NH_NUM_PASSES - 1))
> +#define NH_KEY_BYTES           (NH_KEY_WORDS * sizeof(u32))
> +
> +#define NHPOLY1305_KEY_SIZE    (POLY1305_BLOCK_SIZE + NH_KEY_BYTES)
> +
> +struct nhpoly1305_key {
> +       struct poly1305_key poly_key;
> +       u32 nh_key[NH_KEY_WORDS];
> +};
> +
> +struct nhpoly1305_state {
> +
> +       /* Running total of polynomial evaluation */
> +       struct poly1305_state poly_state;
> +
> +       /* Partial block buffer */
> +       u8 buffer[NH_MESSAGE_UNIT];
> +       unsigned int buflen;
> +
> +       /*
> +        * Number of bytes remaining until the current NH message reaches
> +        * NH_MESSAGE_BYTES.  When nonzero, 'nh_hash' holds the partial NH hash.
> +        */
> +       unsigned int nh_remaining;
> +
> +       __le64 nh_hash[NH_NUM_PASSES];
> +};
> +
> +typedef void (*nh_t)(const u32 *key, const u8 *src, size_t srclen,
> +                    __le64 hash[NH_NUM_PASSES]);
> +
> +int crypto_nhpoly1305_setkey(struct crypto_shash *tfm,
> +                            const u8 *key, unsigned int keylen);
> +
> +int crypto_nhpoly1305_init(struct shash_desc *desc);
> +int crypto_nhpoly1305_update(struct shash_desc *desc,
> +                            const u8 *src, unsigned int srclen);
> +int crypto_nhpoly1305_update_helper(struct shash_desc *desc,
> +                                   const u8 *src, unsigned int srclen,
> +                                   nh_t nh_fn);
> +int crypto_nhpoly1305_final(struct shash_desc *desc, u8 *dst);
> +int crypto_nhpoly1305_final_helper(struct shash_desc *desc, u8 *dst,
> +                                  nh_t nh_fn);
> +
> +#endif /* _NHPOLY1305_H */
> --
> 2.19.1.331.ge82ca0e54c-goog
>
Eric Biggers Oct. 20, 2018, 5:38 a.m. UTC | #2
Hi Ard,

On Sat, Oct 20, 2018 at 12:00:31PM +0800, Ard Biesheuvel wrote:
> On 16 October 2018 at 01:54, Eric Biggers <ebiggers@kernel.org> wrote:
> > From: Eric Biggers <ebiggers@google.com>
> >
> > Add a generic implementation of NHPoly1305, an ε-almost-∆-universal hash
> > function used in the Adiantum encryption mode.
> >
> > CONFIG_NHPOLY1305 is not selectable by itself since there won't be any
> > real reason to enable it without also enabling Adiantum support.
> >
> > Signed-off-by: Eric Biggers <ebiggers@google.com>
> > ---
> >  crypto/Kconfig              |    5 +
> >  crypto/Makefile             |    1 +
> >  crypto/nhpoly1305.c         |  288 ++++++++
> >  crypto/testmgr.c            |    6 +
> >  crypto/testmgr.h            | 1240 ++++++++++++++++++++++++++++++++++-
> >  include/crypto/nhpoly1305.h |   74 +++
> >  6 files changed, 1610 insertions(+), 4 deletions(-)
> >  create mode 100644 crypto/nhpoly1305.c
> >  create mode 100644 include/crypto/nhpoly1305.h
> >
> > diff --git a/crypto/Kconfig b/crypto/Kconfig
> > index 4fa0a4a0e8615..431beca903623 100644
> > --- a/crypto/Kconfig
> > +++ b/crypto/Kconfig
> > @@ -493,6 +493,11 @@ config CRYPTO_KEYWRAP
> >           Support for key wrapping (NIST SP800-38F / RFC3394) without
> >           padding.
> >
> > +config CRYPTO_NHPOLY1305
> > +       tristate
> > +       select CRYPTO_HASH
> > +       select CRYPTO_POLY1305
> > +
> >  comment "Hash modes"
> >
> >  config CRYPTO_CMAC
> > diff --git a/crypto/Makefile b/crypto/Makefile
> > index 7e673f7c71107..87b86f221a2a2 100644
> > --- a/crypto/Makefile
> > +++ b/crypto/Makefile
> > @@ -84,6 +84,7 @@ obj-$(CONFIG_CRYPTO_LRW) += lrw.o
> >  obj-$(CONFIG_CRYPTO_XTS) += xts.o
> >  obj-$(CONFIG_CRYPTO_CTR) += ctr.o
> >  obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
> > +obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
> >  obj-$(CONFIG_CRYPTO_GCM) += gcm.o
> >  obj-$(CONFIG_CRYPTO_CCM) += ccm.o
> >  obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
> > diff --git a/crypto/nhpoly1305.c b/crypto/nhpoly1305.c
> > new file mode 100644
> > index 0000000000000..087ad7680dd62
> > --- /dev/null
> > +++ b/crypto/nhpoly1305.c
> > @@ -0,0 +1,288 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * NHPoly1305 - ε-almost-∆-universal hash function for Adiantum
> > + *
> > + * Copyright 2018 Google LLC
> > + */
> > +
> > +/*
> > + * "NHPoly1305" is the main component of Adiantum hashing.
> > + * Specifically, it is the calculation
> > + *
> > + *     H_M ← Poly1305_{K_M}(NH_{K_N}(pad_{128}(M)))
> > + *
> > + * from the procedure in section A.5 of the Adiantum paper [1].  It is an
> > + * ε-almost-∆-universal (εA∆U) hash function for equal-length inputs over
> > + * Z/(2^{128}Z), where the "∆" operation is addition.  It hashes 1024-byte
> > + * chunks of the input with the NH hash function [2], reducing the input length
> > + * by 32x.  The resulting NH digests are evaluated as a polynomial in
> > + * GF(2^{130}-5), like in the Poly1305 MAC [3].  Note that the polynomial
> > + * evaluation by itself would suffice to achieve the εA∆U property; NH is used
> > + * for performance since it's over twice as fast as Poly1305.
> > + *
> > + * This is *not* a cryptographic hash function; do not use it as such!
> > + *
> > + * [1] Adiantum: length-preserving encryption for entry-level processors
> > + *     (https://eprint.iacr.org/2018/720.pdf)
> > + * [2] UMAC: Fast and Secure Message Authentication
> > + *     (https://fastcrypto.org/umac/umac_proc.pdf)
> > + * [3] The Poly1305-AES message-authentication code
> > + *     (https://cr.yp.to/mac/poly1305-20050329.pdf)
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +#include <crypto/algapi.h>
> > +#include <crypto/internal/hash.h>
> > +#include <crypto/nhpoly1305.h>
> > +#include <linux/crypto.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +
> > +#define NH_STRIDE(K0, K1, K2, K3)                              \
> > +({                                                             \
> > +       m_A = get_unaligned_le32(src); src += 4;                \
> > +       m_B = get_unaligned_le32(src); src += 4;                \
> > +       m_C = get_unaligned_le32(src); src += 4;                \
> > +       m_D = get_unaligned_le32(src); src += 4;                \
> > +       K3##_A = *key++;                                        \
> > +       K3##_B = *key++;                                        \
> > +       K3##_C = *key++;                                        \
> > +       K3##_D = *key++;                                        \
> > +       sum0 += (u64)(u32)(m_A + K0##_A) * (u32)(m_C + K0##_C); \
> > +       sum1 += (u64)(u32)(m_A + K1##_A) * (u32)(m_C + K1##_C); \
> > +       sum2 += (u64)(u32)(m_A + K2##_A) * (u32)(m_C + K2##_C); \
> > +       sum3 += (u64)(u32)(m_A + K3##_A) * (u32)(m_C + K3##_C); \
> > +       sum0 += (u64)(u32)(m_B + K0##_B) * (u32)(m_D + K0##_D); \
> > +       sum1 += (u64)(u32)(m_B + K1##_B) * (u32)(m_D + K1##_D); \
> > +       sum2 += (u64)(u32)(m_B + K2##_B) * (u32)(m_D + K2##_D); \
> > +       sum3 += (u64)(u32)(m_B + K3##_B) * (u32)(m_D + K3##_D); \
> > +})
> > +
> > +static void nh_generic(const u32 *key, const u8 *src, size_t srclen,
> > +                      __le64 hash[NH_NUM_PASSES])
> > +{
> > +       u64 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
> > +       u32 k0_A = *key++;
> > +       u32 k0_B = *key++;
> > +       u32 k0_C = *key++;
> > +       u32 k0_D = *key++;
> > +       u32 k1_A = *key++;
> > +       u32 k1_B = *key++;
> > +       u32 k1_C = *key++;
> > +       u32 k1_D = *key++;
> > +       u32 k2_A = *key++;
> > +       u32 k2_B = *key++;
> > +       u32 k2_C = *key++;
> > +       u32 k2_D = *key++;
> > +       u32 k3_A, k3_B, k3_C, k3_D;
> > +       u32 m_A, m_B, m_C, m_D;
> > +       size_t n = srclen / NH_MESSAGE_UNIT;
> > +
> > +       BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
> > +       BUILD_BUG_ON(NH_NUM_PASSES != 4);
> > +
> > +       while (n >= 4) {
> > +               NH_STRIDE(k0, k1, k2, k3);
> > +               NH_STRIDE(k1, k2, k3, k0);
> > +               NH_STRIDE(k2, k3, k0, k1);
> > +               NH_STRIDE(k3, k0, k1, k2);
> > +               n -= 4;
> > +       }
> > +       if (n) {
> > +               NH_STRIDE(k0, k1, k2, k3);
> > +               if (--n) {
> > +                       NH_STRIDE(k1, k2, k3, k0);
> > +                       if (--n)
> > +                               NH_STRIDE(k2, k3, k0, k1);
> > +               }
> > +       }
> > +
> 
> This all looks a bit clunky to me, with the macro, the *key++s in the
> initializers and these conditionals.
> 
> Was it written in this particular way to get GCC to optimize it in the
> right way?

This does get compiled into something much faster than a naive version, which
you can find commented out at
https://github.com/google/adiantum/blob/master/benchmark/src/nh.c#L14.

Though, I admit that I haven't put a ton of effort into this C implementation of
NH yet.  Right now it's actually somewhat of a translation of the NEON version.
I'll do some experiments and see if it can be made into something less ugly
without losing performance.

> 
> > +       hash[0] = cpu_to_le64(sum0);
> > +       hash[1] = cpu_to_le64(sum1);
> > +       hash[2] = cpu_to_le64(sum2);
> > +       hash[3] = cpu_to_le64(sum3);
> > +}
> > +
> > +/* Pass the next NH hash value through Poly1305 */
> > +static void process_nh_hash_value(struct nhpoly1305_state *state,
> > +                                 const struct nhpoly1305_key *key)
> > +{
> > +       BUILD_BUG_ON(NH_HASH_BYTES % POLY1305_BLOCK_SIZE != 0);
> > +
> > +       poly1305_core_blocks(&state->poly_state, &key->poly_key, state->nh_hash,
> > +                            NH_HASH_BYTES / POLY1305_BLOCK_SIZE);
> > +}
> > +
> > +/*
> > + * Feed the next portion of the source data, as a whole number of 16-byte
> > + * "NH message units", through NH and Poly1305.  Each NH hash is taken over
> > + * 1024 bytes, except possibly the final one which is taken over a multiple of
> > + * 16 bytes up to 1024.  Also, in the case where data is passed in misaligned
> > + * chunks, we combine partial hashes; the end result is the same either way.
> > + */
> > +static void nhpoly1305_units(struct nhpoly1305_state *state,
> > +                            const struct nhpoly1305_key *key,
> > +                            const u8 *src, unsigned int srclen, nh_t nh_fn)
> 
> Since indirect calls are going out of style: can we get rid of the
> function pointer? Or is the compiler already inferring that it always
> refers to nh_generic()?
> 

At least for now I want to use the same crypto_nhpoly1305_*_helper() functions
for all nhpoly1305 implementations, and that requires that 'nh' be a function
pointer.  The helpers could be placed in a header and inlined which would turn
'nh' into a direct call, but it seemed to be too much code to inline, and
normally 'nh' is only invoked once per 1024 bytes anyway.

- Eric
Ard Biesheuvel Oct. 20, 2018, 3:06 p.m. UTC | #3
On 20 October 2018 at 13:38, Eric Biggers <ebiggers@kernel.org> wrote:
> Hi Ard,
>
> On Sat, Oct 20, 2018 at 12:00:31PM +0800, Ard Biesheuvel wrote:
>> On 16 October 2018 at 01:54, Eric Biggers <ebiggers@kernel.org> wrote:
>> > From: Eric Biggers <ebiggers@google.com>
>> >
>> > Add a generic implementation of NHPoly1305, an ε-almost-∆-universal hash
>> > function used in the Adiantum encryption mode.
>> >
>> > CONFIG_NHPOLY1305 is not selectable by itself since there won't be any
>> > real reason to enable it without also enabling Adiantum support.
>> >
>> > Signed-off-by: Eric Biggers <ebiggers@google.com>
>> > ---
>> >  crypto/Kconfig              |    5 +
>> >  crypto/Makefile             |    1 +
>> >  crypto/nhpoly1305.c         |  288 ++++++++
>> >  crypto/testmgr.c            |    6 +
>> >  crypto/testmgr.h            | 1240 ++++++++++++++++++++++++++++++++++-
>> >  include/crypto/nhpoly1305.h |   74 +++
>> >  6 files changed, 1610 insertions(+), 4 deletions(-)
>> >  create mode 100644 crypto/nhpoly1305.c
>> >  create mode 100644 include/crypto/nhpoly1305.h
>> >
>> > diff --git a/crypto/Kconfig b/crypto/Kconfig
>> > index 4fa0a4a0e8615..431beca903623 100644
>> > --- a/crypto/Kconfig
>> > +++ b/crypto/Kconfig
>> > @@ -493,6 +493,11 @@ config CRYPTO_KEYWRAP
>> >           Support for key wrapping (NIST SP800-38F / RFC3394) without
>> >           padding.
>> >
>> > +config CRYPTO_NHPOLY1305
>> > +       tristate
>> > +       select CRYPTO_HASH
>> > +       select CRYPTO_POLY1305
>> > +
>> >  comment "Hash modes"
>> >
>> >  config CRYPTO_CMAC
>> > diff --git a/crypto/Makefile b/crypto/Makefile
>> > index 7e673f7c71107..87b86f221a2a2 100644
>> > --- a/crypto/Makefile
>> > +++ b/crypto/Makefile
>> > @@ -84,6 +84,7 @@ obj-$(CONFIG_CRYPTO_LRW) += lrw.o
>> >  obj-$(CONFIG_CRYPTO_XTS) += xts.o
>> >  obj-$(CONFIG_CRYPTO_CTR) += ctr.o
>> >  obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
>> > +obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
>> >  obj-$(CONFIG_CRYPTO_GCM) += gcm.o
>> >  obj-$(CONFIG_CRYPTO_CCM) += ccm.o
>> >  obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
>> > diff --git a/crypto/nhpoly1305.c b/crypto/nhpoly1305.c
>> > new file mode 100644
>> > index 0000000000000..087ad7680dd62
>> > --- /dev/null
>> > +++ b/crypto/nhpoly1305.c
>> > @@ -0,0 +1,288 @@
>> > +// SPDX-License-Identifier: GPL-2.0
>> > +/*
>> > + * NHPoly1305 - ε-almost-∆-universal hash function for Adiantum
>> > + *
>> > + * Copyright 2018 Google LLC
>> > + */
>> > +
>> > +/*
>> > + * "NHPoly1305" is the main component of Adiantum hashing.
>> > + * Specifically, it is the calculation
>> > + *
>> > + *     H_M ← Poly1305_{K_M}(NH_{K_N}(pad_{128}(M)))
>> > + *
>> > + * from the procedure in section A.5 of the Adiantum paper [1].  It is an
>> > + * ε-almost-∆-universal (εA∆U) hash function for equal-length inputs over
>> > + * Z/(2^{128}Z), where the "∆" operation is addition.  It hashes 1024-byte
>> > + * chunks of the input with the NH hash function [2], reducing the input length
>> > + * by 32x.  The resulting NH digests are evaluated as a polynomial in
>> > + * GF(2^{130}-5), like in the Poly1305 MAC [3].  Note that the polynomial
>> > + * evaluation by itself would suffice to achieve the εA∆U property; NH is used
>> > + * for performance since it's over twice as fast as Poly1305.
>> > + *
>> > + * This is *not* a cryptographic hash function; do not use it as such!
>> > + *
>> > + * [1] Adiantum: length-preserving encryption for entry-level processors
>> > + *     (https://eprint.iacr.org/2018/720.pdf)
>> > + * [2] UMAC: Fast and Secure Message Authentication
>> > + *     (https://fastcrypto.org/umac/umac_proc.pdf)
>> > + * [3] The Poly1305-AES message-authentication code
>> > + *     (https://cr.yp.to/mac/poly1305-20050329.pdf)
>> > + */
>> > +
>> > +#include <asm/unaligned.h>
>> > +#include <crypto/algapi.h>
>> > +#include <crypto/internal/hash.h>
>> > +#include <crypto/nhpoly1305.h>
>> > +#include <linux/crypto.h>
>> > +#include <linux/kernel.h>
>> > +#include <linux/module.h>
>> > +
>> > +#define NH_STRIDE(K0, K1, K2, K3)                              \
>> > +({                                                             \
>> > +       m_A = get_unaligned_le32(src); src += 4;                \
>> > +       m_B = get_unaligned_le32(src); src += 4;                \
>> > +       m_C = get_unaligned_le32(src); src += 4;                \
>> > +       m_D = get_unaligned_le32(src); src += 4;                \
>> > +       K3##_A = *key++;                                        \
>> > +       K3##_B = *key++;                                        \
>> > +       K3##_C = *key++;                                        \
>> > +       K3##_D = *key++;                                        \
>> > +       sum0 += (u64)(u32)(m_A + K0##_A) * (u32)(m_C + K0##_C); \
>> > +       sum1 += (u64)(u32)(m_A + K1##_A) * (u32)(m_C + K1##_C); \
>> > +       sum2 += (u64)(u32)(m_A + K2##_A) * (u32)(m_C + K2##_C); \
>> > +       sum3 += (u64)(u32)(m_A + K3##_A) * (u32)(m_C + K3##_C); \
>> > +       sum0 += (u64)(u32)(m_B + K0##_B) * (u32)(m_D + K0##_D); \
>> > +       sum1 += (u64)(u32)(m_B + K1##_B) * (u32)(m_D + K1##_D); \
>> > +       sum2 += (u64)(u32)(m_B + K2##_B) * (u32)(m_D + K2##_D); \
>> > +       sum3 += (u64)(u32)(m_B + K3##_B) * (u32)(m_D + K3##_D); \
>> > +})
>> > +
>> > +static void nh_generic(const u32 *key, const u8 *src, size_t srclen,
>> > +                      __le64 hash[NH_NUM_PASSES])
>> > +{
>> > +       u64 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
>> > +       u32 k0_A = *key++;
>> > +       u32 k0_B = *key++;
>> > +       u32 k0_C = *key++;
>> > +       u32 k0_D = *key++;
>> > +       u32 k1_A = *key++;
>> > +       u32 k1_B = *key++;
>> > +       u32 k1_C = *key++;
>> > +       u32 k1_D = *key++;
>> > +       u32 k2_A = *key++;
>> > +       u32 k2_B = *key++;
>> > +       u32 k2_C = *key++;
>> > +       u32 k2_D = *key++;
>> > +       u32 k3_A, k3_B, k3_C, k3_D;
>> > +       u32 m_A, m_B, m_C, m_D;
>> > +       size_t n = srclen / NH_MESSAGE_UNIT;
>> > +
>> > +       BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
>> > +       BUILD_BUG_ON(NH_NUM_PASSES != 4);
>> > +
>> > +       while (n >= 4) {
>> > +               NH_STRIDE(k0, k1, k2, k3);
>> > +               NH_STRIDE(k1, k2, k3, k0);
>> > +               NH_STRIDE(k2, k3, k0, k1);
>> > +               NH_STRIDE(k3, k0, k1, k2);
>> > +               n -= 4;
>> > +       }
>> > +       if (n) {
>> > +               NH_STRIDE(k0, k1, k2, k3);
>> > +               if (--n) {
>> > +                       NH_STRIDE(k1, k2, k3, k0);
>> > +                       if (--n)
>> > +                               NH_STRIDE(k2, k3, k0, k1);
>> > +               }
>> > +       }
>> > +
>>
>> This all looks a bit clunky to me, with the macro, the *key++s in the
>> initializers and these conditionals.
>>
>> Was it written in this particular way to get GCC to optimize it in the
>> right way?
>
> This does get compiled into something much faster than a naive version, which
> you can find commented out at
> https://github.com/google/adiantum/blob/master/benchmark/src/nh.c#L14.
>
> Though, I admit that I haven't put a ton of effort into this C implementation of
> NH yet.  Right now it's actually somewhat of a translation of the NEON version.
> I'll do some experiments and see if it can be made into something less ugly
> without losing performance.
>

No that's fine but please document it.

>>
>> > +       hash[0] = cpu_to_le64(sum0);
>> > +       hash[1] = cpu_to_le64(sum1);
>> > +       hash[2] = cpu_to_le64(sum2);
>> > +       hash[3] = cpu_to_le64(sum3);
>> > +}
>> > +
>> > +/* Pass the next NH hash value through Poly1305 */
>> > +static void process_nh_hash_value(struct nhpoly1305_state *state,
>> > +                                 const struct nhpoly1305_key *key)
>> > +{
>> > +       BUILD_BUG_ON(NH_HASH_BYTES % POLY1305_BLOCK_SIZE != 0);
>> > +
>> > +       poly1305_core_blocks(&state->poly_state, &key->poly_key, state->nh_hash,
>> > +                            NH_HASH_BYTES / POLY1305_BLOCK_SIZE);
>> > +}
>> > +
>> > +/*
>> > + * Feed the next portion of the source data, as a whole number of 16-byte
>> > + * "NH message units", through NH and Poly1305.  Each NH hash is taken over
>> > + * 1024 bytes, except possibly the final one which is taken over a multiple of
>> > + * 16 bytes up to 1024.  Also, in the case where data is passed in misaligned
>> > + * chunks, we combine partial hashes; the end result is the same either way.
>> > + */
>> > +static void nhpoly1305_units(struct nhpoly1305_state *state,
>> > +                            const struct nhpoly1305_key *key,
>> > +                            const u8 *src, unsigned int srclen, nh_t nh_fn)
>>
>> Since indirect calls are going out of style: can we get rid of the
>> function pointer? Or is the compiler already inferring that it always
>> refers to nh_generic()?
>>
>
> At least for now I want to use the same crypto_nhpoly1305_*_helper() functions
> for all nhpoly1305 implementations, and that requires that 'nh' be a function
> pointer.  The helpers could be placed in a header and inlined which would turn
> 'nh' into a direct call, but it seemed to be too much code to inline, and
> normally 'nh' is only invoked once per 1024 bytes anyway.
>

OK.
Eric Biggers Oct. 22, 2018, 6:42 p.m. UTC | #4
On Sat, Oct 20, 2018 at 11:06:00PM +0800, Ard Biesheuvel wrote:
> >> > +
> >> > +#define NH_STRIDE(K0, K1, K2, K3)                              \
> >> > +({                                                             \
> >> > +       m_A = get_unaligned_le32(src); src += 4;                \
> >> > +       m_B = get_unaligned_le32(src); src += 4;                \
> >> > +       m_C = get_unaligned_le32(src); src += 4;                \
> >> > +       m_D = get_unaligned_le32(src); src += 4;                \
> >> > +       K3##_A = *key++;                                        \
> >> > +       K3##_B = *key++;                                        \
> >> > +       K3##_C = *key++;                                        \
> >> > +       K3##_D = *key++;                                        \
> >> > +       sum0 += (u64)(u32)(m_A + K0##_A) * (u32)(m_C + K0##_C); \
> >> > +       sum1 += (u64)(u32)(m_A + K1##_A) * (u32)(m_C + K1##_C); \
> >> > +       sum2 += (u64)(u32)(m_A + K2##_A) * (u32)(m_C + K2##_C); \
> >> > +       sum3 += (u64)(u32)(m_A + K3##_A) * (u32)(m_C + K3##_C); \
> >> > +       sum0 += (u64)(u32)(m_B + K0##_B) * (u32)(m_D + K0##_D); \
> >> > +       sum1 += (u64)(u32)(m_B + K1##_B) * (u32)(m_D + K1##_D); \
> >> > +       sum2 += (u64)(u32)(m_B + K2##_B) * (u32)(m_D + K2##_D); \
> >> > +       sum3 += (u64)(u32)(m_B + K3##_B) * (u32)(m_D + K3##_D); \
> >> > +})
> >> > +
> >> > +static void nh_generic(const u32 *key, const u8 *src, size_t srclen,
> >> > +                      __le64 hash[NH_NUM_PASSES])
> >> > +{
> >> > +       u64 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
> >> > +       u32 k0_A = *key++;
> >> > +       u32 k0_B = *key++;
> >> > +       u32 k0_C = *key++;
> >> > +       u32 k0_D = *key++;
> >> > +       u32 k1_A = *key++;
> >> > +       u32 k1_B = *key++;
> >> > +       u32 k1_C = *key++;
> >> > +       u32 k1_D = *key++;
> >> > +       u32 k2_A = *key++;
> >> > +       u32 k2_B = *key++;
> >> > +       u32 k2_C = *key++;
> >> > +       u32 k2_D = *key++;
> >> > +       u32 k3_A, k3_B, k3_C, k3_D;
> >> > +       u32 m_A, m_B, m_C, m_D;
> >> > +       size_t n = srclen / NH_MESSAGE_UNIT;
> >> > +
> >> > +       BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
> >> > +       BUILD_BUG_ON(NH_NUM_PASSES != 4);
> >> > +
> >> > +       while (n >= 4) {
> >> > +               NH_STRIDE(k0, k1, k2, k3);
> >> > +               NH_STRIDE(k1, k2, k3, k0);
> >> > +               NH_STRIDE(k2, k3, k0, k1);
> >> > +               NH_STRIDE(k3, k0, k1, k2);
> >> > +               n -= 4;
> >> > +       }
> >> > +       if (n) {
> >> > +               NH_STRIDE(k0, k1, k2, k3);
> >> > +               if (--n) {
> >> > +                       NH_STRIDE(k1, k2, k3, k0);
> >> > +                       if (--n)
> >> > +                               NH_STRIDE(k2, k3, k0, k1);
> >> > +               }
> >> > +       }
> >> > +
> >>
> >> This all looks a bit clunky to me, with the macro, the *key++s in the
> >> initializers and these conditionals.
> >>
> >> Was it written in this particular way to get GCC to optimize it in the
> >> right way?
> >
> > This does get compiled into something much faster than a naive version, which
> > you can find commented out at
> > https://github.com/google/adiantum/blob/master/benchmark/src/nh.c#L14.
> >
> > Though, I admit that I haven't put a ton of effort into this C implementation of
> > NH yet.  Right now it's actually somewhat of a translation of the NEON version.
> > I'll do some experiments and see if it can be made into something less ugly
> > without losing performance.
> >
> 
> No that's fine but please document it.
> 

Hmm, I'm actually leaning towards the following instead.  Unrolling multiple
strides to try to reduce loads of the keys doesn't seem worthwhile in the C
implementation; for one, it bloats the code size a lot
(412 => 2332 bytes on arm32).

static void nh_generic(const u32 *key, const u8 *message, size_t message_len,
		       __le64 hash[NH_NUM_PASSES])
{
	u64 sums[4] = { 0, 0, 0, 0 };

	BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
	BUILD_BUG_ON(NH_NUM_PASSES != 4);

	while (message_len) {
		u32 m0 = get_unaligned_le32(message + 0);
		u32 m1 = get_unaligned_le32(message + 4);
		u32 m2 = get_unaligned_le32(message + 8);
		u32 m3 = get_unaligned_le32(message + 12);

		sums[0] += (u64)(u32)(m0 + key[ 0]) * (u32)(m2 + key[ 2]);
		sums[1] += (u64)(u32)(m0 + key[ 4]) * (u32)(m2 + key[ 6]);
		sums[2] += (u64)(u32)(m0 + key[ 8]) * (u32)(m2 + key[10]);
		sums[3] += (u64)(u32)(m0 + key[12]) * (u32)(m2 + key[14]);
		sums[0] += (u64)(u32)(m1 + key[ 1]) * (u32)(m3 + key[ 3]);
		sums[1] += (u64)(u32)(m1 + key[ 5]) * (u32)(m3 + key[ 7]);
		sums[2] += (u64)(u32)(m1 + key[ 9]) * (u32)(m3 + key[11]);
		sums[3] += (u64)(u32)(m1 + key[13]) * (u32)(m3 + key[15]);
		key += NH_MESSAGE_UNIT / sizeof(key[0]);
		message += NH_MESSAGE_UNIT;
		message_len -= NH_MESSAGE_UNIT;
	}

	hash[0] = cpu_to_le64(sums[0]);
	hash[1] = cpu_to_le64(sums[1]);
	hash[2] = cpu_to_le64(sums[2]);
	hash[3] = cpu_to_le64(sums[3]);
}
Ard Biesheuvel Oct. 22, 2018, 10:25 p.m. UTC | #5
On 22 October 2018 at 15:42, Eric Biggers <ebiggers@kernel.org> wrote:
> On Sat, Oct 20, 2018 at 11:06:00PM +0800, Ard Biesheuvel wrote:
>> >> > +
>> >> > +#define NH_STRIDE(K0, K1, K2, K3)                              \
>> >> > +({                                                             \
>> >> > +       m_A = get_unaligned_le32(src); src += 4;                \
>> >> > +       m_B = get_unaligned_le32(src); src += 4;                \
>> >> > +       m_C = get_unaligned_le32(src); src += 4;                \
>> >> > +       m_D = get_unaligned_le32(src); src += 4;                \
>> >> > +       K3##_A = *key++;                                        \
>> >> > +       K3##_B = *key++;                                        \
>> >> > +       K3##_C = *key++;                                        \
>> >> > +       K3##_D = *key++;                                        \
>> >> > +       sum0 += (u64)(u32)(m_A + K0##_A) * (u32)(m_C + K0##_C); \
>> >> > +       sum1 += (u64)(u32)(m_A + K1##_A) * (u32)(m_C + K1##_C); \
>> >> > +       sum2 += (u64)(u32)(m_A + K2##_A) * (u32)(m_C + K2##_C); \
>> >> > +       sum3 += (u64)(u32)(m_A + K3##_A) * (u32)(m_C + K3##_C); \
>> >> > +       sum0 += (u64)(u32)(m_B + K0##_B) * (u32)(m_D + K0##_D); \
>> >> > +       sum1 += (u64)(u32)(m_B + K1##_B) * (u32)(m_D + K1##_D); \
>> >> > +       sum2 += (u64)(u32)(m_B + K2##_B) * (u32)(m_D + K2##_D); \
>> >> > +       sum3 += (u64)(u32)(m_B + K3##_B) * (u32)(m_D + K3##_D); \
>> >> > +})
>> >> > +
>> >> > +static void nh_generic(const u32 *key, const u8 *src, size_t srclen,
>> >> > +                      __le64 hash[NH_NUM_PASSES])
>> >> > +{
>> >> > +       u64 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
>> >> > +       u32 k0_A = *key++;
>> >> > +       u32 k0_B = *key++;
>> >> > +       u32 k0_C = *key++;
>> >> > +       u32 k0_D = *key++;
>> >> > +       u32 k1_A = *key++;
>> >> > +       u32 k1_B = *key++;
>> >> > +       u32 k1_C = *key++;
>> >> > +       u32 k1_D = *key++;
>> >> > +       u32 k2_A = *key++;
>> >> > +       u32 k2_B = *key++;
>> >> > +       u32 k2_C = *key++;
>> >> > +       u32 k2_D = *key++;
>> >> > +       u32 k3_A, k3_B, k3_C, k3_D;
>> >> > +       u32 m_A, m_B, m_C, m_D;
>> >> > +       size_t n = srclen / NH_MESSAGE_UNIT;
>> >> > +
>> >> > +       BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
>> >> > +       BUILD_BUG_ON(NH_NUM_PASSES != 4);
>> >> > +
>> >> > +       while (n >= 4) {
>> >> > +               NH_STRIDE(k0, k1, k2, k3);
>> >> > +               NH_STRIDE(k1, k2, k3, k0);
>> >> > +               NH_STRIDE(k2, k3, k0, k1);
>> >> > +               NH_STRIDE(k3, k0, k1, k2);
>> >> > +               n -= 4;
>> >> > +       }
>> >> > +       if (n) {
>> >> > +               NH_STRIDE(k0, k1, k2, k3);
>> >> > +               if (--n) {
>> >> > +                       NH_STRIDE(k1, k2, k3, k0);
>> >> > +                       if (--n)
>> >> > +                               NH_STRIDE(k2, k3, k0, k1);
>> >> > +               }
>> >> > +       }
>> >> > +
>> >>
>> >> This all looks a bit clunky to me, with the macro, the *key++s in the
>> >> initializers and these conditionals.
>> >>
>> >> Was it written in this particular way to get GCC to optimize it in the
>> >> right way?
>> >
>> > This does get compiled into something much faster than a naive version, which
>> > you can find commented out at
>> > https://github.com/google/adiantum/blob/master/benchmark/src/nh.c#L14.
>> >
>> > Though, I admit that I haven't put a ton of effort into this C implementation of
>> > NH yet.  Right now it's actually somewhat of a translation of the NEON version.
>> > I'll do some experiments and see if it can be made into something less ugly
>> > without losing performance.
>> >
>>
>> No that's fine but please document it.
>>
>
> Hmm, I'm actually leaning towards the following instead.  Unrolling multiple
> strides to try to reduce loads of the keys doesn't seem worthwhile in the C
> implementation; for one, it bloats the code size a lot
> (412 => 2332 bytes on arm32).
>
> static void nh_generic(const u32 *key, const u8 *message, size_t message_len,
>                        __le64 hash[NH_NUM_PASSES])
> {
>         u64 sums[4] = { 0, 0, 0, 0 };
>
>         BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
>         BUILD_BUG_ON(NH_NUM_PASSES != 4);
>
>         while (message_len) {
>                 u32 m0 = get_unaligned_le32(message + 0);
>                 u32 m1 = get_unaligned_le32(message + 4);
>                 u32 m2 = get_unaligned_le32(message + 8);
>                 u32 m3 = get_unaligned_le32(message + 12);
>
>                 sums[0] += (u64)(u32)(m0 + key[ 0]) * (u32)(m2 + key[ 2]);
>                 sums[1] += (u64)(u32)(m0 + key[ 4]) * (u32)(m2 + key[ 6]);
>                 sums[2] += (u64)(u32)(m0 + key[ 8]) * (u32)(m2 + key[10]);
>                 sums[3] += (u64)(u32)(m0 + key[12]) * (u32)(m2 + key[14]);
>                 sums[0] += (u64)(u32)(m1 + key[ 1]) * (u32)(m3 + key[ 3]);
>                 sums[1] += (u64)(u32)(m1 + key[ 5]) * (u32)(m3 + key[ 7]);
>                 sums[2] += (u64)(u32)(m1 + key[ 9]) * (u32)(m3 + key[11]);
>                 sums[3] += (u64)(u32)(m1 + key[13]) * (u32)(m3 + key[15]);

Are these (u32) casts really necessary? All the addends are u32 types,
so I'd expect each (x + y) subexpression to have a u32 type already as
well. Or am I missing something?

>                 key += NH_MESSAGE_UNIT / sizeof(key[0]);
>                 message += NH_MESSAGE_UNIT;
>                 message_len -= NH_MESSAGE_UNIT;
>         }
>
>         hash[0] = cpu_to_le64(sums[0]);
>         hash[1] = cpu_to_le64(sums[1]);
>         hash[2] = cpu_to_le64(sums[2]);
>         hash[3] = cpu_to_le64(sums[3]);
> }

In any case, this looks much better to me, so if the performance is
satisfactory, let's use this version.
Eric Biggers Oct. 22, 2018, 10:40 p.m. UTC | #6
Hi Ard,

On Mon, Oct 22, 2018 at 07:25:27PM -0300, Ard Biesheuvel wrote:
> >
> > Hmm, I'm actually leaning towards the following instead.  Unrolling multiple
> > strides to try to reduce loads of the keys doesn't seem worthwhile in the C
> > implementation; for one, it bloats the code size a lot
> > (412 => 2332 bytes on arm32).
> >
> > static void nh_generic(const u32 *key, const u8 *message, size_t message_len,
> >                        __le64 hash[NH_NUM_PASSES])
> > {
> >         u64 sums[4] = { 0, 0, 0, 0 };
> >
> >         BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
> >         BUILD_BUG_ON(NH_NUM_PASSES != 4);
> >
> >         while (message_len) {
> >                 u32 m0 = get_unaligned_le32(message + 0);
> >                 u32 m1 = get_unaligned_le32(message + 4);
> >                 u32 m2 = get_unaligned_le32(message + 8);
> >                 u32 m3 = get_unaligned_le32(message + 12);
> >
> >                 sums[0] += (u64)(u32)(m0 + key[ 0]) * (u32)(m2 + key[ 2]);
> >                 sums[1] += (u64)(u32)(m0 + key[ 4]) * (u32)(m2 + key[ 6]);
> >                 sums[2] += (u64)(u32)(m0 + key[ 8]) * (u32)(m2 + key[10]);
> >                 sums[3] += (u64)(u32)(m0 + key[12]) * (u32)(m2 + key[14]);
> >                 sums[0] += (u64)(u32)(m1 + key[ 1]) * (u32)(m3 + key[ 3]);
> >                 sums[1] += (u64)(u32)(m1 + key[ 5]) * (u32)(m3 + key[ 7]);
> >                 sums[2] += (u64)(u32)(m1 + key[ 9]) * (u32)(m3 + key[11]);
> >                 sums[3] += (u64)(u32)(m1 + key[13]) * (u32)(m3 + key[15]);
> 
> Are these (u32) casts really necessary? All the addends are u32 types,
> so I'd expect each (x + y) subexpression to have a u32 type already as
> well. Or am I missing something?
> 

The (u32) casts are only necessary when sizeof(int) > sizeof(u32), as then the
addends will be promoted to 'int'.  Of course, that's never the case for the
Linux kernel.  But I prefer it to be as robust and well-defined as possible,
since people might use this as a reference when coding other implementations,
which could end up finding their way into unusual and/or future platforms.

- Eric
Ard Biesheuvel Oct. 22, 2018, 10:43 p.m. UTC | #7
On 22 October 2018 at 19:40, Eric Biggers <ebiggers@kernel.org> wrote:
> Hi Ard,
>
> On Mon, Oct 22, 2018 at 07:25:27PM -0300, Ard Biesheuvel wrote:
>> >
>> > Hmm, I'm actually leaning towards the following instead.  Unrolling multiple
>> > strides to try to reduce loads of the keys doesn't seem worthwhile in the C
>> > implementation; for one, it bloats the code size a lot
>> > (412 => 2332 bytes on arm32).
>> >
>> > static void nh_generic(const u32 *key, const u8 *message, size_t message_len,
>> >                        __le64 hash[NH_NUM_PASSES])
>> > {
>> >         u64 sums[4] = { 0, 0, 0, 0 };
>> >
>> >         BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
>> >         BUILD_BUG_ON(NH_NUM_PASSES != 4);
>> >
>> >         while (message_len) {
>> >                 u32 m0 = get_unaligned_le32(message + 0);
>> >                 u32 m1 = get_unaligned_le32(message + 4);
>> >                 u32 m2 = get_unaligned_le32(message + 8);
>> >                 u32 m3 = get_unaligned_le32(message + 12);
>> >
>> >                 sums[0] += (u64)(u32)(m0 + key[ 0]) * (u32)(m2 + key[ 2]);
>> >                 sums[1] += (u64)(u32)(m0 + key[ 4]) * (u32)(m2 + key[ 6]);
>> >                 sums[2] += (u64)(u32)(m0 + key[ 8]) * (u32)(m2 + key[10]);
>> >                 sums[3] += (u64)(u32)(m0 + key[12]) * (u32)(m2 + key[14]);
>> >                 sums[0] += (u64)(u32)(m1 + key[ 1]) * (u32)(m3 + key[ 3]);
>> >                 sums[1] += (u64)(u32)(m1 + key[ 5]) * (u32)(m3 + key[ 7]);
>> >                 sums[2] += (u64)(u32)(m1 + key[ 9]) * (u32)(m3 + key[11]);
>> >                 sums[3] += (u64)(u32)(m1 + key[13]) * (u32)(m3 + key[15]);
>>
>> Are these (u32) casts really necessary? All the addends are u32 types,
>> so I'd expect each (x + y) subexpression to have a u32 type already as
>> well. Or am I missing something?
>>
>
> The (u32) casts are only necessary when sizeof(int) > sizeof(u32), as then the
> addends will be promoted to 'int'.  Of course, that's never the case for the
> Linux kernel.  But I prefer it to be as robust and well-defined as possible,
> since people might use this as a reference when coding other implementations,
> which could end up finding their way into unusual and/or future platforms.
>

Fair enough.
diff mbox series

Patch

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4fa0a4a0e8615..431beca903623 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -493,6 +493,11 @@  config CRYPTO_KEYWRAP
 	  Support for key wrapping (NIST SP800-38F / RFC3394) without
 	  padding.
 
+config CRYPTO_NHPOLY1305
+	tristate
+	select CRYPTO_HASH
+	select CRYPTO_POLY1305
+
 comment "Hash modes"
 
 config CRYPTO_CMAC
diff --git a/crypto/Makefile b/crypto/Makefile
index 7e673f7c71107..87b86f221a2a2 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -84,6 +84,7 @@  obj-$(CONFIG_CRYPTO_LRW) += lrw.o
 obj-$(CONFIG_CRYPTO_XTS) += xts.o
 obj-$(CONFIG_CRYPTO_CTR) += ctr.o
 obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
+obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
 obj-$(CONFIG_CRYPTO_GCM) += gcm.o
 obj-$(CONFIG_CRYPTO_CCM) += ccm.o
 obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
diff --git a/crypto/nhpoly1305.c b/crypto/nhpoly1305.c
new file mode 100644
index 0000000000000..087ad7680dd62
--- /dev/null
+++ b/crypto/nhpoly1305.c
@@ -0,0 +1,288 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NHPoly1305 - ε-almost-∆-universal hash function for Adiantum
+ *
+ * Copyright 2018 Google LLC
+ */
+
+/*
+ * "NHPoly1305" is the main component of Adiantum hashing.
+ * Specifically, it is the calculation
+ *
+ *	H_M ← Poly1305_{K_M}(NH_{K_N}(pad_{128}(M)))
+ *
+ * from the procedure in section A.5 of the Adiantum paper [1].  It is an
+ * ε-almost-∆-universal (εA∆U) hash function for equal-length inputs over
+ * Z/(2^{128}Z), where the "∆" operation is addition.  It hashes 1024-byte
+ * chunks of the input with the NH hash function [2], reducing the input length
+ * by 32x.  The resulting NH digests are evaluated as a polynomial in
+ * GF(2^{130}-5), like in the Poly1305 MAC [3].  Note that the polynomial
+ * evaluation by itself would suffice to achieve the εA∆U property; NH is used
+ * for performance since it's over twice as fast as Poly1305.
+ *
+ * This is *not* a cryptographic hash function; do not use it as such!
+ *
+ * [1] Adiantum: length-preserving encryption for entry-level processors
+ *     (https://eprint.iacr.org/2018/720.pdf)
+ * [2] UMAC: Fast and Secure Message Authentication
+ *     (https://fastcrypto.org/umac/umac_proc.pdf)
+ * [3] The Poly1305-AES message-authentication code
+ *     (https://cr.yp.to/mac/poly1305-20050329.pdf)
+ */
+
+#include <asm/unaligned.h>
+#include <crypto/algapi.h>
+#include <crypto/internal/hash.h>
+#include <crypto/nhpoly1305.h>
+#include <linux/crypto.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#define NH_STRIDE(K0, K1, K2, K3)				\
+({								\
+	m_A = get_unaligned_le32(src); src += 4;		\
+	m_B = get_unaligned_le32(src); src += 4;		\
+	m_C = get_unaligned_le32(src); src += 4;		\
+	m_D = get_unaligned_le32(src); src += 4;		\
+	K3##_A = *key++;					\
+	K3##_B = *key++;					\
+	K3##_C = *key++;					\
+	K3##_D = *key++;					\
+	sum0 += (u64)(u32)(m_A + K0##_A) * (u32)(m_C + K0##_C);	\
+	sum1 += (u64)(u32)(m_A + K1##_A) * (u32)(m_C + K1##_C);	\
+	sum2 += (u64)(u32)(m_A + K2##_A) * (u32)(m_C + K2##_C);	\
+	sum3 += (u64)(u32)(m_A + K3##_A) * (u32)(m_C + K3##_C);	\
+	sum0 += (u64)(u32)(m_B + K0##_B) * (u32)(m_D + K0##_D);	\
+	sum1 += (u64)(u32)(m_B + K1##_B) * (u32)(m_D + K1##_D);	\
+	sum2 += (u64)(u32)(m_B + K2##_B) * (u32)(m_D + K2##_D);	\
+	sum3 += (u64)(u32)(m_B + K3##_B) * (u32)(m_D + K3##_D);	\
+})
+
+static void nh_generic(const u32 *key, const u8 *src, size_t srclen,
+		       __le64 hash[NH_NUM_PASSES])
+{
+	u64 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
+	u32 k0_A = *key++;
+	u32 k0_B = *key++;
+	u32 k0_C = *key++;
+	u32 k0_D = *key++;
+	u32 k1_A = *key++;
+	u32 k1_B = *key++;
+	u32 k1_C = *key++;
+	u32 k1_D = *key++;
+	u32 k2_A = *key++;
+	u32 k2_B = *key++;
+	u32 k2_C = *key++;
+	u32 k2_D = *key++;
+	u32 k3_A, k3_B, k3_C, k3_D;
+	u32 m_A, m_B, m_C, m_D;
+	size_t n = srclen / NH_MESSAGE_UNIT;
+
+	BUILD_BUG_ON(NH_PAIR_STRIDE != 2);
+	BUILD_BUG_ON(NH_NUM_PASSES != 4);
+
+	while (n >= 4) {
+		NH_STRIDE(k0, k1, k2, k3);
+		NH_STRIDE(k1, k2, k3, k0);
+		NH_STRIDE(k2, k3, k0, k1);
+		NH_STRIDE(k3, k0, k1, k2);
+		n -= 4;
+	}
+	if (n) {
+		NH_STRIDE(k0, k1, k2, k3);
+		if (--n) {
+			NH_STRIDE(k1, k2, k3, k0);
+			if (--n)
+				NH_STRIDE(k2, k3, k0, k1);
+		}
+	}
+
+	hash[0] = cpu_to_le64(sum0);
+	hash[1] = cpu_to_le64(sum1);
+	hash[2] = cpu_to_le64(sum2);
+	hash[3] = cpu_to_le64(sum3);
+}
+
+/* Pass the next NH hash value through Poly1305 */
+static void process_nh_hash_value(struct nhpoly1305_state *state,
+				  const struct nhpoly1305_key *key)
+{
+	BUILD_BUG_ON(NH_HASH_BYTES % POLY1305_BLOCK_SIZE != 0);
+
+	poly1305_core_blocks(&state->poly_state, &key->poly_key, state->nh_hash,
+			     NH_HASH_BYTES / POLY1305_BLOCK_SIZE);
+}
+
+/*
+ * Feed the next portion of the source data, as a whole number of 16-byte
+ * "NH message units", through NH and Poly1305.  Each NH hash is taken over
+ * 1024 bytes, except possibly the final one which is taken over a multiple of
+ * 16 bytes up to 1024.  Also, in the case where data is passed in misaligned
+ * chunks, we combine partial hashes; the end result is the same either way.
+ */
+static void nhpoly1305_units(struct nhpoly1305_state *state,
+			     const struct nhpoly1305_key *key,
+			     const u8 *src, unsigned int srclen, nh_t nh_fn)
+{
+	do {
+		unsigned int bytes;
+
+		if (state->nh_remaining == 0) {
+			/* Starting a new NH message */
+			bytes = min_t(unsigned int, srclen, NH_MESSAGE_BYTES);
+			nh_fn(key->nh_key, src, bytes, state->nh_hash);
+			state->nh_remaining = NH_MESSAGE_BYTES - bytes;
+		} else {
+			/* Continuing a previous NH message */
+			__le64 tmp_hash[NH_NUM_PASSES];
+			unsigned int pos;
+			int i;
+
+			pos = NH_MESSAGE_BYTES - state->nh_remaining;
+			bytes = min(srclen, state->nh_remaining);
+			nh_fn(&key->nh_key[pos / 4], src, bytes, tmp_hash);
+			for (i = 0; i < NH_NUM_PASSES; i++)
+				le64_add_cpu(&state->nh_hash[i],
+					     le64_to_cpu(tmp_hash[i]));
+			state->nh_remaining -= bytes;
+		}
+		if (state->nh_remaining == 0)
+			process_nh_hash_value(state, key);
+		src += bytes;
+		srclen -= bytes;
+	} while (srclen);
+}
+
+int crypto_nhpoly1305_setkey(struct crypto_shash *tfm,
+			     const u8 *key, unsigned int keylen)
+{
+	struct nhpoly1305_key *ctx = crypto_shash_ctx(tfm);
+	int i;
+
+	if (keylen != NHPOLY1305_KEY_SIZE)
+		return -EINVAL;
+
+	poly1305_core_setkey(&ctx->poly_key, key);
+	key += POLY1305_BLOCK_SIZE;
+
+	for (i = 0; i < NH_KEY_WORDS; i++)
+		ctx->nh_key[i] = get_unaligned_le32(key + i * sizeof(u32));
+
+	return 0;
+}
+EXPORT_SYMBOL(crypto_nhpoly1305_setkey);
+
+int crypto_nhpoly1305_init(struct shash_desc *desc)
+{
+	struct nhpoly1305_state *state = shash_desc_ctx(desc);
+
+	poly1305_core_init(&state->poly_state);
+	state->buflen = 0;
+	state->nh_remaining = 0;
+	return 0;
+}
+EXPORT_SYMBOL(crypto_nhpoly1305_init);
+
+int crypto_nhpoly1305_update_helper(struct shash_desc *desc,
+				    const u8 *src, unsigned int srclen,
+				    nh_t nh_fn)
+{
+	struct nhpoly1305_state *state = shash_desc_ctx(desc);
+	const struct nhpoly1305_key *key = crypto_shash_ctx(desc->tfm);
+	unsigned int bytes;
+
+	if (state->buflen) {
+		bytes = min(srclen, (int)NH_MESSAGE_UNIT - state->buflen);
+		memcpy(&state->buffer[state->buflen], src, bytes);
+		state->buflen += bytes;
+		if (state->buflen < NH_MESSAGE_UNIT)
+			return 0;
+		nhpoly1305_units(state, key, state->buffer, NH_MESSAGE_UNIT,
+				 nh_fn);
+		state->buflen = 0;
+		src += bytes;
+		srclen -= bytes;
+	}
+
+	if (srclen >= NH_MESSAGE_UNIT) {
+		bytes = round_down(srclen, NH_MESSAGE_UNIT);
+		nhpoly1305_units(state, key, src, bytes, nh_fn);
+		src += bytes;
+		srclen -= bytes;
+	}
+
+	if (srclen) {
+		memcpy(state->buffer, src, srclen);
+		state->buflen = srclen;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(crypto_nhpoly1305_update_helper);
+
+int crypto_nhpoly1305_update(struct shash_desc *desc,
+			     const u8 *src, unsigned int srclen)
+{
+	return crypto_nhpoly1305_update_helper(desc, src, srclen, nh_generic);
+}
+EXPORT_SYMBOL(crypto_nhpoly1305_update);
+
+int crypto_nhpoly1305_final_helper(struct shash_desc *desc, u8 *dst, nh_t nh_fn)
+{
+	struct nhpoly1305_state *state = shash_desc_ctx(desc);
+	const struct nhpoly1305_key *key = crypto_shash_ctx(desc->tfm);
+
+	if (state->buflen) {
+		memset(&state->buffer[state->buflen], 0,
+		       NH_MESSAGE_UNIT - state->buflen);
+		nhpoly1305_units(state, key, state->buffer, NH_MESSAGE_UNIT,
+				 nh_fn);
+	}
+
+	if (state->nh_remaining)
+		process_nh_hash_value(state, key);
+
+	poly1305_core_emit(&state->poly_state, dst);
+	return 0;
+}
+EXPORT_SYMBOL(crypto_nhpoly1305_final_helper);
+
+int crypto_nhpoly1305_final(struct shash_desc *desc, u8 *dst)
+{
+	return crypto_nhpoly1305_final_helper(desc, dst, nh_generic);
+}
+EXPORT_SYMBOL(crypto_nhpoly1305_final);
+
+static struct shash_alg nhpoly1305_alg = {
+	.digestsize	= POLY1305_DIGEST_SIZE,
+	.init		= crypto_nhpoly1305_init,
+	.update		= crypto_nhpoly1305_update,
+	.final		= crypto_nhpoly1305_final,
+	.setkey		= crypto_nhpoly1305_setkey,
+	.descsize	= sizeof(struct nhpoly1305_state),
+	.base		= {
+		.cra_name		= "nhpoly1305",
+		.cra_driver_name	= "nhpoly1305-generic",
+		.cra_priority		= 100,
+		.cra_ctxsize		= sizeof(struct nhpoly1305_key),
+		.cra_module		= THIS_MODULE,
+	},
+};
+
+static int __init nhpoly1305_mod_init(void)
+{
+	return crypto_register_shash(&nhpoly1305_alg);
+}
+
+static void __exit nhpoly1305_mod_exit(void)
+{
+	crypto_unregister_shash(&nhpoly1305_alg);
+}
+
+module_init(nhpoly1305_mod_init);
+module_exit(nhpoly1305_mod_exit);
+
+MODULE_DESCRIPTION("NHPoly1305 ε-almost-∆-universal hash function");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
+MODULE_ALIAS_CRYPTO("nhpoly1305");
+MODULE_ALIAS_CRYPTO("nhpoly1305-generic");
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 3ff70ebc745cb..039a5d850a29c 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -3291,6 +3291,12 @@  static const struct alg_test_desc alg_test_descs[] = {
 				.dec = __VECS(morus640_dec_tv_template),
 			}
 		}
+	}, {
+		.alg = "nhpoly1305",
+		.test = alg_test_hash,
+		.suite = {
+			.hash = __VECS(nhpoly1305_tv_template)
+		}
 	}, {
 		.alg = "ofb(aes)",
 		.test = alg_test_skcipher,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 3b57b2701fcb2..40197d74b3d56 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -27,7 +27,7 @@ 
 #define MAX_DIGEST_SIZE		64
 #define MAX_TAP			8
 
-#define MAX_KEYLEN		160
+#define MAX_KEYLEN		1088
 #define MAX_IVLEN		32
 
 struct hash_testvec {
@@ -35,10 +35,10 @@  struct hash_testvec {
 	const char *key;
 	const char *plaintext;
 	const char *digest;
-	unsigned char tap[MAX_TAP];
+	unsigned short tap[MAX_TAP];
+	unsigned short np;
 	unsigned short psize;
-	unsigned char np;
-	unsigned char ksize;
+	unsigned short ksize;
 };
 
 /*
@@ -5593,6 +5593,1238 @@  static const struct hash_testvec poly1305_tv_template[] = {
 	},
 };
 
+/* NHPoly1305 test vectors from https://github.com/google/adiantum */
+static const struct hash_testvec nhpoly1305_tv_template[] = {
+	{
+		.key	= "\xd2\x5d\x4c\xdd\x8d\x2b\x7f\x7a"
+			  "\xd9\xbe\x71\xec\xd1\x83\x52\xe3"
+			  "\xe1\xad\xd7\x5c\x0a\x75\x9d\xec"
+			  "\x1d\x13\x7e\x5d\x71\x07\xc9\xe4"
+			  "\x57\x2d\x44\x68\xcf\xd8\xd6\xc5"
+			  "\x39\x69\x7d\x32\x75\x51\x4f\x7e"
+			  "\xb2\x4c\xc6\x90\x51\x6e\xd9\xd6"
+			  "\xa5\x8b\x2d\xf1\x94\xf9\xf7\x5e"
+			  "\x2c\x84\x7b\x41\x0f\x88\x50\x89"
+			  "\x30\xd9\xa1\x38\x46\x6c\xc0\x4f"
+			  "\xe8\xdf\xdc\x66\xab\x24\x43\x41"
+			  "\x91\x55\x29\x65\x86\x28\x5e\x45"
+			  "\xd5\x2d\xb7\x80\x08\x9a\xc3\xd4"
+			  "\x9a\x77\x0a\xd4\xef\x3e\xe6\x3f"
+			  "\x6f\x2f\x9b\x3a\x7d\x12\x1e\x80"
+			  "\x6c\x44\xa2\x25\xe1\xf6\x60\xe9"
+			  "\x0d\xaf\xc5\x3c\xa5\x79\xae\x64"
+			  "\xbc\xa0\x39\xa3\x4d\x10\xe5\x4d"
+			  "\xd5\xe7\x89\x7a\x13\xee\x06\x78"
+			  "\xdc\xa4\xdc\x14\x27\xe6\x49\x38"
+			  "\xd0\xe0\x45\x25\x36\xc5\xf4\x79"
+			  "\x2e\x9a\x98\x04\xe4\x2b\x46\x52"
+			  "\x7c\x33\xca\xe2\x56\x51\x50\xe2"
+			  "\xa5\x9a\xae\x18\x6a\x13\xf8\xd2"
+			  "\x21\x31\x66\x02\xe2\xda\x8d\x7e"
+			  "\x41\x19\xb2\x61\xee\x48\x8f\xf1"
+			  "\x65\x24\x2e\x1e\x68\xce\x05\xd9"
+			  "\x2a\xcf\xa5\x3a\x57\xdd\x35\x91"
+			  "\x93\x01\xca\x95\xfc\x2b\x36\x04"
+			  "\xe6\x96\x97\x28\xf6\x31\xfe\xa3"
+			  "\x9d\xf6\x6a\x1e\x80\x8d\xdc\xec"
+			  "\xaf\x66\x11\x13\x02\x88\xd5\x27"
+			  "\x33\xb4\x1a\xcd\xa3\xf6\xde\x31"
+			  "\x8e\xc0\x0e\x6c\xd8\x5a\x97\x5e"
+			  "\xdd\xfd\x60\x69\x38\x46\x3f\x90"
+			  "\x5e\x97\xd3\x32\x76\xc7\x82\x49"
+			  "\xfe\xba\x06\x5f\x2f\xa2\xfd\xff"
+			  "\x80\x05\x40\xe4\x33\x03\xfb\x10"
+			  "\xc0\xde\x65\x8c\xc9\x8d\x3a\x9d"
+			  "\xb5\x7b\x36\x4b\xb5\x0c\xcf\x00"
+			  "\x9c\x87\xe4\x49\xad\x90\xda\x4a"
+			  "\xdd\xbd\xff\xe2\x32\x57\xd6\x78"
+			  "\x36\x39\x6c\xd3\x5b\x9b\x88\x59"
+			  "\x2d\xf0\x46\xe4\x13\x0e\x2b\x35"
+			  "\x0d\x0f\x73\x8a\x4f\x26\x84\x75"
+			  "\x88\x3c\xc5\x58\x66\x18\x1a\xb4"
+			  "\x64\x51\x34\x27\x1b\xa4\x11\xc9"
+			  "\x6d\x91\x8a\xfa\x32\x60\x9d\xd7"
+			  "\x87\xe5\xaa\x43\x72\xf8\xda\xd1"
+			  "\x48\x44\x13\x61\xdc\x8c\x76\x17"
+			  "\x0c\x85\x4e\xf3\xdd\xa2\x42\xd2"
+			  "\x74\xc1\x30\x1b\xeb\x35\x31\x29"
+			  "\x5b\xd7\x4c\x94\x46\x35\xa1\x23"
+			  "\x50\xf2\xa2\x8e\x7e\x4f\x23\x4f"
+			  "\x51\xff\xe2\xc9\xa3\x7d\x56\x8b"
+			  "\x41\xf2\xd0\xc5\x57\x7e\x59\xac"
+			  "\xbb\x65\xf3\xfe\xf7\x17\xef\x63"
+			  "\x7c\x6f\x23\xdd\x22\x8e\xed\x84"
+			  "\x0e\x3b\x09\xb3\xf3\xf4\x8f\xcd"
+			  "\x37\xa8\xe1\xa7\x30\xdb\xb1\xa2"
+			  "\x9c\xa2\xdf\x34\x17\x3e\x68\x44"
+			  "\xd0\xde\x03\x50\xd1\x48\x6b\x20"
+			  "\xe2\x63\x45\xa5\xea\x87\xc2\x42"
+			  "\x95\x03\x49\x05\xed\xe0\x90\x29"
+			  "\x1a\xb8\xcf\x9b\x43\xcf\x29\x7a"
+			  "\x63\x17\x41\x9f\xe0\xc9\x10\xfd"
+			  "\x2c\x56\x8c\x08\x55\xb4\xa9\x27"
+			  "\x0f\x23\xb1\x05\x6a\x12\x46\xc7"
+			  "\xe1\xfe\x28\x93\x93\xd7\x2f\xdc"
+			  "\x98\x30\xdb\x75\x8a\xbe\x97\x7a"
+			  "\x02\xfb\x8c\xba\xbe\x25\x09\xbe"
+			  "\xce\xcb\xa2\xef\x79\x4d\x0e\x9d"
+			  "\x1b\x9d\xb6\x39\x34\x38\xfa\x07"
+			  "\xec\xe8\xfc\x32\x85\x1d\xf7\x85"
+			  "\x63\xc3\x3c\xc0\x02\x75\xd7\x3f"
+			  "\xb2\x68\x60\x66\x65\x81\xc6\xb1"
+			  "\x42\x65\x4b\x4b\x28\xd7\xc7\xaa"
+			  "\x9b\xd2\xdc\x1b\x01\xe0\x26\x39"
+			  "\x01\xc1\x52\x14\xd1\x3f\xb7\xe6"
+			  "\x61\x41\xc7\x93\xd2\xa2\x67\xc6"
+			  "\xf7\x11\xb5\xf5\xea\xdd\x19\xfb"
+			  "\x4d\x21\x12\xd6\x7d\xf1\x10\xb0"
+			  "\x89\x07\xc7\x5a\x52\x73\x70\x2f"
+			  "\x32\xef\x65\x2b\x12\xb2\xf0\xf5"
+			  "\x20\xe0\x90\x59\x7e\x64\xf1\x4c"
+			  "\x41\xb3\xa5\x91\x08\xe6\x5e\x5f"
+			  "\x05\x56\x76\xb4\xb0\xcd\x70\x53"
+			  "\x10\x48\x9c\xff\xc2\x69\x55\x24"
+			  "\x87\xef\x84\xea\xfb\xa7\xbf\xa0"
+			  "\x91\x04\xad\x4f\x8b\x57\x54\x4b"
+			  "\xb6\xe9\xd1\xac\x37\x2f\x1d\x2e"
+			  "\xab\xa5\xa4\xe8\xff\xfb\xd9\x39"
+			  "\x2f\xb7\xac\xd1\xfe\x0b\x9a\x80"
+			  "\x0f\xb6\xf4\x36\x39\x90\x51\xe3"
+			  "\x0a\x2f\xb6\x45\x76\x89\xcd\x61"
+			  "\xfe\x48\x5f\x75\x1d\x13\x00\x62"
+			  "\x80\x24\x47\xe7\xbc\x37\xd7\xe3"
+			  "\x15\xe8\x68\x22\xaf\x80\x6f\x4b"
+			  "\xa8\x9f\x01\x10\x48\x14\xc3\x02"
+			  "\x52\xd2\xc7\x75\x9b\x52\x6d\x30"
+			  "\xac\x13\x85\xc8\xf7\xa3\x58\x4b"
+			  "\x49\xf7\x1c\x45\x55\x8c\x39\x9a"
+			  "\x99\x6d\x97\x27\x27\xe6\xab\xdd"
+			  "\x2c\x42\x1b\x35\xdd\x9d\x73\xbb"
+			  "\x6c\xf3\x64\xf1\xfb\xb9\xf7\xe6"
+			  "\x4a\x3c\xc0\x92\xc0\x2e\xb7\x1a"
+			  "\xbe\xab\xb3\x5a\xe5\xea\xb1\x48"
+			  "\x58\x13\x53\x90\xfd\xc3\x8e\x54"
+			  "\xf9\x18\x16\x73\xe8\xcb\x6d\x39"
+			  "\x0e\xd7\xe0\xfe\xb6\x9f\x43\x97"
+			  "\xe8\xd0\x85\x56\x83\x3e\x98\x68"
+			  "\x7f\xbd\x95\xa8\x9a\x61\x21\x8f"
+			  "\x06\x98\x34\xa6\xc8\xd6\x1d\xf3"
+			  "\x3d\x43\xa4\x9a\x8c\xe5\xd3\x5a"
+			  "\x32\xa2\x04\x22\xa4\x19\x1a\x46"
+			  "\x42\x7e\x4d\xe5\xe0\xe6\x0e\xca"
+			  "\xd5\x58\x9d\x2c\xaf\xda\x33\x5c"
+			  "\xb0\x79\x9e\xc9\xfc\xca\xf0\x2f"
+			  "\xa8\xb2\x77\xeb\x7a\xa2\xdd\x37"
+			  "\x35\x83\x07\xd6\x02\x1a\xb6\x6c"
+			  "\x24\xe2\x59\x08\x0e\xfd\x3e\x46"
+			  "\xec\x40\x93\xf4\x00\x26\x4f\x2a"
+			  "\xff\x47\x2f\xeb\x02\x92\x26\x5b"
+			  "\x53\x17\xc2\x8d\x2a\xc7\xa3\x1b"
+			  "\xcd\xbc\xa7\xe8\xd1\x76\xe3\x80"
+			  "\x21\xca\x5d\x3b\xe4\x9c\x8f\xa9"
+			  "\x5b\x7f\x29\x7f\x7c\xd8\xed\x6d"
+			  "\x8c\xb2\x86\x85\xe7\x77\xf2\x85"
+			  "\xab\x38\xa9\x9d\xc1\x4e\xc5\x64"
+			  "\x33\x73\x8b\x59\x03\xad\x05\xdf"
+			  "\x25\x98\x31\xde\xef\x13\xf1\x9b"
+			  "\x3c\x91\x9d\x7b\xb1\xfa\xe6\xbf"
+			  "\x5b\xed\xa5\x55\xe6\xea\x6c\x74"
+			  "\xf4\xb9\xe4\x45\x64\x72\x81\xc2"
+			  "\x4c\x28\xd4\xcd\xac\xe2\xde\xf9"
+			  "\xeb\x5c\xeb\x61\x60\x5a\xe5\x28",
+		.ksize	= 1088,
+		.plaintext	= "",
+		.psize	= 0,
+		.digest	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+	}, {
+		.key	= "\x29\x21\x43\xcb\xcb\x13\x07\xde"
+			  "\xbf\x48\xdf\x8a\x7f\xa2\x84\xde"
+			  "\x72\x23\x9d\xf5\xf0\x07\xf2\x4c"
+			  "\x20\x3a\x93\xb9\xcd\x5d\xfe\xcb"
+			  "\x99\x2c\x2b\x58\xc6\x50\x5f\x94"
+			  "\x56\xc3\x7c\x0d\x02\x3f\xb8\x5e"
+			  "\x7b\xc0\x6c\x51\x34\x76\xc0\x0e"
+			  "\xc6\x22\xc8\x9e\x92\xa0\x21\xc9"
+			  "\x85\x5c\x7c\xf8\xe2\x64\x47\xc9"
+			  "\xe4\xa2\x57\x93\xf8\xa2\x69\xcd"
+			  "\x62\x98\x99\xf4\xd7\x7b\x14\xb1"
+			  "\xd8\x05\xff\x04\x15\xc9\xe1\x6e"
+			  "\x9b\xe6\x50\x6b\x0b\x3f\x22\x1f"
+			  "\x08\xde\x0c\x5b\x08\x7e\xc6\x2f"
+			  "\x6c\xed\xd6\xb2\x15\xa4\xb3\xf9"
+			  "\xa7\x46\x38\x2a\xea\x69\xa5\xde"
+			  "\x02\xc3\x96\x89\x4d\x55\x3b\xed"
+			  "\x3d\x3a\x85\x77\xbf\x97\x45\x5c"
+			  "\x9e\x02\x69\xe2\x1b\x68\xbe\x96"
+			  "\xfb\x64\x6f\x0f\xf6\x06\x40\x67"
+			  "\xfa\x04\xe3\x55\xfa\xbe\xa4\x60"
+			  "\xef\x21\x66\x97\xe6\x9d\x5c\x1f"
+			  "\x62\x37\xaa\x31\xde\xe4\x9c\x28"
+			  "\x95\xe0\x22\x86\xf4\x4d\xf3\x07"
+			  "\xfd\x5f\x3a\x54\x2c\x51\x80\x71"
+			  "\xba\x78\x69\x5b\x65\xab\x1f\x81"
+			  "\xed\x3b\xff\x34\xa3\xfb\xbc\x73"
+			  "\x66\x7d\x13\x7f\xdf\x6e\xe2\xe2"
+			  "\xeb\x4f\x6c\xda\x7d\x33\x57\xd0"
+			  "\xd3\x7c\x95\x4f\x33\x58\x21\xc7"
+			  "\xc0\xe5\x6f\x42\x26\xc6\x1f\x5e"
+			  "\x85\x1b\x98\x9a\xa2\x1e\x55\x77"
+			  "\x23\xdf\x81\x5e\x79\x55\x05\xfc"
+			  "\xfb\xda\xee\xba\x5a\xba\xf7\x77"
+			  "\x7f\x0e\xd3\xe1\x37\xfe\x8d\x2b"
+			  "\xd5\x3f\xfb\xd0\xc0\x3c\x0b\x3f"
+			  "\xcf\x3c\x14\xcf\xfb\x46\x72\x4c"
+			  "\x1f\x39\xe2\xda\x03\x71\x6d\x23"
+			  "\xef\x93\xcd\x39\xd9\x37\x80\x4d"
+			  "\x65\x61\xd1\x2c\x03\xa9\x47\x72"
+			  "\x4d\x1e\x0e\x16\x33\x0f\x21\x17"
+			  "\xec\x92\xea\x6f\x37\x22\xa4\xd8"
+			  "\x03\x33\x9e\xd8\x03\x69\x9a\xe8"
+			  "\xb2\x57\xaf\x78\x99\x05\x12\xab"
+			  "\x48\x90\x80\xf0\x12\x9b\x20\x64"
+			  "\x7a\x1d\x47\x5f\xba\x3c\xf9\xc3"
+			  "\x0a\x0d\x8d\xa1\xf9\x1b\x82\x13"
+			  "\x3e\x0d\xec\x0a\x83\xc0\x65\xe1"
+			  "\xe9\x95\xff\x97\xd6\xf2\xe4\xd5"
+			  "\x86\xc0\x1f\x29\x27\x63\xd7\xde"
+			  "\xb7\x0a\x07\x99\x04\x2d\xa3\x89"
+			  "\xa2\x43\xcf\xf3\xe1\x43\xac\x4a"
+			  "\x06\x97\xd0\x05\x4f\x87\xfa\xf9"
+			  "\x9b\xbf\x52\x70\xbd\xbc\x6c\xf3"
+			  "\x03\x13\x60\x41\x28\x09\xec\xcc"
+			  "\xb1\x1a\xec\xd6\xfb\x6f\x2a\x89"
+			  "\x5d\x0b\x53\x9c\x59\xc1\x84\x21"
+			  "\x33\x51\x47\x19\x31\x9c\xd4\x0a"
+			  "\x4d\x04\xec\x50\x90\x61\xbd\xbc"
+			  "\x7e\xc8\xd9\x6c\x98\x1d\x45\x41"
+			  "\x17\x5e\x97\x1c\xc5\xa8\xe8\xea"
+			  "\x46\x58\x53\xf7\x17\xd5\xad\x11"
+			  "\xc8\x54\xf5\x7a\x33\x90\xf5\x19"
+			  "\xba\x36\xb4\xfc\x52\xa5\x72\x3d"
+			  "\x14\xbb\x55\xa7\xe9\xe3\x12\xf7"
+			  "\x1c\x30\xa2\x82\x03\xbf\x53\x91"
+			  "\x2e\x60\x41\x9f\x5b\x69\x39\xf6"
+			  "\x4d\xc8\xf8\x46\x7a\x7f\xa4\x98"
+			  "\x36\xff\x06\xcb\xca\xe7\x33\xf2"
+			  "\xc0\x4a\xf4\x3c\x14\x44\x5f\x6b"
+			  "\x75\xef\x02\x36\x75\x08\x14\xfd"
+			  "\x10\x8e\xa5\x58\xd0\x30\x46\x49"
+			  "\xaf\x3a\xf8\x40\x3d\x35\xdb\x84"
+			  "\x11\x2e\x97\x6a\xb7\x87\x7f\xad"
+			  "\xf1\xfa\xa5\x63\x60\xd8\x5e\xbf"
+			  "\x41\x78\x49\xcf\x77\xbb\x56\xbb"
+			  "\x7d\x01\x67\x05\x22\xc8\x8f\x41"
+			  "\xba\x81\xd2\xca\x2c\x38\xac\x76"
+			  "\x06\xc1\x1a\xc2\xce\xac\x90\x67"
+			  "\x57\x3e\x20\x12\x5b\xd9\x97\x58"
+			  "\x65\x05\xb7\x04\x61\x7e\xd8\x3a"
+			  "\xbf\x55\x3b\x13\xe9\x34\x5a\x37"
+			  "\x36\xcb\x94\x45\xc5\x32\xb3\xa0"
+			  "\x0c\x3e\x49\xc5\xd3\xed\xa7\xf0"
+			  "\x1c\x69\xcc\xea\xcc\x83\xc9\x16"
+			  "\x95\x72\x4b\xf4\x89\xd5\xb9\x10"
+			  "\xf6\x2d\x60\x15\xea\x3c\x06\x66"
+			  "\x9f\x82\xad\x17\xce\xd2\xa4\x48"
+			  "\x7c\x65\xd9\xf8\x02\x4d\x9b\x4c"
+			  "\x89\x06\x3a\x34\x85\x48\x89\x86"
+			  "\xf9\x24\xa9\x54\x72\xdb\x44\x95"
+			  "\xc7\x44\x1c\x19\x11\x4c\x04\xdc"
+			  "\x13\xb9\x67\xc8\xc3\x3a\x6a\x50"
+			  "\xfa\xd1\xfb\xe1\x88\xb6\xf1\xa3"
+			  "\xc5\x3b\xdc\x38\x45\x16\x26\x02"
+			  "\x3b\xb8\x8f\x8b\x58\x7d\x23\x04"
+			  "\x50\x6b\x81\x9f\xae\x66\xac\x6f"
+			  "\xcf\x2a\x9d\xf1\xfd\x1d\x57\x07"
+			  "\xbe\x58\xeb\x77\x0c\xe3\xc2\x19"
+			  "\x14\x74\x1b\x51\x1c\x4f\x41\xf3"
+			  "\x32\x89\xb3\xe7\xde\x62\xf6\x5f"
+			  "\xc7\x6a\x4a\x2a\x5b\x0f\x5f\x87"
+			  "\x9c\x08\xb9\x02\x88\xc8\x29\xb7"
+			  "\x94\x52\xfa\x52\xfe\xaa\x50\x10"
+			  "\xba\x48\x75\x5e\x11\x1b\xe6\x39"
+			  "\xd7\x82\x2c\x87\xf1\x1e\xa4\x38"
+			  "\x72\x3e\x51\xe7\xd8\x3e\x5b\x7b"
+			  "\x31\x16\x89\xba\xd6\xad\x18\x5e"
+			  "\xba\xf8\x12\xb3\xf4\x6c\x47\x30"
+			  "\xc0\x38\x58\xb3\x10\x8d\x58\x5d"
+			  "\xb4\xfb\x19\x7e\x41\xc3\x66\xb8"
+			  "\xd6\x72\x84\xe1\x1a\xc2\x71\x4c"
+			  "\x0d\x4a\x21\x7a\xab\xa2\xc0\x36"
+			  "\x15\xc5\xe9\x46\xd7\x29\x17\x76"
+			  "\x5e\x47\x36\x7f\x72\x05\xa7\xcc"
+			  "\x36\x63\xf9\x47\x7d\xe6\x07\x3c"
+			  "\x8b\x79\x1d\x96\x61\x8d\x90\x65"
+			  "\x7c\xf5\xeb\x4e\x6e\x09\x59\x6d"
+			  "\x62\x50\x1b\x0f\xe0\xdc\x78\xf2"
+			  "\x5b\x83\x1a\xa1\x11\x75\xfd\x18"
+			  "\xd7\xe2\x8d\x65\x14\x21\xce\xbe"
+			  "\xb5\x87\xe3\x0a\xda\x24\x0a\x64"
+			  "\xa9\x9f\x03\x8d\x46\x5d\x24\x1a"
+			  "\x8a\x0c\x42\x01\xca\xb1\x5f\x7c"
+			  "\xa5\xac\x32\x4a\xb8\x07\x91\x18"
+			  "\x6f\xb0\x71\x3c\xc9\xb1\xa8\xf8"
+			  "\x5f\x69\xa5\xa1\xca\x9e\x7a\xaa"
+			  "\xac\xe9\xc7\x47\x41\x75\x25\xc3"
+			  "\x73\xe2\x0b\xdd\x6d\x52\x71\xbe"
+			  "\xc5\xdc\xb4\xe7\x01\x26\x53\x77"
+			  "\x86\x90\x85\x68\x6b\x7b\x03\x53"
+			  "\xda\x52\x52\x51\x68\xc8\xf3\xec"
+			  "\x6c\xd5\x03\x7a\xa3\x0e\xb4\x02"
+			  "\x5f\x1a\xab\xee\xca\x67\x29\x7b"
+			  "\xbd\x96\x59\xb3\x8b\x32\x7a\x92"
+			  "\x9f\xd8\x25\x2b\xdf\xc0\x4c\xda",
+		.ksize	= 1088,
+		.plaintext	= "\xbc\xda\x81\xa8\x78\x79\x1c\xbf"
+			  "\x77\x53\xba\x4c\x30\x5b\xb8\x33",
+		.psize	= 16,
+		.digest	= "\x04\xbf\x7f\x6a\xce\x72\xea\x6a"
+			  "\x79\xdb\xb0\xc9\x60\xf6\x12\xcc",
+		.np	= 6,
+		.tap	= { 4, 4, 1, 1, 1, 5 },
+	}, {
+		.key	= "\x65\x4d\xe3\xf8\xd2\x4c\xac\x28"
+			  "\x68\xf5\xb3\x81\x71\x4b\xa1\xfa"
+			  "\x04\x0e\xd3\x81\x36\xbe\x0c\x81"
+			  "\x5e\xaf\xbc\x3a\xa4\xc0\x8e\x8b"
+			  "\x55\x63\xd3\x52\x97\x88\xd6\x19"
+			  "\xbc\x96\xdf\x49\xff\x04\x63\xf5"
+			  "\x0c\x11\x13\xaa\x9e\x1f\x5a\xf7"
+			  "\xdd\xbd\x37\x80\xc3\xd0\xbe\xa7"
+			  "\x05\xc8\x3c\x98\x1e\x05\x3c\x84"
+			  "\x39\x61\xc4\xed\xed\x71\x1b\xc4"
+			  "\x74\x45\x2c\xa1\x56\x70\x97\xfd"
+			  "\x44\x18\x07\x7d\xca\x60\x1f\x73"
+			  "\x3b\x6d\x21\xcb\x61\x87\x70\x25"
+			  "\x46\x21\xf1\x1f\x21\x91\x31\x2d"
+			  "\x5d\xcc\xb7\xd1\x84\x3e\x3d\xdb"
+			  "\x03\x53\x2a\x82\xa6\x9a\x95\xbc"
+			  "\x1a\x1e\x0a\x5e\x07\x43\xab\x43"
+			  "\xaf\x92\x82\x06\x91\x04\x09\xf4"
+			  "\x17\x0a\x9a\x2c\x54\xdb\xb8\xf4"
+			  "\xd0\xf0\x10\x66\x24\x8d\xcd\xda"
+			  "\xfe\x0e\x45\x9d\x6f\xc4\x4e\xf4"
+			  "\x96\xaf\x13\xdc\xa9\xd4\x8c\xc4"
+			  "\xc8\x57\x39\x3c\xc2\xd3\x0a\x76"
+			  "\x4a\x1f\x75\x83\x44\xc7\xd1\x39"
+			  "\xd8\xb5\x41\xba\x73\x87\xfa\x96"
+			  "\xc7\x18\x53\xfb\x9b\xda\xa0\x97"
+			  "\x1d\xee\x60\x85\x9e\x14\xc3\xce"
+			  "\xc4\x05\x29\x3b\x95\x30\xa3\xd1"
+			  "\x9f\x82\x6a\x04\xf5\xa7\x75\x57"
+			  "\x82\x04\xfe\x71\x51\x71\xb1\x49"
+			  "\x50\xf8\xe0\x96\xf1\xfa\xa8\x88"
+			  "\x3f\xa0\x86\x20\xd4\x60\x79\x59"
+			  "\x17\x2d\xd1\x09\xf4\xec\x05\x57"
+			  "\xcf\x62\x7e\x0e\x7e\x60\x78\xe6"
+			  "\x08\x60\x29\xd8\xd5\x08\x1a\x24"
+			  "\xc4\x6c\x24\xe7\x92\x08\x3d\x8a"
+			  "\x98\x7a\xcf\x99\x0a\x65\x0e\xdc"
+			  "\x8c\x8a\xbe\x92\x82\x91\xcc\x62"
+			  "\x30\xb6\xf4\x3f\xc6\x8a\x7f\x12"
+			  "\x4a\x8a\x49\xfa\x3f\x5c\xd4\x5a"
+			  "\xa6\x82\xa3\xe6\xaa\x34\x76\xb2"
+			  "\xab\x0a\x30\xef\x6c\x77\x58\x3f"
+			  "\x05\x6b\xcc\x5c\xae\xdc\xd7\xb9"
+			  "\x51\x7e\x8d\x32\x5b\x24\x25\xbe"
+			  "\x2b\x24\x01\xcf\x80\xda\x16\xd8"
+			  "\x90\x72\x2c\xad\x34\x8d\x0c\x74"
+			  "\x02\xcb\xfd\xcf\x6e\xef\x97\xb5"
+			  "\x4c\xf2\x68\xca\xde\x43\x9e\x8a"
+			  "\xc5\x5f\x31\x7f\x14\x71\x38\xec"
+			  "\xbd\x98\xe5\x71\xc4\xb5\xdb\xef"
+			  "\x59\xd2\xca\xc0\xc1\x86\x75\x01"
+			  "\xd4\x15\x0d\x6f\xa4\xf7\x7b\x37"
+			  "\x47\xda\x18\x93\x63\xda\xbe\x9e"
+			  "\x07\xfb\xb2\x83\xd5\xc4\x34\x55"
+			  "\xee\x73\xa1\x42\x96\xf9\x66\x41"
+			  "\xa4\xcc\xd2\x93\x6e\xe1\x0a\xbb"
+			  "\xd2\xdd\x18\x23\xe6\x6b\x98\x0b"
+			  "\x8a\x83\x59\x2c\xc3\xa6\x59\x5b"
+			  "\x01\x22\x59\xf7\xdc\xb0\x87\x7e"
+			  "\xdb\x7d\xf4\x71\x41\xab\xbd\xee"
+			  "\x79\xbe\x3c\x01\x76\x0b\x2d\x0a"
+			  "\x42\xc9\x77\x8c\xbb\x54\x95\x60"
+			  "\x43\x2e\xe0\x17\x52\xbd\x90\xc9"
+			  "\xc2\x2c\xdd\x90\x24\x22\x76\x40"
+			  "\x5c\xb9\x41\xc9\xa1\xd5\xbd\xe3"
+			  "\x44\xe0\xa4\xab\xcc\xb8\xe2\x32"
+			  "\x02\x15\x04\x1f\x8c\xec\x5d\x14"
+			  "\xac\x18\xaa\xef\x6e\x33\x19\x6e"
+			  "\xde\xfe\x19\xdb\xeb\x61\xca\x18"
+			  "\xad\xd8\x3d\xbf\x09\x11\xc7\xa5"
+			  "\x86\x0b\x0f\xe5\x3e\xde\xe8\xd9"
+			  "\x0a\x69\x9e\x4c\x20\xff\xf9\xc5"
+			  "\xfa\xf8\xf3\x7f\xa5\x01\x4b\x5e"
+			  "\x0f\xf0\x3b\x68\xf0\x46\x8c\x2a"
+			  "\x7a\xc1\x8f\xa0\xfe\x6a\x5b\x44"
+			  "\x70\x5c\xcc\x92\x2c\x6f\x0f\xbd"
+			  "\x25\x3e\xb7\x8e\x73\x58\xda\xc9"
+			  "\xa5\xaa\x9e\xf3\x9b\xfd\x37\x3e"
+			  "\xe2\x88\xa4\x7b\xc8\x5c\xa8\x93"
+			  "\x0e\xe7\x9a\x9c\x2e\x95\x18\x9f"
+			  "\xc8\x45\x0c\x88\x9e\x53\x4f\x3a"
+			  "\x76\xc1\x35\xfa\x17\xd8\xac\xa0"
+			  "\x0c\x2d\x47\x2e\x4f\x69\x9b\xf7"
+			  "\xd0\xb6\x96\x0c\x19\xb3\x08\x01"
+			  "\x65\x7a\x1f\xc7\x31\x86\xdb\xc8"
+			  "\xc1\x99\x8f\xf8\x08\x4a\x9d\x23"
+			  "\x22\xa8\xcf\x27\x01\x01\x88\x93"
+			  "\x9c\x86\x45\xbd\xe0\x51\xca\x52"
+			  "\x84\xba\xfe\x03\xf7\xda\xc5\xce"
+			  "\x3e\x77\x75\x86\xaf\x84\xc8\x05"
+			  "\x44\x01\x0f\x02\xf3\x58\xb0\x06"
+			  "\x5a\xd7\x12\x30\x8d\xdf\x1f\x1f"
+			  "\x0a\xe6\xd2\xea\xf6\x3a\x7a\x99"
+			  "\x63\xe8\xd2\xc1\x4a\x45\x8b\x40"
+			  "\x4d\x0a\xa9\x76\x92\xb3\xda\x87"
+			  "\x36\x33\xf0\x78\xc3\x2f\x5f\x02"
+			  "\x1a\x6a\x2c\x32\xcd\x76\xbf\xbd"
+			  "\x5a\x26\x20\x28\x8c\x8c\xbc\x52"
+			  "\x3d\x0a\xc9\xcb\xab\xa4\x21\xb0"
+			  "\x54\x40\x81\x44\xc7\xd6\x1c\x11"
+			  "\x44\xc6\x02\x92\x14\x5a\xbf\x1a"
+			  "\x09\x8a\x18\xad\xcd\x64\x3d\x53"
+			  "\x4a\xb6\xa5\x1b\x57\x0e\xef\xe0"
+			  "\x8c\x44\x5f\x7d\xbd\x6c\xfd\x60"
+			  "\xae\x02\x24\xb6\x99\xdd\x8c\xaf"
+			  "\x59\x39\x75\x3c\xd1\x54\x7b\x86"
+			  "\xcc\x99\xd9\x28\x0c\xb0\x94\x62"
+			  "\xf9\x51\xd1\x19\x96\x2d\x66\xf5"
+			  "\x55\xcf\x9e\x59\xe2\x6b\x2c\x08"
+			  "\xc0\x54\x48\x24\x45\xc3\x8c\x73"
+			  "\xea\x27\x6e\x66\x7d\x1d\x0e\x6e"
+			  "\x13\xe8\x56\x65\x3a\xb0\x81\x5c"
+			  "\xf0\xe8\xd8\x00\x6b\xcd\x8f\xad"
+			  "\xdd\x53\xf3\xa4\x6c\x43\xd6\x31"
+			  "\xaf\xd2\x76\x1e\x91\x12\xdb\x3c"
+			  "\x8c\xc2\x81\xf0\x49\xdb\xe2\x6b"
+			  "\x76\x62\x0a\x04\xe4\xaa\x8a\x7c"
+			  "\x08\x0b\x5d\xd0\xee\x1d\xfb\xc4"
+			  "\x02\x75\x42\xd6\xba\xa7\x22\xa8"
+			  "\x47\x29\xb7\x85\x6d\x93\x3a\xdb"
+			  "\x00\x53\x0b\xa2\xeb\xf8\xfe\x01"
+			  "\x6f\x8a\x31\xd6\x17\x05\x6f\x67"
+			  "\x88\x95\x32\xfe\x4f\xa6\x4b\xf8"
+			  "\x03\xe4\xcd\x9a\x18\xe8\x4e\x2d"
+			  "\xf7\x97\x9a\x0c\x7d\x9f\x7e\x44"
+			  "\x69\x51\xe0\x32\x6b\x62\x86\x8f"
+			  "\xa6\x8e\x0b\x21\x96\xe5\xaf\x77"
+			  "\xc0\x83\xdf\xa5\x0e\xd0\xa1\x04"
+			  "\xaf\xc1\x10\xcb\x5a\x40\xe4\xe3"
+			  "\x38\x7e\x07\xe8\x4d\xfa\xed\xc5"
+			  "\xf0\x37\xdf\xbb\x8a\xcf\x3d\xdc"
+			  "\x61\xd2\xc6\x2b\xff\x07\xc9\x2f"
+			  "\x0c\x2d\x5c\x07\xa8\x35\x6a\xfc"
+			  "\xae\x09\x03\x45\x74\x51\x4d\xc4"
+			  "\xb8\x23\x87\x4a\x99\x27\x20\x87"
+			  "\x62\x44\x0a\x4a\xce\x78\x47\x22",
+		.ksize	= 1088,
+		.plaintext	= "\x8e\xb0\x4c\xde\x9c\x4a\x04\x5a"
+			  "\xf6\xa9\x7f\x45\x25\xa5\x7b\x3a"
+			  "\xbc\x4d\x73\x39\x81\xb5\xbd\x3d"
+			  "\x21\x6f\xd7\x37\x50\x3c\x7b\x28"
+			  "\xd1\x03\x3a\x17\xed\x7b\x7c\x2a"
+			  "\x16\xbc\xdf\x19\x89\x52\x71\x31"
+			  "\xb6\xc0\xfd\xb5\xd3\xba\x96\x99"
+			  "\xb6\x34\x0b\xd0\x99\x93\xfc\x1a"
+			  "\x01\x3c\x85\xc6\x9b\x78\x5c\x8b"
+			  "\xfe\xae\xd2\xbf\xb2\x6f\xf9\xed"
+			  "\xc8\x25\x17\xfe\x10\x3b\x7d\xda"
+			  "\xf4\x8d\x35\x4b\x7c\x7b\x82\xe7"
+			  "\xc2\xb3\xee\x60\x4a\x03\x86\xc9"
+			  "\x4e\xb5\xc4\xbe\xd2\xbd\x66\xf1"
+			  "\x13\xf1\x09\xab\x5d\xca\x63\x1f"
+			  "\xfc\xfb\x57\x2a\xfc\xca\x66\xd8"
+			  "\x77\x84\x38\x23\x1d\xac\xd3\xb3"
+			  "\x7a\xad\x4c\x70\xfa\x9c\xc9\x61"
+			  "\xa6\x1b\xba\x33\x4b\x4e\x33\xec"
+			  "\xa0\xa1\x64\x39\x40\x05\x1c\xc2"
+			  "\x3f\x49\x9d\xae\xf2\xc5\xf2\xc5"
+			  "\xfe\xe8\xf4\xc2\xf9\x96\x2d\x28"
+			  "\x92\x30\x44\xbc\xd2\x7f\xe1\x6e"
+			  "\x62\x02\x8f\x3d\x1c\x80\xda\x0e"
+			  "\x6a\x90\x7e\x75\xff\xec\x3e\xc4"
+			  "\xcd\x16\x34\x3b\x05\x6d\x4d\x20"
+			  "\x1c\x7b\xf5\x57\x4f\xfa\x3d\xac"
+			  "\xd0\x13\x55\xe8\xb3\xe1\x1b\x78"
+			  "\x30\xe6\x9f\x84\xd4\x69\xd1\x08"
+			  "\x12\x77\xa7\x4a\xbd\xc0\xf2\xd2"
+			  "\x78\xdd\xa3\x81\x12\xcb\x6c\x14"
+			  "\x90\x61\xe2\x84\xc6\x2b\x16\xcc"
+			  "\x40\x99\x50\x88\x01\x09\x64\x4f"
+			  "\x0a\x80\xbe\x61\xae\x46\xc9\x0a"
+			  "\x5d\xe0\xfb\x72\x7a\x1a\xdd\x61"
+			  "\x63\x20\x05\xa0\x4a\xf0\x60\x69"
+			  "\x7f\x92\xbc\xbf\x4e\x39\x4d\xdd"
+			  "\x74\xd1\xb7\xc0\x5a\x34\xb7\xae"
+			  "\x76\x65\x2e\xbc\x36\xb9\x04\x95"
+			  "\x42\xe9\x6f\xca\x78\xb3\x72\x07"
+			  "\xa3\xba\x02\x94\x67\x4c\xb1\xd7"
+			  "\xe9\x30\x0d\xf0\x3b\xb8\x10\x6d"
+			  "\xea\x2b\x21\xbf\x74\x59\x82\x97"
+			  "\x85\xaa\xf1\xd7\x54\x39\xeb\x05"
+			  "\xbd\xf3\x40\xa0\x97\xe6\x74\xfe"
+			  "\xb4\x82\x5b\xb1\x36\xcb\xe8\x0d"
+			  "\xce\x14\xd9\xdf\xf1\x94\x22\xcd"
+			  "\xd6\x00\xba\x04\x4c\x05\x0c\xc0"
+			  "\xd1\x5a\xeb\x52\xd5\xa8\x8e\xc8"
+			  "\x97\xa1\xaa\xc1\xea\xc1\xbe\x7c"
+			  "\x36\xb3\x36\xa0\xc6\x76\x66\xc5"
+			  "\xe2\xaf\xd6\x5c\xe2\xdb\x2c\xb3"
+			  "\x6c\xb9\x99\x7f\xff\x9f\x03\x24"
+			  "\xe1\x51\x44\x66\xd8\x0c\x5d\x7f"
+			  "\x5c\x85\x22\x2a\xcf\x6d\x79\x28"
+			  "\xab\x98\x01\x72\xfe\x80\x87\x5f"
+			  "\x46\xba\xef\x81\x24\xee\xbf\xb0"
+			  "\x24\x74\xa3\x65\x97\x12\xc4\xaf"
+			  "\x8b\xa0\x39\xda\x8a\x7e\x74\x6e"
+			  "\x1b\x42\xb4\x44\x37\xfc\x59\xfd"
+			  "\x86\xed\xfb\x8c\x66\x33\xda\x63"
+			  "\x75\xeb\xe1\xa4\x85\x4f\x50\x8f"
+			  "\x83\x66\x0d\xd3\x37\xfa\xe6\x9c"
+			  "\x4f\x30\x87\x35\x18\xe3\x0b\xb7"
+			  "\x6e\x64\x54\xcd\x70\xb3\xde\x54"
+			  "\xb7\x1d\xe6\x4c\x4d\x55\x12\x12"
+			  "\xaf\x5f\x7f\x5e\xee\x9d\xe8\x8e"
+			  "\x32\x9d\x4e\x75\xeb\xc6\xdd\xaa"
+			  "\x48\x82\xa4\x3f\x3c\xd7\xd3\xa8"
+			  "\x63\x9e\x64\xfe\xe3\x97\x00\x62"
+			  "\xe5\x40\x5d\xc3\xad\x72\xe1\x28"
+			  "\x18\x50\xb7\x75\xef\xcd\x23\xbf"
+			  "\x3f\xc0\x51\x36\xf8\x41\xc3\x08"
+			  "\xcb\xf1\x8d\x38\x34\xbd\x48\x45"
+			  "\x75\xed\xbc\x65\x7b\xb5\x0c\x9b"
+			  "\xd7\x67\x7d\x27\xb4\xc4\x80\xd7"
+			  "\xa9\xb9\xc7\x4a\x97\xaa\xda\xc8"
+			  "\x3c\x74\xcf\x36\x8f\xe4\x41\xe3"
+			  "\xd4\xd3\x26\xa7\xf3\x23\x9d\x8f"
+			  "\x6c\x20\x05\x32\x3e\xe0\xc3\xc8"
+			  "\x56\x3f\xa7\x09\xb7\xfb\xc7\xf7"
+			  "\xbe\x2a\xdd\x0f\x06\x7b\x0d\xdd"
+			  "\xb0\xb4\x86\x17\xfd\xb9\x04\xe5"
+			  "\xc0\x64\x5d\xad\x2a\x36\x38\xdb"
+			  "\x24\xaf\x5b\xff\xca\xf9\x41\xe8"
+			  "\xf9\x2f\x1e\x5e\xf9\xf5\xd5\xf2"
+			  "\xb2\x88\xca\xc9\xa1\x31\xe2\xe8"
+			  "\x10\x95\x65\xbf\xf1\x11\x61\x7a"
+			  "\x30\x1a\x54\x90\xea\xd2\x30\xf6"
+			  "\xa5\xad\x60\xf9\x4d\x84\x21\x1b"
+			  "\xe4\x42\x22\xc8\x12\x4b\xb0\x58"
+			  "\x3e\x9c\x2d\x32\x95\x0a\x8e\xb0"
+			  "\x0a\x7e\x77\x2f\xe8\x97\x31\x6a"
+			  "\xf5\x59\xb4\x26\xe6\x37\x12\xc9"
+			  "\xcb\xa0\x58\x33\x6f\xd5\x55\x55"
+			  "\x3c\xa1\x33\xb1\x0b\x7e\x2e\xb4"
+			  "\x43\x2a\x84\x39\xf0\x9c\xf4\x69"
+			  "\x4f\x1e\x79\xa6\x15\x1b\x87\xbb"
+			  "\xdb\x9b\xe0\xf1\x0b\xba\xe3\x6e"
+			  "\xcc\x2f\x49\x19\x22\x29\xfc\x71"
+			  "\xbb\x77\x38\x18\x61\xaf\x85\x76"
+			  "\xeb\xd1\x09\xcc\x86\x04\x20\x9a"
+			  "\x66\x53\x2f\x44\x8b\xc6\xa3\xd2"
+			  "\x5f\xc7\x79\x82\x66\xa8\x6e\x75"
+			  "\x7d\x94\xd1\x86\x75\x0f\xa5\x4f"
+			  "\x3c\x7a\x33\xce\xd1\x6e\x9d\x7b"
+			  "\x1f\x91\x37\xb8\x37\x80\xfb\xe0"
+			  "\x52\x26\xd0\x9a\xd4\x48\x02\x41"
+			  "\x05\xe3\x5a\x94\xf1\x65\x61\x19"
+			  "\xb8\x88\x4e\x2b\xea\xba\x8b\x58"
+			  "\x8b\x42\x01\x00\xa8\xfe\x00\x5c"
+			  "\xfe\x1c\xee\x31\x15\x69\xfa\xb3"
+			  "\x9b\x5f\x22\x8e\x0d\x2c\xe3\xa5"
+			  "\x21\xb9\x99\x8a\x8e\x94\x5a\xef"
+			  "\x13\x3e\x99\x96\x79\x6e\xd5\x42"
+			  "\x36\x03\xa9\xe2\xca\x65\x4e\x8a"
+			  "\x8a\x30\xd2\x7d\x74\xe7\xf0\xaa"
+			  "\x23\x26\xdd\xcb\x82\x39\xfc\x9d"
+			  "\x51\x76\x21\x80\xa2\xbe\x93\x03"
+			  "\x47\xb0\xc1\xb6\xdc\x63\xfd\x9f"
+			  "\xca\x9d\xa5\xca\x27\x85\xe2\xd8"
+			  "\x15\x5b\x7e\x14\x7a\xc4\x89\xcc"
+			  "\x74\x14\x4b\x46\xd2\xce\xac\x39"
+			  "\x6b\x6a\x5a\xa4\x0e\xe3\x7b\x15"
+			  "\x94\x4b\x0f\x74\xcb\x0c\x7f\xa9"
+			  "\xbe\x09\x39\xa3\xdd\x56\x5c\xc7"
+			  "\x99\x56\x65\x39\xf4\x0b\x7d\x87"
+			  "\xec\xaa\xe3\x4d\x22\x65\x39\x4e",
+		.psize	= 1024,
+		.digest	= "\x64\x3a\xbc\xc3\x3f\x74\x40\x51"
+			  "\x6e\x56\x01\x1a\x51\xec\x36\xde",
+		.np	= 8,
+		.tap	= { 64, 203, 267, 28, 263, 62, 54, 83 },
+	}, {
+		.key	= "\x1b\x82\x2e\x1b\x17\x23\xb9\x6d"
+			  "\xdc\x9c\xda\x99\x07\xe3\x5f\xd8"
+			  "\xd2\xf8\x43\x80\x8d\x86\x7d\x80"
+			  "\x1a\xd0\xcc\x13\xb9\x11\x05\x3f"
+			  "\x7e\xcf\x7e\x80\x0e\xd8\x25\x48"
+			  "\x8b\xaa\x63\x83\x92\xd0\x72\xf5"
+			  "\x4f\x67\x7e\x50\x18\x25\xa4\xd1"
+			  "\xe0\x7e\x1e\xba\xd8\xa7\x6e\xdb"
+			  "\x1a\xcc\x0d\xfe\x9f\x6d\x22\x35"
+			  "\xe1\xe6\xe0\xa8\x7b\x9c\xb1\x66"
+			  "\xa3\xf8\xff\x4d\x90\x84\x28\xbc"
+			  "\xdc\x19\xc7\x91\x49\xfc\xf6\x33"
+			  "\xc9\x6e\x65\x7f\x28\x6f\x68\x2e"
+			  "\xdf\x1a\x75\xe9\xc2\x0c\x96\xb9"
+			  "\x31\x22\xc4\x07\xc6\x0a\x2f\xfd"
+			  "\x36\x06\x5f\x5c\xc5\xb1\x3a\xf4"
+			  "\x5e\x48\xa4\x45\x2b\x88\xa7\xee"
+			  "\xa9\x8b\x52\xcc\x99\xd9\x2f\xb8"
+			  "\xa4\x58\x0a\x13\xeb\x71\x5a\xfa"
+			  "\xe5\x5e\xbe\xf2\x64\xad\x75\xbc"
+			  "\x0b\x5b\x34\x13\x3b\x23\x13\x9a"
+			  "\x69\x30\x1e\x9a\xb8\x03\xb8\x8b"
+			  "\x3e\x46\x18\x6d\x38\xd9\xb3\xd8"
+			  "\xbf\xf1\xd0\x28\xe6\x51\x57\x80"
+			  "\x5e\x99\xfb\xd0\xce\x1e\x83\xf7"
+			  "\xe9\x07\x5a\x63\xa9\xef\xce\xa5"
+			  "\xfb\x3f\x37\x17\xfc\x0b\x37\x0e"
+			  "\xbb\x4b\x21\x62\xb7\x83\x0e\xa9"
+			  "\x9e\xb0\xc4\xad\x47\xbe\x35\xe7"
+			  "\x51\xb2\xf2\xac\x2b\x65\x7b\x48"
+			  "\xe3\x3f\x5f\xb6\x09\x04\x0c\x58"
+			  "\xce\x99\xa9\x15\x2f\x4e\xc1\xf2"
+			  "\x24\x48\xc0\xd8\x6c\xd3\x76\x17"
+			  "\x83\x5d\xe6\xe3\xfd\x01\x8e\xf7"
+			  "\x42\xa5\x04\x29\x30\xdf\xf9\x00"
+			  "\x4a\xdc\x71\x22\x1a\x33\x15\xb6"
+			  "\xd7\x72\xfb\x9a\xb8\xeb\x2b\x38"
+			  "\xea\xa8\x61\xa8\x90\x11\x9d\x73"
+			  "\x2e\x6c\xce\x81\x54\x5a\x9f\xcd"
+			  "\xcf\xd5\xbd\x26\x5d\x66\xdb\xfb"
+			  "\xdc\x1e\x7c\x10\xfe\x58\x82\x10"
+			  "\x16\x24\x01\xce\x67\x55\x51\xd1"
+			  "\xdd\x6b\x44\xa3\x20\x8e\xa9\xa6"
+			  "\x06\xa8\x29\x77\x6e\x00\x38\x5b"
+			  "\xde\x4d\x58\xd8\x1f\x34\xdf\xf9"
+			  "\x2c\xac\x3e\xad\xfb\x92\x0d\x72"
+			  "\x39\xa4\xac\x44\x10\xc0\x43\xc4"
+			  "\xa4\x77\x3b\xfc\xc4\x0d\x37\xd3"
+			  "\x05\x84\xda\x53\x71\xf8\x80\xd3"
+			  "\x34\x44\xdb\x09\xb4\x2b\x8e\xe3"
+			  "\x00\x75\x50\x9e\x43\x22\x00\x0b"
+			  "\x7c\x70\xab\xd4\x41\xf1\x93\xcd"
+			  "\x25\x2d\x84\x74\xb5\xf2\x92\xcd"
+			  "\x0a\x28\xea\x9a\x49\x02\x96\xcb"
+			  "\x85\x9e\x2f\x33\x03\x86\x1d\xdc"
+			  "\x1d\x31\xd5\xfc\x9d\xaa\xc5\xe9"
+			  "\x9a\xc4\x57\xf5\x35\xed\xf4\x4b"
+			  "\x3d\x34\xc2\x29\x13\x86\x36\x42"
+			  "\x5d\xbf\x90\x86\x13\x77\xe5\xc3"
+			  "\x62\xb4\xfe\x0b\x70\x39\x35\x65"
+			  "\x02\xea\xf6\xce\x57\x0c\xbb\x74"
+			  "\x29\xe3\xfd\x60\x90\xfd\x10\x38"
+			  "\xd5\x4e\x86\xbd\x37\x70\xf0\x97"
+			  "\xa6\xab\x3b\x83\x64\x52\xca\x66"
+			  "\x2f\xf9\xa4\xca\x3a\x55\x6b\xb0"
+			  "\xe8\x3a\x34\xdb\x9e\x48\x50\x2f"
+			  "\x3b\xef\xfd\x08\x2d\x5f\xc1\x37"
+			  "\x5d\xbe\x73\xe4\xd8\xe9\xac\xca"
+			  "\x8a\xaa\x48\x7c\x5c\xf4\xa6\x96"
+			  "\x5f\xfa\x70\xa6\xb7\x8b\x50\xcb"
+			  "\xa6\xf5\xa9\xbd\x7b\x75\x4c\x22"
+			  "\x0b\x19\x40\x2e\xc9\x39\x39\x32"
+			  "\x83\x03\xa8\xa4\x98\xe6\x8e\x16"
+			  "\xb9\xde\x08\xc5\xfc\xbf\xad\x39"
+			  "\xa8\xc7\x93\x6c\x6f\x23\xaf\xc1"
+			  "\xab\xe1\xdf\xbb\x39\xae\x93\x29"
+			  "\x0e\x7d\x80\x8d\x3e\x65\xf3\xfd"
+			  "\x96\x06\x65\x90\xa1\x28\x64\x4b"
+			  "\x69\xf9\xa8\x84\x27\x50\xfc\x87"
+			  "\xf7\xbf\x55\x8e\x56\x13\x58\x7b"
+			  "\x85\xb4\x6a\x72\x0f\x40\xf1\x4f"
+			  "\x83\x81\x1f\x76\xde\x15\x64\x7a"
+			  "\x7a\x80\xe4\xc7\x5e\x63\x01\x91"
+			  "\xd7\x6b\xea\x0b\x9b\xa2\x99\x3b"
+			  "\x6c\x88\xd8\xfd\x59\x3c\x8d\x22"
+			  "\x86\x56\xbe\xab\xa1\x37\x08\x01"
+			  "\x50\x85\x69\x29\xee\x9f\xdf\x21"
+			  "\x3e\x20\x20\xf5\xb0\xbb\x6b\xd0"
+			  "\x9c\x41\x38\xec\x54\x6f\x2d\xbd"
+			  "\x0f\xe1\xbd\xf1\x2b\x6e\x60\x56"
+			  "\x29\xe5\x7a\x70\x1c\xe2\xfc\x97"
+			  "\x82\x68\x67\xd9\x3d\x1f\xfb\xd8"
+			  "\x07\x9f\xbf\x96\x74\xba\x6a\x0e"
+			  "\x10\x48\x20\xd8\x13\x1e\xb5\x44"
+			  "\xf2\xcc\xb1\x8b\xfb\xbb\xec\xd7"
+			  "\x37\x70\x1f\x7c\x55\xd2\x4b\xb9"
+			  "\xfd\x70\x5e\xa3\x91\x73\x63\x52"
+			  "\x13\x47\x5a\x06\xfb\x01\x67\xa5"
+			  "\xc0\xd0\x49\x19\x56\x66\x9a\x77"
+			  "\x64\xaf\x8c\x25\x91\x52\x87\x0e"
+			  "\x18\xf3\x5f\x97\xfd\x71\x13\xf8"
+			  "\x05\xa5\x39\xcc\x65\xd3\xcc\x63"
+			  "\x5b\xdb\x5f\x7e\x5f\x6e\xad\xc4"
+			  "\xf4\xa0\xc5\xc2\x2b\x4d\x97\x38"
+			  "\x4f\xbc\xfa\x33\x17\xb4\x47\xb9"
+			  "\x43\x24\x15\x8d\xd2\xed\x80\x68"
+			  "\x84\xdb\x04\x80\xca\x5e\x6a\x35"
+			  "\x2c\x2c\xe7\xc5\x03\x5f\x54\xb0"
+			  "\x5e\x4f\x1d\x40\x54\x3d\x78\x9a"
+			  "\xac\xda\x80\x27\x4d\x15\x4c\x1a"
+			  "\x6e\x80\xc9\xc4\x3b\x84\x0e\xd9"
+			  "\x2e\x93\x01\x8c\xc3\xc8\x91\x4b"
+			  "\xb3\xaa\x07\x04\x68\x5b\x93\xa5"
+			  "\xe7\xc4\x9d\xe7\x07\xee\xf5\x3b"
+			  "\x40\x89\xcc\x60\x34\x9d\xb4\x06"
+			  "\x1b\xef\x92\xe6\xc1\x2a\x7d\x0f"
+			  "\x81\xaa\x56\xe3\xd7\xed\xa7\xd4"
+			  "\xa7\x3a\x49\xc4\xad\x81\x5c\x83"
+			  "\x55\x8e\x91\x54\xb7\x7d\x65\xa5"
+			  "\x06\x16\xd5\x9a\x16\xc1\xb0\xa2"
+			  "\x06\xd8\x98\x47\x73\x7e\x73\xa0"
+			  "\xb8\x23\xb1\x52\xbf\x68\x74\x5d"
+			  "\x0b\xcb\xfa\x8c\x46\xe3\x24\xe6"
+			  "\xab\xd4\x69\x8d\x8c\xf2\x8a\x59"
+			  "\xbe\x48\x46\x50\x8c\x9a\xe8\xe3"
+			  "\x31\x55\x0a\x06\xed\x4f\xf8\xb7"
+			  "\x4f\xe3\x85\x17\x30\xbd\xd5\x20"
+			  "\xe7\x5b\xb2\x32\xcf\x6b\x16\x44"
+			  "\xd2\xf5\x7e\xd7\xd1\x2f\xee\x64"
+			  "\x3e\x9d\x10\xef\x27\x35\x43\x64"
+			  "\x67\xfb\x7a\x7b\xe0\x62\x31\x9a"
+			  "\x4d\xdf\xa5\xab\xc0\x20\xbb\x01"
+			  "\xe9\x7b\x54\xf1\xde\xb2\x79\x50"
+			  "\x6c\x4b\x91\xdb\x7f\xbb\x50\xc1"
+			  "\x55\x44\x38\x9a\xe0\x9f\xe8\x29"
+			  "\x6f\x15\xf8\x4e\xa6\xec\xa0\x60",
+		.ksize	= 1088,
+		.plaintext	= "\x15\x68\x9e\x2f\xad\x15\x52\xdf"
+			  "\xf0\x42\x62\x24\x2a\x2d\xea\xbf"
+			  "\xc7\xf3\xb4\x1a\xf5\xed\xb2\x08"
+			  "\x15\x60\x1c\x00\x77\xbf\x0b\x0e"
+			  "\xb7\x2c\xcf\x32\x3a\xc7\x01\x77"
+			  "\xef\xa6\x75\xd0\x29\xc7\x68\x20"
+			  "\xb2\x92\x25\xbf\x12\x34\xe9\xa4"
+			  "\xfd\x32\x7b\x3f\x7c\xbd\xa5\x02"
+			  "\x38\x41\xde\xc9\xc1\x09\xd9\xfc"
+			  "\x6e\x78\x22\x83\x18\xf7\x50\x8d"
+			  "\x8f\x9c\x2d\x02\xa5\x30\xac\xff"
+			  "\xea\x63\x2e\x80\x37\x83\xb0\x58"
+			  "\xda\x2f\xef\x21\x55\xba\x7b\xb1"
+			  "\xb6\xed\xf5\xd2\x4d\xaa\x8c\xa9"
+			  "\xdd\xdb\x0f\xb4\xce\xc1\x9a\xb1"
+			  "\xc1\xdc\xbd\xab\x86\xc2\xdf\x0b"
+			  "\xe1\x2c\xf9\xbe\xf6\xd8\xda\x62"
+			  "\x72\xdd\x98\x09\x52\xc0\xc4\xb6"
+			  "\x7b\x17\x5c\xf5\xd8\x4b\x88\xd6"
+			  "\x6b\xbf\x84\x4a\x3f\xf5\x4d\xd2"
+			  "\x94\xe2\x9c\xff\xc7\x3c\xd9\xc8"
+			  "\x37\x38\xbc\x8c\xf3\xe7\xb7\xd0"
+			  "\x1d\x78\xc4\x39\x07\xc8\x5e\x79"
+			  "\xb6\x5a\x90\x5b\x6e\x97\xc9\xd4"
+			  "\x82\x9c\xf3\x83\x7a\xe7\x97\xfc"
+			  "\x1d\xbb\xef\xdb\xce\xe0\x82\xad"
+			  "\xca\x07\x6c\x54\x62\x6f\x81\xe6"
+			  "\x7a\x5a\x96\x6e\x80\x3a\xa2\x37"
+			  "\x6f\xc6\xa4\x29\xc3\x9e\x19\x94"
+			  "\x9f\xb0\x3e\x38\xfb\x3c\x2b\x7d"
+			  "\xaa\xb8\x74\xda\x54\x23\x51\x12"
+			  "\x4b\x96\x36\x8f\x91\x4f\x19\x37"
+			  "\x83\xc9\xdd\xc7\x1a\x32\x2d\xab"
+			  "\xc7\x89\xe2\x07\x47\x6c\xe8\xa6"
+			  "\x70\x6b\x8e\x0c\xda\x5c\x6a\x59"
+			  "\x27\x33\x0e\xe1\xe1\x20\xe8\xc8"
+			  "\xae\xdc\xd0\xe3\x6d\xa8\xa6\x06"
+			  "\x41\xb4\xd4\xd4\xcf\x91\x3e\x06"
+			  "\xb0\x9a\xf7\xf1\xaa\xa6\x23\x92"
+			  "\x10\x86\xf0\x94\xd1\x7c\x2e\x07"
+			  "\x30\xfb\xc5\xd8\xf3\x12\xa9\xe8"
+			  "\x22\x1c\x97\x1a\xad\x96\xb0\xa1"
+			  "\x72\x6a\x6b\xb4\xfd\xf7\xe8\xfa"
+			  "\xe2\x74\xd8\x65\x8d\x35\x17\x4b"
+			  "\x00\x23\x5c\x8c\x70\xad\x71\xa2"
+			  "\xca\xc5\x6c\x59\xbf\xb4\xc0\x6d"
+			  "\x86\x98\x3e\x19\x5a\x90\x92\xb1"
+			  "\x66\x57\x6a\x91\x68\x7c\xbc\xf3"
+			  "\xf1\xdb\x94\xf8\x48\xf1\x36\xd8"
+			  "\x78\xac\x1c\xa9\xcc\xd6\x27\xba"
+			  "\x91\x54\x22\xf5\xe6\x05\x3f\xcc"
+			  "\xc2\x8f\x2c\x3b\x2b\xc3\x2b\x2b"
+			  "\x3b\xb8\xb6\x29\xb7\x2f\x94\xb6"
+			  "\x7b\xfc\x94\x3e\xd0\x7a\x41\x59"
+			  "\x7b\x1f\x9a\x09\xa6\xed\x4a\x82"
+			  "\x9d\x34\x1c\xbd\x4e\x1c\x3a\x66"
+			  "\x80\x74\x0e\x9a\x4f\x55\x54\x47"
+			  "\x16\xba\x2a\x0a\x03\x35\x99\xa3"
+			  "\x5c\x63\x8d\xa2\x72\x8b\x17\x15"
+			  "\x68\x39\x73\xeb\xec\xf2\xe8\xf5"
+			  "\x95\x32\x27\xd6\xc4\xfe\xb0\x51"
+			  "\xd5\x0c\x50\xc5\xcd\x6d\x16\xb3"
+			  "\xa3\x1e\x95\x69\xad\x78\x95\x06"
+			  "\xb9\x46\xf2\x6d\x24\x5a\x99\x76"
+			  "\x73\x6a\x91\xa6\xac\x12\xe1\x28"
+			  "\x79\xbc\x08\x4e\x97\x00\x98\x63"
+			  "\x07\x1c\x4e\xd1\x68\xf3\xb3\x81"
+			  "\xa8\xa6\x5f\xf1\x01\xc9\xc1\xaf"
+			  "\x3a\x96\xf9\x9d\xb5\x5a\x5f\x8f"
+			  "\x7e\xc1\x7e\x77\x0a\x40\xc8\x8e"
+			  "\xfc\x0e\xed\xe1\x0d\xb0\xe5\x5e"
+			  "\x5e\x6f\xf5\x7f\xab\x33\x7d\xcd"
+			  "\xf0\x09\x4b\xb2\x11\x37\xdc\x65"
+			  "\x97\x32\x62\x71\x3a\x29\x54\xb9"
+			  "\xc7\xa4\xbf\x75\x0f\xf9\x40\xa9"
+			  "\x8d\xd7\x8b\xa7\xe0\x9a\xbe\x15"
+			  "\xc6\xda\xd8\x00\x14\x69\x1a\xaf"
+			  "\x5f\x79\xc3\xf5\xbb\x6c\x2a\x9d"
+			  "\xdd\x3c\x5f\x97\x21\xe1\x3a\x03"
+			  "\x84\x6a\xe9\x76\x11\x1f\xd3\xd5"
+			  "\xf0\x54\x20\x4d\xc2\x91\xc3\xa4"
+			  "\x36\x25\xbe\x1b\x2a\x06\xb7\xf3"
+			  "\xd1\xd0\x55\x29\x81\x4c\x83\xa3"
+			  "\xa6\x84\x1e\x5c\xd1\xd0\x6c\x90"
+			  "\xa4\x11\xf0\xd7\x63\x6a\x48\x05"
+			  "\xbc\x48\x18\x53\xcd\xb0\x8d\xdb"
+			  "\xdc\xfe\x55\x11\x5c\x51\xb3\xab"
+			  "\xab\x63\x3e\x31\x5a\x8b\x93\x63"
+			  "\x34\xa9\xba\x2b\x69\x1a\xc0\xe3"
+			  "\xcb\x41\xbc\xd7\xf5\x7f\x82\x3e"
+			  "\x01\xa3\x3c\x72\xf4\xfe\xdf\xbe"
+			  "\xb1\x67\x17\x2b\x37\x60\x0d\xca"
+			  "\x6f\xc3\x94\x2c\xd2\x92\x6d\x9d"
+			  "\x75\x18\x77\xaa\x29\x38\x96\xed"
+			  "\x0e\x20\x70\x92\xd5\xd0\xb4\x00"
+			  "\xc0\x31\xf2\xc9\x43\x0e\x75\x1d"
+			  "\x4b\x64\xf2\x1f\xf2\x29\x6c\x7b"
+			  "\x7f\xec\x59\x7d\x8c\x0d\xd4\xd3"
+			  "\xac\x53\x4c\xa3\xde\x42\x92\x95"
+			  "\x6d\xa3\x4f\xd0\xe6\x3d\xe7\xec"
+			  "\x7a\x4d\x68\xf1\xfe\x67\x66\x09"
+			  "\x83\x22\xb1\x98\x43\x8c\xab\xb8"
+			  "\x45\xe6\x6d\xdf\x5e\x50\x71\xce"
+			  "\xf5\x4e\x40\x93\x2b\xfa\x86\x0e"
+			  "\xe8\x30\xbd\x82\xcc\x1c\x9c\x5f"
+			  "\xad\xfd\x08\x31\xbe\x52\xe7\xe6"
+			  "\xf2\x06\x01\x62\x25\x15\x99\x74"
+			  "\x33\x51\x52\x57\x3f\x57\x87\x61"
+			  "\xb9\x7f\x29\x3d\xcd\x92\x5e\xa6"
+			  "\x5c\x3b\xf1\xed\x5f\xeb\x82\xed"
+			  "\x56\x7b\x61\xe7\xfd\x02\x47\x0e"
+			  "\x2a\x15\xa4\xce\x43\x86\x9b\xe1"
+			  "\x2b\x4c\x2a\xd9\x42\x97\xf7\x9a"
+			  "\xe5\x47\x46\x48\xd3\x55\x6f\x4d"
+			  "\xd9\xeb\x4b\xdd\x7b\x21\x2f\xb3"
+			  "\xa8\x36\x28\xdf\xca\xf1\xf6\xd9"
+			  "\x10\xf6\x1c\xfd\x2e\x0c\x27\xe0"
+			  "\x01\xb3\xff\x6d\x47\x08\x4d\xd4"
+			  "\x00\x25\xee\x55\x4a\xe9\xe8\x5b"
+			  "\xd8\xf7\x56\x12\xd4\x50\xb2\xe5"
+			  "\x51\x6f\x34\x63\x69\xd2\x4e\x96"
+			  "\x4e\xbc\x79\xbf\x18\xae\xc6\x13"
+			  "\x80\x92\x77\xb0\xb4\x0f\x29\x94"
+			  "\x6f\x4c\xbb\x53\x11\x36\xc3\x9f"
+			  "\x42\x8e\x96\x8a\x91\xc8\xe9\xfc"
+			  "\xfe\xbf\x7c\x2d\x6f\xf9\xb8\x44"
+			  "\x89\x1b\x09\x53\x0a\x2a\x92\xc3"
+			  "\x54\x7a\x3a\xf9\xe2\xe4\x75\x87"
+			  "\xa0\x5e\x4b\x03\x7a\x0d\x8a\xf4"
+			  "\x55\x59\x94\x2b\x63\x96\x0e\xf5",
+		.psize	= 1040,
+		.digest	= "\xb5\xb9\x08\xb3\x24\x3e\x03\xf0"
+			  "\xd6\x0b\x57\xbc\x0a\x6d\x89\x59",
+	}, {
+		.key	= "\xf6\x34\x42\x71\x35\x52\x8b\x58"
+			  "\x02\x3a\x8e\x4a\x8d\x41\x13\xe9"
+			  "\x7f\xba\xb9\x55\x9d\x73\x4d\xf8"
+			  "\x3f\x5d\x73\x15\xff\xd3\x9e\x7f"
+			  "\x20\x2a\x6a\xa8\xd1\xf0\x8f\x12"
+			  "\x6b\x02\xd8\x6c\xde\xba\x80\x22"
+			  "\x19\x37\xc8\xd0\x4e\x89\x17\x7c"
+			  "\x7c\xdd\x88\xfd\x41\xc0\x04\xb7"
+			  "\x1d\xac\x19\xe3\x20\xc7\x16\xcf"
+			  "\x58\xee\x1d\x7a\x61\x69\xa9\x12"
+			  "\x4b\xef\x4f\xb6\x38\xdd\x78\xf8"
+			  "\x28\xee\x70\x08\xc7\x7c\xcc\xc8"
+			  "\x1e\x41\xf5\x80\x86\x70\xd0\xf0"
+			  "\xa3\x87\x6b\x0a\x00\xd2\x41\x28"
+			  "\x74\x26\xf1\x24\xf3\xd0\x28\x77"
+			  "\xd7\xcd\xf6\x2d\x61\xf4\xa2\x13"
+			  "\x77\xb4\x6f\xa0\xf4\xfb\xd6\xb5"
+			  "\x38\x9d\x5a\x0c\x51\xaf\xad\x63"
+			  "\x27\x67\x8c\x01\xea\x42\x1a\x66"
+			  "\xda\x16\x7c\x3c\x30\x0c\x66\x53"
+			  "\x1c\x88\xa4\x5c\xb2\xe3\x78\x0a"
+			  "\x13\x05\x6d\xe2\xaf\xb3\xe4\x75"
+			  "\x00\x99\x58\xee\x76\x09\x64\xaa"
+			  "\xbb\x2e\xb1\x81\xec\xd8\x0e\xd3"
+			  "\x0c\x33\x5d\xb7\x98\xef\x36\xb6"
+			  "\xd2\x65\x69\x41\x70\x12\xdc\x25"
+			  "\x41\x03\x99\x81\x41\x19\x62\x13"
+			  "\xd1\x0a\x29\xc5\x8c\xe0\x4c\xf3"
+			  "\xd6\xef\x4c\xf4\x1d\x83\x2e\x6d"
+			  "\x8e\x14\x87\xed\x80\xe0\xaa\xd3"
+			  "\x08\x04\x73\x1a\x84\x40\xf5\x64"
+			  "\xbd\x61\x32\x65\x40\x42\xfb\xb0"
+			  "\x40\xf6\x40\x8d\xc7\x7f\x14\xd0"
+			  "\x83\x99\xaa\x36\x7e\x60\xc6\xbf"
+			  "\x13\x8a\xf9\x21\xe4\x7e\x68\x87"
+			  "\xf3\x33\x86\xb4\xe0\x23\x7e\x0a"
+			  "\x21\xb1\xf5\xad\x67\x3c\x9c\x9d"
+			  "\x09\xab\xaf\x5f\xba\xe0\xd0\x82"
+			  "\x48\x22\x70\xb5\x6d\x53\xd6\x0e"
+			  "\xde\x64\x92\x41\xb0\xd3\xfb\xda"
+			  "\x21\xfe\xab\xea\x20\xc4\x03\x58"
+			  "\x18\x2e\x7d\x2f\x03\xa9\x47\x66"
+			  "\xdf\x7b\xa4\x6b\x34\x6b\x55\x9c"
+			  "\x4f\xd7\x9c\x47\xfb\xa9\x42\xec"
+			  "\x5a\x12\xfd\xfe\x76\xa0\x92\x9d"
+			  "\xfe\x1e\x16\xdd\x24\x2a\xe4\x27"
+			  "\xd5\xa9\xf2\x05\x4f\x83\xa2\xaf"
+			  "\xfe\xee\x83\x7a\xad\xde\xdf\x9a"
+			  "\x80\xd5\x81\x14\x93\x16\x7e\x46"
+			  "\x47\xc2\x14\xef\x49\x6e\xb9\xdb"
+			  "\x40\xe8\x06\x6f\x9c\x2a\xfd\x62"
+			  "\x06\x46\xfd\x15\x1d\x36\x61\x6f"
+			  "\x77\x77\x5e\x64\xce\x78\x1b\x85"
+			  "\xbf\x50\x9a\xfd\x67\xa6\x1a\x65"
+			  "\xad\x5b\x33\x30\xf1\x71\xaa\xd9"
+			  "\x23\x0d\x92\x24\x5f\xae\x57\xb0"
+			  "\x24\x37\x0a\x94\x12\xfb\xb5\xb1"
+			  "\xd3\xb8\x1d\x12\x29\xb0\x80\x24"
+			  "\x2d\x47\x9f\x96\x1f\x95\xf1\xb1"
+			  "\xda\x35\xf6\x29\xe0\xe1\x23\x96"
+			  "\xc7\xe8\x22\x9b\x7c\xac\xf9\x41"
+			  "\x39\x01\xe5\x73\x15\x5e\x99\xec"
+			  "\xb4\xc1\xf4\xe7\xa7\x97\x6a\xd5"
+			  "\x90\x9a\xa0\x1d\xf3\x5a\x8b\x5f"
+			  "\xdf\x01\x52\xa4\x93\x31\x97\xb0"
+			  "\x93\x24\xb5\xbc\xb2\x14\x24\x98"
+			  "\x4a\x8f\x19\x85\xc3\x2d\x0f\x74"
+			  "\x9d\x16\x13\x80\x5e\x59\x62\x62"
+			  "\x25\xe0\xd1\x2f\x64\xef\xba\xac"
+			  "\xcd\x09\x07\x15\x8a\xcf\x73\xb5"
+			  "\x8b\xc9\xd8\x24\xb0\x53\xd5\x6f"
+			  "\xe1\x2b\x77\xb1\xc5\xe4\xa7\x0e"
+			  "\x18\x45\xab\x36\x03\x59\xa8\xbd"
+			  "\x43\xf0\xd8\x2c\x1a\x69\x96\xbb"
+			  "\x13\xdf\x6c\x33\x77\xdf\x25\x34"
+			  "\x5b\xa5\x5b\x8c\xf9\x51\x05\xd4"
+			  "\x8b\x8b\x44\x87\x49\xfc\xa0\x8f"
+			  "\x45\x15\x5b\x40\x42\xc4\x09\x92"
+			  "\x98\x0c\x4d\xf4\x26\x37\x1b\x13"
+			  "\x76\x01\x93\x8d\x4f\xe6\xed\x18"
+			  "\xd0\x79\x7b\x3f\x44\x50\xcb\xee"
+			  "\xf7\x4a\xc9\x9e\xe0\x96\x74\xa7"
+			  "\xe6\x93\xb2\x53\xca\x55\xa8\xdc"
+			  "\x1e\x68\x07\x87\xb7\x2e\xc1\x08"
+			  "\xb2\xa4\x5b\xaf\xc6\xdb\x5c\x66"
+			  "\x41\x1c\x51\xd9\xb0\x07\x00\x0d"
+			  "\xf0\x4c\xdc\x93\xde\xa9\x1e\x8e"
+			  "\xd3\x22\x62\xd8\x8b\x88\x2c\xea"
+			  "\x5e\xf1\x6e\x14\x40\xc7\xbe\xaa"
+			  "\x42\x28\xd0\x26\x30\x78\x01\x9b"
+			  "\x83\x07\xbc\x94\xc7\x57\xa2\x9f"
+			  "\x03\x07\xff\x16\xff\x3c\x6e\x48"
+			  "\x0a\xd0\xdd\x4c\xf6\x64\x9a\xf1"
+			  "\xcd\x30\x12\x82\x2c\x38\xd3\x26"
+			  "\x83\xdb\xab\x3e\xc6\xf8\xe6\xfa"
+			  "\x77\x0a\x78\x82\x75\xf8\x63\x51"
+			  "\x59\xd0\x8d\x24\x9f\x25\xe6\xa3"
+			  "\x4c\xbc\x34\xfc\xe3\x10\xc7\x62"
+			  "\xd4\x23\xc8\x3d\xa7\xc6\xa6\x0a"
+			  "\x4f\x7e\x29\x9d\x6d\xbe\xb5\xf1"
+			  "\xdf\xa4\x53\xfa\xc0\x23\x0f\x37"
+			  "\x84\x68\xd0\xb5\xc8\xc6\xae\xf8"
+			  "\xb7\x8d\xb3\x16\xfe\x8f\x87\xad"
+			  "\xd0\xc1\x08\xee\x12\x1c\x9b\x1d"
+			  "\x90\xf8\xd1\x63\xa4\x92\x3c\xf0"
+			  "\xc7\x34\xd8\xf1\x14\xed\xa3\xbc"
+			  "\x17\x7e\xd4\x62\x42\x54\x57\x2c"
+			  "\x3e\x7a\x35\x35\x17\x0f\x0b\x7f"
+			  "\x81\xa1\x3f\xd0\xcd\xc8\x3b\x96"
+			  "\xe9\xe0\x4a\x04\xe1\xb6\x3c\xa1"
+			  "\xd6\xca\xc4\xbd\xb6\xb5\x95\x34"
+			  "\x12\x9d\xc5\x96\xf2\xdf\xba\x54"
+			  "\x76\xd1\xb2\x6b\x3b\x39\xe0\xb9"
+			  "\x18\x62\xfb\xf7\xfc\x12\xf1\x5f"
+			  "\x7e\xc7\xe3\x59\x4c\xa6\xc2\x3d"
+			  "\x40\x15\xf9\xa3\x95\x64\x4c\x74"
+			  "\x8b\x73\x77\x33\x07\xa7\x04\x1d"
+			  "\x33\x5a\x7e\x8f\xbd\x86\x01\x4f"
+			  "\x3e\xb9\x27\x6f\xe2\x41\xf7\x09"
+			  "\x67\xfd\x29\x28\xc5\xe4\xf6\x18"
+			  "\x4c\x1b\x49\xb2\x9c\x5b\xf6\x81"
+			  "\x4f\xbb\x5c\xcc\x0b\xdf\x84\x23"
+			  "\x58\xd6\x28\x34\x93\x3a\x25\x97"
+			  "\xdf\xb2\xc3\x9e\x97\x38\x0b\x7d"
+			  "\x10\xb3\x54\x35\x23\x8c\x64\xee"
+			  "\xf0\xd8\x66\xff\x8b\x22\xd2\x5b"
+			  "\x05\x16\x3c\x89\xf7\xb1\x75\xaf"
+			  "\xc0\xae\x6a\x4f\x3f\xaf\x9a\xf4"
+			  "\xf4\x9a\x24\xd9\x80\x82\xc0\x12"
+			  "\xde\x96\xd1\xbe\x15\x0b\x8d\x6a"
+			  "\xd7\x12\xe4\x85\x9f\x83\xc9\xc3"
+			  "\xff\x0b\xb5\xaf\x3b\xd8\x6d\x67"
+			  "\x81\x45\xe6\xac\xec\xc1\x7b\x16"
+			  "\x18\x0a\xce\x4b\xc0\x2e\x76\xbc"
+			  "\x1b\xfa\xb4\x34\xb8\xfc\x3e\xc8"
+			  "\x5d\x90\x71\x6d\x7a\x79\xef\x06",
+		.ksize	= 1088,
+		.plaintext	= "\xaa\x5d\x54\xcb\xea\x1e\x46\x0f"
+			  "\x45\x87\x70\x51\x8a\x66\x7a\x33"
+			  "\xb4\x18\xff\xa9\x82\xf9\x45\x4b"
+			  "\x93\xae\x2e\x7f\xab\x98\xfe\xbf"
+			  "\x01\xee\xe5\xa0\x37\x8f\x57\xa6"
+			  "\xb0\x76\x0d\xa4\xd6\x28\x2b\x5d"
+			  "\xe1\x03\xd6\x1c\x6f\x34\x0d\xe7"
+			  "\x61\x2d\x2e\xe5\xae\x5d\x47\xc7"
+			  "\x80\x4b\x18\x8f\xa8\x99\xbc\x28"
+			  "\xed\x1d\x9d\x86\x7d\xd7\x41\xd1"
+			  "\xe0\x2b\xe1\x8c\x93\x2a\xa7\x80"
+			  "\xe1\x07\xa0\xa9\x9f\x8c\x8d\x1a"
+			  "\x55\xfc\x6b\x24\x7a\xbd\x3e\x51"
+			  "\x68\x4b\x26\x59\xc8\xa7\x16\xd9"
+			  "\xb9\x61\x13\xde\x8b\x63\x1c\xf6"
+			  "\x60\x01\xfb\x08\xb3\x5b\x0a\xbf"
+			  "\x34\x73\xda\x87\x87\x3d\x6f\x97"
+			  "\x4a\x0c\xa3\x58\x20\xa2\xc0\x81"
+			  "\x5b\x8c\xef\xa9\xc2\x01\x1e\x64"
+			  "\x83\x8c\xbc\x03\xb6\xd0\x29\x9f"
+			  "\x54\xe2\xce\x8b\xc2\x07\x85\x78"
+			  "\x25\x38\x96\x4c\xb4\xbe\x17\x4a"
+			  "\x65\xa6\xfa\x52\x9d\x66\x9d\x65"
+			  "\x4a\xd1\x01\x01\xf0\xcb\x13\xcc"
+			  "\xa5\x82\xf3\xf2\x66\xcd\x3f\x9d"
+			  "\xd1\xaa\xe4\x67\xea\xf2\xad\x88"
+			  "\x56\x76\xa7\x9b\x59\x3c\xb1\x5d"
+			  "\x78\xfd\x69\x79\x74\x78\x43\x26"
+			  "\x7b\xde\x3f\xf1\xf5\x4e\x14\xd9"
+			  "\x15\xf5\x75\xb5\x2e\x19\xf3\x0c"
+			  "\x48\x72\xd6\x71\x6d\x03\x6e\xaa"
+			  "\xa7\x08\xf9\xaa\x70\xa3\x0f\x4d"
+			  "\x12\x8a\xdd\xe3\x39\x73\x7e\xa7"
+			  "\xea\x1f\x6d\x06\x26\x2a\xf2\xc5"
+			  "\x52\xb4\xbf\xfd\x52\x0c\x06\x60"
+			  "\x90\xd1\xb2\x7b\x56\xae\xac\x58"
+			  "\x5a\x6b\x50\x2a\xf5\xe0\x30\x3c"
+			  "\x2a\x98\x0f\x1b\x5b\x0a\x84\x6c"
+			  "\x31\xae\x92\xe2\xd4\xbb\x7f\x59"
+			  "\x26\x10\xb9\x89\x37\x68\x26\xbf"
+			  "\x41\xc8\x49\xc4\x70\x35\x7d\xff"
+			  "\x2d\x7f\xf6\x8a\x93\x68\x8c\x78"
+			  "\x0d\x53\xce\x7d\xff\x7d\xfb\xae"
+			  "\x13\x1b\x75\xc4\x78\xd7\x71\xd8"
+			  "\xea\xd3\xf4\x9d\x95\x64\x8e\xb4"
+			  "\xde\xb8\xe4\xa6\x68\xc8\xae\x73"
+			  "\x58\xaf\xa8\xb0\x5a\x20\xde\x87"
+			  "\x43\xb9\x0f\xe3\xad\x41\x4b\xd5"
+			  "\xb7\xad\x16\x00\xa6\xff\xf6\x74"
+			  "\xbf\x8c\x9f\xb3\x58\x1b\xb6\x55"
+			  "\xa9\x90\x56\x28\xf0\xb5\x13\x4e"
+			  "\x9e\xf7\x25\x86\xe0\x07\x7b\x98"
+			  "\xd8\x60\x5d\x38\x95\x3c\xe4\x22"
+			  "\x16\x2f\xb2\xa2\xaf\xe8\x90\x17"
+			  "\xec\x11\x83\x1a\xf4\xa9\x26\xda"
+			  "\x39\x72\xf5\x94\x61\x05\x51\xec"
+			  "\xa8\x30\x8b\x2c\x13\xd0\x72\xac"
+			  "\xb9\xd2\xa0\x4c\x4b\x78\xe8\x6e"
+			  "\x04\x85\xe9\x04\x49\x82\x91\xff"
+			  "\x89\xe5\xab\x4c\xaa\x37\x03\x12"
+			  "\xca\x8b\x74\x10\xfd\x9e\xd9\x7b"
+			  "\xcb\xdb\x82\x6e\xce\x2e\x33\x39"
+			  "\xce\xd2\x84\x6e\x34\x71\x51\x6e"
+			  "\x0d\xd6\x01\x87\xc7\xfa\x0a\xd3"
+			  "\xad\x36\xf3\x4c\x9f\x96\x5e\x62"
+			  "\x62\x54\xc3\x03\x78\xd6\xab\xdd"
+			  "\x89\x73\x55\x25\x30\xf8\xa7\xe6"
+			  "\x4f\x11\x0c\x7c\x0a\xa1\x2b\x7b"
+			  "\x3d\x0d\xde\x81\xd4\x9d\x0b\xae"
+			  "\xdf\x00\xf9\x4c\xb6\x90\x8e\x16"
+			  "\xcb\x11\xc8\xd1\x2e\x73\x13\x75"
+			  "\x75\x3e\xaa\xf5\xee\x02\xb3\x18"
+			  "\xa6\x2d\xf5\x3b\x51\xd1\x1f\x47"
+			  "\x6b\x2c\xdb\xc4\x10\xe0\xc8\xba"
+			  "\x9d\xac\xb1\x9d\x75\xd5\x41\x0e"
+			  "\x7e\xbe\x18\x5b\xa4\x1f\xf8\x22"
+			  "\x4c\xc1\x68\xda\x6d\x51\x34\x6c"
+			  "\x19\x59\xec\xb5\xb1\xec\xa7\x03"
+			  "\xca\x54\x99\x63\x05\x6c\xb1\xac"
+			  "\x9c\x31\xd6\xdb\xba\x7b\x14\x12"
+			  "\x7a\xc3\x2f\xbf\x8d\xdc\x37\x46"
+			  "\xdb\xd2\xbc\xd4\x2f\xab\x30\xd5"
+			  "\xed\x34\x99\x8e\x83\x3e\xbe\x4c"
+			  "\x86\x79\x58\xe0\x33\x8d\x9a\xb8"
+			  "\xa9\xa6\x90\x46\xa2\x02\xb8\xdd"
+			  "\xf5\xf9\x1a\x5c\x8c\x01\xaa\x6e"
+			  "\xb4\x22\x12\xf5\x0c\x1b\x9b\x7a"
+			  "\xc3\x80\xf3\x06\x00\x5f\x30\xd5"
+			  "\x06\xdb\x7d\x82\xc2\xd4\x0b\x4c"
+			  "\x5f\xe9\xc5\xf5\xdf\x97\x12\xbf"
+			  "\x56\xaf\x9b\x69\xcd\xee\x30\xb4"
+			  "\xa8\x71\xff\x3e\x7d\x73\x7a\xb4"
+			  "\x0d\xa5\x46\x7a\xf3\xf4\x15\x87"
+			  "\x5d\x93\x2b\x8c\x37\x64\xb5\xdd"
+			  "\x48\xd1\xe5\x8c\xae\xd4\xf1\x76"
+			  "\xda\xf4\xba\x9e\x25\x0e\xad\xa3"
+			  "\x0d\x08\x7c\xa8\x82\x16\x8d\x90"
+			  "\x56\x40\x16\x84\xe7\x22\x53\x3a"
+			  "\x58\xbc\xb9\x8f\x33\xc8\xc2\x84"
+			  "\x22\xe6\x0d\xe7\xb3\xdc\x5d\xdf"
+			  "\xd7\x2a\x36\xe4\x16\x06\x07\xd2"
+			  "\x97\x60\xb2\xf5\x5e\x14\xc9\xfd"
+			  "\x8b\x05\xd1\xce\xee\x9a\x65\x99"
+			  "\xb7\xae\x19\xb7\xc8\xbc\xd5\xa2"
+			  "\x7b\x95\xe1\xcc\xba\x0d\xdc\x8a"
+			  "\x1d\x59\x52\x50\xaa\x16\x02\x82"
+			  "\xdf\x61\x33\x2e\x44\xce\x49\xc7"
+			  "\xe5\xc6\x2e\x76\xcf\x80\x52\xf0"
+			  "\x3d\x17\x34\x47\x3f\xd3\x80\x48"
+			  "\xa2\xba\xd5\xc7\x7b\x02\x28\xdb"
+			  "\xac\x44\xc7\x6e\x05\x5c\xc2\x79"
+			  "\xb3\x7d\x6a\x47\x77\x66\xf1\x38"
+			  "\xf0\xf5\x4f\x27\x1a\x31\xca\x6c"
+			  "\x72\x95\x92\x8e\x3f\xb0\xec\x1d"
+			  "\xc7\x2a\xff\x73\xee\xdf\x55\x80"
+			  "\x93\xd2\xbd\x34\xd3\x9f\x00\x51"
+			  "\xfb\x2e\x41\xba\x6c\x5a\x7c\x17"
+			  "\x7f\xe6\x70\xac\x8d\x39\x3f\x77"
+			  "\xe2\x23\xac\x8f\x72\x4e\xe4\x53"
+			  "\xcc\xf1\x1b\xf1\x35\xfe\x52\xa4"
+			  "\xd6\xb8\x40\x6b\xc1\xfd\xa0\xa1"
+			  "\xf5\x46\x65\xc2\x50\xbb\x43\xe2"
+			  "\xd1\x43\x28\x34\x74\xf5\x87\xa0"
+			  "\xf2\x5e\x27\x3b\x59\x2b\x3e\x49"
+			  "\xdf\x46\xee\xaf\x71\xd7\x32\x36"
+			  "\xc7\x14\x0b\x58\x6e\x3e\x2d\x41"
+			  "\xfa\x75\x66\x3a\x54\xe0\xb2\xb9"
+			  "\xaf\xdd\x04\x80\x15\x19\x3f\x6f"
+			  "\xce\x12\xb4\xd8\xe8\x89\x3c\x05"
+			  "\x30\xeb\xf3\x3d\xcd\x27\xec\xdc"
+			  "\x56\x70\x12\xcf\x78\x2b\x77\xbf"
+			  "\x22\xf0\x1b\x17\x9c\xcc\xd6\x1b"
+			  "\x2d\x3d\xa0\x3b\xd8\xc9\x70\xa4"
+			  "\x7a\x3e\x07\xb9\x06\xc3\xfa\xb0"
+			  "\x33\xee\xc1\xd8\xf6\xe0\xf0\xb2"
+			  "\x61\x12\x69\xb0\x5f\x28\x99\xda"
+			  "\xc3\x61\x48\xfa\x07\x16\x03\xc4"
+			  "\xa8\xe1\x3c\xe8\x0e\x64\x15\x30"
+			  "\xc1\x9d\x84\x2f\x73\x98\x0e\x3a"
+			  "\xf2\x86\x21\xa4\x9e\x1d\xb5\x86"
+			  "\x16\xdb\x2b\x9a\x06\x64\x8e\x79"
+			  "\x8d\x76\x3e\xc3\xc2\x64\x44\xe3"
+			  "\xda\xbc\x1a\x52\xd7\x61\x03\x65"
+			  "\x54\x32\x77\x01\xed\x9d\x8a\x43"
+			  "\x25\x24\xe3\xc1\xbe\xb8\x2f\xcb"
+			  "\x89\x14\x64\xab\xf6\xa0\x6e\x02"
+			  "\x57\xe4\x7d\xa9\x4e\x9a\x03\x36"
+			  "\xad\xf1\xb1\xfc\x0b\xe6\x79\x51"
+			  "\x9f\x81\x77\xc4\x14\x78\x9d\xbf"
+			  "\xb6\xd6\xa3\x8c\xba\x0b\x26\xe7"
+			  "\xc8\xb9\x5c\xcc\xe1\x5f\xd5\xc6"
+			  "\xc4\xca\xc2\xa3\x45\xba\x94\x13"
+			  "\xb2\x8f\xc3\x54\x01\x09\xe7\x8b"
+			  "\xda\x2a\x0a\x11\x02\x43\xcb\x57"
+			  "\xc9\xcc\xb5\x5c\xab\xc4\xec\x54"
+			  "\x00\x06\x34\xe1\x6e\x03\x89\x7c"
+			  "\xc6\xfb\x6a\xc7\x60\x43\xd6\xc5"
+			  "\xb5\x68\x72\x89\x8f\x42\xc3\x74"
+			  "\xbd\x25\xaa\x9f\x67\xb5\xdf\x26"
+			  "\x20\xe8\xb7\x01\x3c\xe4\x77\xce"
+			  "\xc4\x65\xa7\x23\x79\xea\x33\xc7"
+			  "\x82\x14\x5c\x82\xf2\x4e\x3d\xf6"
+			  "\xc6\x4a\x0e\x29\xbb\xec\x44\xcd"
+			  "\x2f\xd1\x4f\x21\x71\xa9\xce\x0f"
+			  "\x5c\xf2\x72\x5c\x08\x2e\x21\xd2"
+			  "\xc3\x29\x13\xd8\xac\xc3\xda\x13"
+			  "\x1a\x9d\xa7\x71\x1d\x27\x1d\x27"
+			  "\x1d\xea\xab\x44\x79\xad\xe5\xeb"
+			  "\xef\x1f\x22\x0a\x44\x4f\xcb\x87"
+			  "\xa7\x58\x71\x0e\x66\xf8\x60\xbf"
+			  "\x60\x74\x4a\xb4\xec\x2e\xfe\xd3"
+			  "\xf5\xb8\xfe\x46\x08\x50\x99\x6c"
+			  "\x66\xa5\xa8\x34\x44\xb5\xe5\xf0"
+			  "\xdd\x2c\x67\x4e\x35\x96\x8e\x67"
+			  "\x48\x3f\x5f\x37\x44\x60\x51\x2e"
+			  "\x14\x91\x5e\x57\xc3\x0e\x79\x77"
+			  "\x2f\x03\xf4\xe2\x1c\x72\xbf\x85"
+			  "\x5d\xd3\x17\xdf\x6c\xc5\x70\x24"
+			  "\x42\xdf\x51\x4e\x2a\xb2\xd2\x5b"
+			  "\x9e\x69\x83\x41\x11\xfe\x73\x22"
+			  "\xde\x8a\x9e\xd8\x8a\xfb\x20\x38"
+			  "\xd8\x47\x6f\xd5\xed\x8f\x41\xfd"
+			  "\x13\x7a\x18\x03\x7d\x0f\xcd\x7d"
+			  "\xa6\x7d\x31\x9e\xf1\x8f\x30\xa3"
+			  "\x8b\x4c\x24\xb7\xf5\x48\xd7\xd9"
+			  "\x12\xe7\x84\x97\x5c\x31\x6d\xfb"
+			  "\xdf\xf3\xd3\xd1\xd5\x0c\x30\x06"
+			  "\x01\x6a\xbc\x6c\x78\x7b\xa6\x50"
+			  "\xfa\x0f\x3c\x42\x2d\xa5\xa3\x3b"
+			  "\xcf\x62\x50\xff\x71\x6d\xe7\xda"
+			  "\x27\xab\xc6\x67\x16\x65\x68\x64"
+			  "\xc7\xd5\x5f\x81\xa9\xf6\x65\xb3"
+			  "\x5e\x43\x91\x16\xcd\x3d\x55\x37"
+			  "\x55\xb3\xf0\x28\xc5\x54\x19\xc0"
+			  "\xe0\xd6\x2a\x61\xd4\xc8\x72\x51"
+			  "\xe9\xa1\x7b\x48\x21\xad\x44\x09"
+			  "\xe4\x01\x61\x3c\x8a\x5b\xf9\xa1"
+			  "\x6e\x1b\xdf\xc0\x04\xa8\x8b\xf2"
+			  "\x21\xbe\x34\x7b\xfc\xa1\xcd\xc9"
+			  "\xa9\x96\xf4\xa4\x4c\xf7\x4e\x8f"
+			  "\x84\xcc\xd3\xa8\x92\x77\x8f\x36"
+			  "\xe2\x2e\x8c\x33\xe8\x84\xa6\x0c"
+			  "\x6c\x8a\xda\x14\x32\xc2\x96\xff"
+			  "\xc6\x4a\xc2\x9b\x30\x7f\xd1\x29"
+			  "\xc0\xd5\x78\x41\x00\x80\x80\x03"
+			  "\x2a\xb1\xde\x26\x03\x48\x49\xee"
+			  "\x57\x14\x76\x51\x3c\x36\x5d\x0a"
+			  "\x5c\x9f\xe8\xd8\x53\xdb\x4f\xd4"
+			  "\x38\xbf\x66\xc9\x75\x12\x18\x75"
+			  "\x34\x2d\x93\x22\x96\x51\x24\x6e"
+			  "\x4e\xd9\x30\xea\x67\xff\x92\x1c"
+			  "\x16\x26\xe9\xb5\x33\xab\x8c\x22"
+			  "\x47\xdb\xa0\x2c\x08\xf0\x12\x69"
+			  "\x7e\x93\x52\xda\xa5\xe5\xca\xc1"
+			  "\x0f\x55\x2a\xbd\x09\x30\x88\x1b"
+			  "\x9c\xc6\x9f\xe6\xdb\xa6\x92\xeb"
+			  "\xf4\xbd\x5c\xc4\xdb\xc6\x71\x09"
+			  "\xab\x5e\x48\x0c\xed\x6f\xda\x8e"
+			  "\x8d\x0c\x98\x71\x7d\x10\xd0\x9c"
+			  "\x20\x9b\x79\x53\x26\x5d\xb9\x85"
+			  "\x8a\x31\xb8\xc5\x1c\x97\xde\x88"
+			  "\x61\x55\x7f\x7c\x21\x06\xea\xc4"
+			  "\x5f\xaf\xf2\xf0\xd5\x5e\x7d\xb4"
+			  "\x6e\xcf\xe9\xae\x1b\x0e\x11\x80"
+			  "\xc1\x9a\x74\x7e\x52\x6f\xa0\xb7"
+			  "\x24\xcd\x8d\x0a\x11\x40\x63\x72"
+			  "\xfa\xe2\xc5\xb3\x94\xef\x29\xa2"
+			  "\x1a\x23\x43\x04\x37\x55\x0d\xe9"
+			  "\x83\xb2\x29\x51\x49\x64\xa0\xbd"
+			  "\xde\x73\xfd\xa5\x7c\x95\x70\x62"
+			  "\x58\xdc\xe2\xd0\xbf\x98\xf5\x8a"
+			  "\x6a\xfd\xce\xa8\x0e\x42\x2a\xeb"
+			  "\xd2\xff\x83\x27\x53\x5c\xa0\x6e"
+			  "\x93\xef\xe2\xb9\x5d\x35\xd6\x98"
+			  "\xf6\x71\x19\x7a\x54\xa1\xa7\xe8"
+			  "\x09\xfe\xf6\x9e\xc7\xbd\x3e\x29"
+			  "\xbd\x6b\x17\xf4\xe7\x3e\x10\x5c"
+			  "\xc1\xd2\x59\x4f\x4b\x12\x1a\x5b"
+			  "\x50\x80\x59\xb9\xec\x13\x66\xa8"
+			  "\xd2\x31\x7b\x6a\x61\x22\xdd\x7d"
+			  "\x61\xee\x87\x16\x46\x9f\xf9\xc7"
+			  "\x41\xee\x74\xf8\xd0\x96\x2c\x76"
+			  "\x2a\xac\x7d\x6e\x9f\x0e\x7f\x95"
+			  "\xfe\x50\x16\xb2\x23\xca\x62\xd5"
+			  "\x68\xcf\x07\x3f\x3f\x97\x85\x2a"
+			  "\x0c\x25\x45\xba\xdb\x32\xcb\x83"
+			  "\x8c\x4f\xe0\x6d\x9a\x99\xf9\xc9"
+			  "\xda\xd4\x19\x31\xc1\x7c\x6d\xd9"
+			  "\x9c\x56\xd3\xec\xc1\x81\x4c\xed"
+			  "\x28\x9d\x87\xeb\x19\xd7\x1a\x4f"
+			  "\x04\x6a\xcb\x1f\xcf\x1f\xa2\x16"
+			  "\xfc\x2a\x0d\xa1\x14\x2d\xfa\xc5"
+			  "\x5a\xd2\xc5\xf9\x19\x7c\x20\x1f"
+			  "\x2d\x10\xc0\x66\x7c\xd9\x2d\xe5"
+			  "\x88\x70\x59\xa7\x85\xd5\x2e\x7c"
+			  "\x5c\xe3\xb7\x12\xd6\x97\x3f\x29",
+		.psize	= 2048,
+		.digest	= "\x37\x90\x92\xc2\xeb\x01\x87\xd9"
+			  "\x95\xc7\x91\xc3\x17\x8b\x38\x52",
+	}
+};
+
+
 /*
  * DES test vectors.
  */
diff --git a/include/crypto/nhpoly1305.h b/include/crypto/nhpoly1305.h
new file mode 100644
index 0000000000000..06bfb876a1563
--- /dev/null
+++ b/include/crypto/nhpoly1305.h
@@ -0,0 +1,74 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Common values and helper functions for the NHPoly1305 hash function.
+ */
+
+#ifndef _NHPOLY1305_H
+#define _NHPOLY1305_H
+
+#include <crypto/hash.h>
+#include <crypto/poly1305.h>
+
+/* NH parameterization: */
+
+/* Endianness: little */
+/* Word size: 32 bits (works well on NEON, SSE2, AVX2) */
+
+/* Stride: 2 words (optimal on ARM32 NEON; works okay on other CPUs too) */
+#define NH_PAIR_STRIDE		2
+#define NH_MESSAGE_UNIT		(NH_PAIR_STRIDE * 2 * sizeof(u32))
+
+/* Num passes (Toeplitz iteration count): 4, to give ε = 2^{-128} */
+#define NH_NUM_PASSES		4
+#define NH_HASH_BYTES		(NH_NUM_PASSES * sizeof(u64))
+
+/* Max message size: 1024 bytes (32x compression factor) */
+#define NH_NUM_STRIDES		64
+#define NH_MESSAGE_WORDS	(NH_PAIR_STRIDE * 2 * NH_NUM_STRIDES)
+#define NH_MESSAGE_BYTES	(NH_MESSAGE_WORDS * sizeof(u32))
+#define NH_KEY_WORDS		(NH_MESSAGE_WORDS + \
+				 NH_PAIR_STRIDE * 2 * (NH_NUM_PASSES - 1))
+#define NH_KEY_BYTES		(NH_KEY_WORDS * sizeof(u32))
+
+#define NHPOLY1305_KEY_SIZE	(POLY1305_BLOCK_SIZE + NH_KEY_BYTES)
+
+struct nhpoly1305_key {
+	struct poly1305_key poly_key;
+	u32 nh_key[NH_KEY_WORDS];
+};
+
+struct nhpoly1305_state {
+
+	/* Running total of polynomial evaluation */
+	struct poly1305_state poly_state;
+
+	/* Partial block buffer */
+	u8 buffer[NH_MESSAGE_UNIT];
+	unsigned int buflen;
+
+	/*
+	 * Number of bytes remaining until the current NH message reaches
+	 * NH_MESSAGE_BYTES.  When nonzero, 'nh_hash' holds the partial NH hash.
+	 */
+	unsigned int nh_remaining;
+
+	__le64 nh_hash[NH_NUM_PASSES];
+};
+
+typedef void (*nh_t)(const u32 *key, const u8 *src, size_t srclen,
+		     __le64 hash[NH_NUM_PASSES]);
+
+int crypto_nhpoly1305_setkey(struct crypto_shash *tfm,
+			     const u8 *key, unsigned int keylen);
+
+int crypto_nhpoly1305_init(struct shash_desc *desc);
+int crypto_nhpoly1305_update(struct shash_desc *desc,
+			     const u8 *src, unsigned int srclen);
+int crypto_nhpoly1305_update_helper(struct shash_desc *desc,
+				    const u8 *src, unsigned int srclen,
+				    nh_t nh_fn);
+int crypto_nhpoly1305_final(struct shash_desc *desc, u8 *dst);
+int crypto_nhpoly1305_final_helper(struct shash_desc *desc, u8 *dst,
+				   nh_t nh_fn);
+
+#endif /* _NHPOLY1305_H */