Mailing List Archive

[PATCH 3/4] Add x86 HW acceleration for GCM-SIV counter mode
* cipher/cipher-gcm-siv.c (do_ctr_le32): Use bulk function if
available.
* cipher/cipher-internal.h (cipher_bulk_ops): Add 'ctr32le_enc'.
* cipher/rijndael-aesni.c (_gcry_aes_aesni_ctr32le_enc): New.
* cipher/rijndael-vaes-avx2-amd64.S
(_gcry_vaes_avx2_ctr32le_enc_amd64, .Lle_addd_*): New.
* cipher/rijndael-vaes.c (_gcry_vaes_avx2_ctr32le_enc_amd64)
(_gcry_aes_vaes_ctr32le_enc): New.
* cipher/rijndael.c (_gcry_aes_aesni_ctr32le_enc)
(_gcry_aes_vaes_ctr32le_enc): New prototypes.
(do_setkey): Add setup of 'bulk_ops->ctr32le_enc' for AES-NI and
VAES.
* tests/basic.c (check_gcm_siv_cipher): Add large test-vector for
bulk ops testing.
--

Counter mode in GCM-SIV is little-endian on first 4 bytes of
of counter block, unlike regular CTR mode which works on
big-endian full block.

Benchmark on AMD Ryzen 7 5800X:

Before:
AES | nanosecs/byte mebibytes/sec cycles/byte auto Mhz
GCM-SIV enc | 1.00 ns/B 953.2 MiB/s 4.85 c/B 4850
GCM-SIV dec | 1.01 ns/B 940.1 MiB/s 4.92 c/B 4850
GCM-SIV auth | 0.118 ns/B 8051 MiB/s 0.575 c/B 4850

After (~6x faster):
AES | nanosecs/byte mebibytes/sec cycles/byte auto Mhz
GCM-SIV enc | 0.150 ns/B 6367 MiB/s 0.727 c/B 4850
GCM-SIV dec | 0.161 ns/B 5909 MiB/s 0.783 c/B 4850
GCM-SIV auth | 0.118 ns/B 8051 MiB/s 0.574 c/B 4850

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
---
cipher/cipher-gcm-siv.c | 26 ++-
cipher/cipher-internal.h | 2 +
cipher/rijndael-aesni.c | 192 +++++++++++++++++
cipher/rijndael-vaes-avx2-amd64.S | 328 ++++++++++++++++++++++++++++++
cipher/rijndael-vaes.c | 21 ++
cipher/rijndael.c | 10 +-
tests/basic.c | 139 +++++++++++++
7 files changed, 708 insertions(+), 10 deletions(-)

diff --git a/cipher/cipher-gcm-siv.c b/cipher/cipher-gcm-siv.c
index b735d199..813cf579 100644
--- a/cipher/cipher-gcm-siv.c
+++ b/cipher/cipher-gcm-siv.c
@@ -178,12 +178,21 @@ do_ctr_le32 (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
unsigned char tmp[GCRY_SIV_BLOCK_LEN];
unsigned int burn = 0, nburn;
- size_t n;
+ size_t nblocks;

if (inbuflen == 0)
return;

- n = GCRY_SIV_BLOCK_LEN;
+ /* Use a bulk method if available. */
+ nblocks = inbuflen / GCRY_SIV_BLOCK_LEN;
+ if (nblocks && c->bulk.ctr32le_enc)
+ {
+ c->bulk.ctr32le_enc (c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
+ inbuf += nblocks * GCRY_SIV_BLOCK_LEN;
+ outbuf += nblocks * GCRY_SIV_BLOCK_LEN;
+ inbuflen -= nblocks * GCRY_SIV_BLOCK_LEN;
+ }
+
do
{
nburn = enc_fn (c->context.c, tmp, c->u_ctr.ctr);
@@ -195,20 +204,19 @@ do_ctr_le32 (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
break;
cipher_block_xor(outbuf, inbuf, tmp, GCRY_SIV_BLOCK_LEN);

- inbuflen -= n;
- outbuf += n;
- inbuf += n;
+ inbuflen -= GCRY_SIV_BLOCK_LEN;
+ outbuf += GCRY_SIV_BLOCK_LEN;
+ inbuf += GCRY_SIV_BLOCK_LEN;
}
while (inbuflen);

if (inbuflen)
{
- n = inbuflen;
buf_xor(outbuf, inbuf, tmp, inbuflen);

- inbuflen -= n;
- outbuf += n;
- inbuf += n;
+ outbuf += inbuflen;
+ inbuf += inbuflen;
+ inbuflen -= inbuflen;
}

wipememory (tmp, sizeof(tmp));
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
index 8b04cff7..0bc85b1a 100644
--- a/cipher/cipher-internal.h
+++ b/cipher/cipher-internal.h
@@ -157,6 +157,8 @@ typedef struct cipher_bulk_ops
const void *inbuf_arg, size_t nblocks);
void (*ctr_enc)(void *context, unsigned char *iv, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks);
+ void (*ctr32le_enc)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
size_t (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks, int encrypt);
size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks);
diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c
index 9dde0489..34a4a447 100644
--- a/cipher/rijndael-aesni.c
+++ b/cipher/rijndael-aesni.c
@@ -1854,6 +1854,198 @@ _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr,
}


+void ASM_FUNC_ATTR
+_gcry_aes_aesni_ctr32le_enc (RIJNDAEL_context *ctx, unsigned char *ctr,
+ unsigned char *outbuf, const unsigned char *inbuf,
+ size_t nblocks)
+{
+ static const byte le_addd_const[8][16] __attribute__ ((aligned (16))) =
+ {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+ aesni_prepare_2_7_variable;
+
+ aesni_prepare ();
+ aesni_prepare_2_7();
+
+ asm volatile ("movdqa %[ctr], %%xmm5\n\t" /* Preload CTR */
+ : /* No output */
+ : [ctr] "m" (*ctr)
+ : "memory");
+
+#ifdef __x86_64__
+ if (nblocks >= 8)
+ {
+ aesni_prepare_8_15_variable;
+
+ aesni_prepare_8_15();
+
+ for ( ;nblocks >= 8 ; nblocks -= 8 )
+ {
+ asm volatile
+ ("movdqa (%[key]), %%xmm0\n\t"
+
+ "movdqa %%xmm5, %%xmm1\n\t" /* load input blocks */
+ "movdqa %%xmm5, %%xmm2\n\t"
+ "movdqa %%xmm5, %%xmm3\n\t"
+ "movdqa %%xmm5, %%xmm4\n\t"
+ "movdqa %%xmm5, %%xmm8\n\t"
+ "movdqa %%xmm5, %%xmm9\n\t"
+ "movdqa %%xmm5, %%xmm10\n\t"
+ "movdqa %%xmm5, %%xmm11\n\t"
+
+ "paddd 0*16(%[addd]), %%xmm2\n\t"
+ "paddd 1*16(%[addd]), %%xmm3\n\t"
+ "paddd 2*16(%[addd]), %%xmm4\n\t"
+ "paddd 3*16(%[addd]), %%xmm8\n\t"
+ "paddd 4*16(%[addd]), %%xmm9\n\t"
+ "paddd 5*16(%[addd]), %%xmm10\n\t"
+ "paddd 6*16(%[addd]), %%xmm11\n\t"
+
+ "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */
+ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */
+ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */
+ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */
+ "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */
+ "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */
+ "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */
+ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */
+
+ "movdqu 0*16(%[inbuf]), %%xmm6\n\t"
+ "movdqu 1*16(%[inbuf]), %%xmm7\n\t"
+ "movdqu 2*16(%[inbuf]), %%xmm12\n\t"
+ "movdqu 3*16(%[inbuf]), %%xmm13\n\t"
+ "movdqu 4*16(%[inbuf]), %%xmm14\n\t"
+ "movdqu 5*16(%[inbuf]), %%xmm15\n\t"
+
+ "paddd 7*16(%[addd]), %%xmm5\n\t"
+ : /* No output */
+ : [addd] "r" (&le_addd_const[0][0]),
+ [inbuf] "r" (inbuf),
+ [key] "r" (ctx->keyschenc)
+ : "memory");
+
+ do_aesni_enc_vec8 (ctx);
+
+ asm volatile
+ ("pxor %%xmm0, %%xmm6\n\t"
+ "pxor %%xmm0, %%xmm7\n\t"
+ "pxor %%xmm0, %%xmm12\n\t"
+ "pxor %%xmm0, %%xmm13\n\t"
+ "pxor %%xmm0, %%xmm14\n\t"
+ "pxor %%xmm0, %%xmm15\n\t"
+ "aesenclast %%xmm6, %%xmm1\n\t"
+ "aesenclast %%xmm7, %%xmm2\n\t"
+ "movdqu 6*16(%[inbuf]), %%xmm6\n\t"
+ "movdqu 7*16(%[inbuf]), %%xmm7\n\t"
+ "aesenclast %%xmm12, %%xmm3\n\t"
+ "aesenclast %%xmm13, %%xmm4\n\t"
+ "pxor %%xmm0, %%xmm6\n\t"
+ "pxor %%xmm0, %%xmm7\n\t"
+ "aesenclast %%xmm14, %%xmm8\n\t"
+ "aesenclast %%xmm15, %%xmm9\n\t"
+ "aesenclast %%xmm6, %%xmm10\n\t"
+ "aesenclast %%xmm7, %%xmm11\n\t"
+ "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
+ "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
+ "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
+ "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
+ "movdqu %%xmm8, 4*16(%[outbuf])\n\t"
+ "movdqu %%xmm9, 5*16(%[outbuf])\n\t"
+ "movdqu %%xmm10, 6*16(%[outbuf])\n\t"
+ "movdqu %%xmm11, 7*16(%[outbuf])\n\t"
+ : /* No output */
+ : [inbuf] "r" (inbuf),
+ [outbuf] "r" (outbuf)
+ : "memory");
+
+ outbuf += 8*BLOCKSIZE;
+ inbuf += 8*BLOCKSIZE;
+ }
+
+ aesni_cleanup_8_15();
+ }
+#endif
+
+ for ( ;nblocks >= 4 ; nblocks -= 4 )
+ {
+ asm volatile
+ ("movdqa %%xmm5, %%xmm1\n\t" /* load input blocks */
+ "movdqa %%xmm5, %%xmm2\n\t"
+ "movdqa %%xmm5, %%xmm3\n\t"
+ "movdqa %%xmm5, %%xmm4\n\t"
+ "paddd 0*16(%[addd]), %%xmm2\n\t"
+ "paddd 1*16(%[addd]), %%xmm3\n\t"
+ "paddd 2*16(%[addd]), %%xmm4\n\t"
+ "paddd 3*16(%[addd]), %%xmm5\n\t"
+ "movdqu 0*16(%[inbuf]), %%xmm6\n\t"
+ "movdqu 1*16(%[inbuf]), %%xmm7\n\t"
+ : /* No output */
+ : [addd] "r" (&le_addd_const[0][0]),
+ [inbuf] "r" (inbuf)
+ : "memory");
+
+ do_aesni_enc_vec4 (ctx);
+
+ asm volatile
+ ("pxor %%xmm6, %%xmm1\n\t"
+ "pxor %%xmm7, %%xmm2\n\t"
+ "movdqu 2*16(%[inbuf]), %%xmm6\n\t"
+ "movdqu 3*16(%[inbuf]), %%xmm7\n\t"
+ "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
+ "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
+ "pxor %%xmm6, %%xmm3\n\t"
+ "pxor %%xmm7, %%xmm4\n\t"
+ "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
+ "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
+ : /* No output */
+ : [inbuf] "r" (inbuf),
+ [outbuf] "r" (outbuf)
+ : "memory");
+
+ outbuf += 4*BLOCKSIZE;
+ inbuf += 4*BLOCKSIZE;
+ }
+
+ for ( ;nblocks; nblocks-- )
+ {
+ asm volatile ("movdqa %%xmm5, %%xmm0\n\t"
+ "paddd %[add_one], %%xmm5\n\t"
+ "movdqu %[inbuf], %%xmm6\n\t"
+ :
+ : [add_one] "m" (*le_addd_const[0]),
+ [inbuf] "m" (*inbuf)
+ : "memory" );
+
+ do_aesni_enc (ctx);
+
+ asm volatile ("pxor %%xmm0, %%xmm6\n\t"
+ "movdqu %%xmm6, %[outbuf]\n\t"
+ : [outbuf] "=m" (*outbuf)
+ :
+ : "memory" );
+
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+
+ asm volatile ("movdqa %%xmm5, %[ctr]\n\t"
+ : [ctr] "=m" (*ctr)
+ :
+ : "memory" );
+
+ aesni_cleanup ();
+ aesni_cleanup_2_7 ();
+}
+
+
unsigned int ASM_FUNC_ATTR
_gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
const unsigned char *src)
diff --git a/cipher/rijndael-vaes-avx2-amd64.S b/cipher/rijndael-vaes-avx2-amd64.S
index c4deea9b..d4ecf59f 100644
--- a/cipher/rijndael-vaes-avx2-amd64.S
+++ b/cipher/rijndael-vaes-avx2-amd64.S
@@ -1107,6 +1107,290 @@ _gcry_vaes_avx2_ctr_enc_amd64:
CFI_ENDPROC();
ELF(.size _gcry_vaes_avx2_ctr_enc_amd64,.-_gcry_vaes_avx2_ctr_enc_amd64)

+/**********************************************************************
+ Little-endian 32-bit CTR-mode encryption (GCM-SIV)
+ **********************************************************************/
+ELF(.type _gcry_vaes_avx2_ctr32le_enc_amd64,@function)
+.globl _gcry_vaes_avx2_ctr32le_enc_amd64
+_gcry_vaes_avx2_ctr32le_enc_amd64:
+ /* input:
+ * %rdi: round keys
+ * %rsi: counter
+ * %rdx: dst
+ * %rcx: src
+ * %r8: nblocks
+ * %r9: nrounds
+ */
+ CFI_STARTPROC();
+
+ vbroadcasti128 (%rsi), %ymm15; // CTR
+
+ /* Process 16 blocks per loop. */
+.align 8
+.Lctr32le_enc_blk16:
+ cmpq $16, %r8;
+ jb .Lctr32le_enc_blk8;
+
+ leaq -16(%r8), %r8;
+
+ vbroadcasti128 (0 * 16)(%rdi), %ymm8;
+
+ /* Increment counters. */
+ vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0;
+ vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1;
+ vpaddd .Lle_addd_4 rRIP, %ymm15, %ymm2;
+ vpaddd .Lle_addd_6 rRIP, %ymm15, %ymm3;
+ vpaddd .Lle_addd_8 rRIP, %ymm15, %ymm4;
+ vpaddd .Lle_addd_10 rRIP, %ymm15, %ymm5;
+ vpaddd .Lle_addd_12 rRIP, %ymm15, %ymm6;
+ vpaddd .Lle_addd_14 rRIP, %ymm15, %ymm7;
+
+ vpaddd .Lle_addd_16_2 rRIP, %ymm15, %ymm15;
+
+ /* AES rounds */
+ XOR8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (1 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (2 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (3 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (4 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (5 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (6 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (7 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (8 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (9 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (10 * 16)(%rdi), %ymm8;
+ cmpl $12, %r9d;
+ jb .Lctr32le_enc_blk16_last;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (11 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (12 * 16)(%rdi), %ymm8;
+ jz .Lctr32le_enc_blk16_last;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (13 * 16)(%rdi), %ymm8;
+ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+ vbroadcasti128 (14 * 16)(%rdi), %ymm8;
+
+ /* Last round and output handling. */
+ .Lctr32le_enc_blk16_last:
+ vpxor (0 * 16)(%rcx), %ymm8, %ymm9; /* Xor src to last round key. */
+ vpxor (2 * 16)(%rcx), %ymm8, %ymm10;
+ vpxor (4 * 16)(%rcx), %ymm8, %ymm11;
+ vpxor (6 * 16)(%rcx), %ymm8, %ymm12;
+ vaesenclast %ymm9, %ymm0, %ymm0;
+ vaesenclast %ymm10, %ymm1, %ymm1;
+ vaesenclast %ymm11, %ymm2, %ymm2;
+ vaesenclast %ymm12, %ymm3, %ymm3;
+ vpxor (8 * 16)(%rcx), %ymm8, %ymm9;
+ vpxor (10 * 16)(%rcx), %ymm8, %ymm10;
+ vpxor (12 * 16)(%rcx), %ymm8, %ymm11;
+ vpxor (14 * 16)(%rcx), %ymm8, %ymm8;
+ leaq (16 * 16)(%rcx), %rcx;
+ vaesenclast %ymm9, %ymm4, %ymm4;
+ vaesenclast %ymm10, %ymm5, %ymm5;
+ vaesenclast %ymm11, %ymm6, %ymm6;
+ vaesenclast %ymm8, %ymm7, %ymm7;
+ vmovdqu %ymm0, (0 * 16)(%rdx);
+ vmovdqu %ymm1, (2 * 16)(%rdx);
+ vmovdqu %ymm2, (4 * 16)(%rdx);
+ vmovdqu %ymm3, (6 * 16)(%rdx);
+ vmovdqu %ymm4, (8 * 16)(%rdx);
+ vmovdqu %ymm5, (10 * 16)(%rdx);
+ vmovdqu %ymm6, (12 * 16)(%rdx);
+ vmovdqu %ymm7, (14 * 16)(%rdx);
+ leaq (16 * 16)(%rdx), %rdx;
+
+ jmp .Lctr32le_enc_blk16;
+
+ /* Handle trailing eight blocks. */
+.align 8
+.Lctr32le_enc_blk8:
+ cmpq $8, %r8;
+ jb .Lctr32le_enc_blk4;
+
+ leaq -8(%r8), %r8;
+
+ vbroadcasti128 (0 * 16)(%rdi), %ymm4;
+
+ /* Increment counters. */
+ vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0;
+ vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1;
+ vpaddd .Lle_addd_4 rRIP, %ymm15, %ymm2;
+ vpaddd .Lle_addd_6 rRIP, %ymm15, %ymm3;
+
+ vpaddd .Lle_addd_8_2 rRIP, %ymm15, %ymm15;
+
+ /* AES rounds */
+ XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (1 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (2 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (3 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (4 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (5 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (6 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (7 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (8 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (9 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (10 * 16)(%rdi), %ymm4;
+ cmpl $12, %r9d;
+ jb .Lctr32le_enc_blk8_last;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (11 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (12 * 16)(%rdi), %ymm4;
+ jz .Lctr32le_enc_blk8_last;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (13 * 16)(%rdi), %ymm4;
+ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+ vbroadcasti128 (14 * 16)(%rdi), %ymm4;
+
+ /* Last round and output handling. */
+ .Lctr32le_enc_blk8_last:
+ vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */
+ vpxor (2 * 16)(%rcx), %ymm4, %ymm6;
+ vpxor (4 * 16)(%rcx), %ymm4, %ymm7;
+ vpxor (6 * 16)(%rcx), %ymm4, %ymm4;
+ leaq (8 * 16)(%rcx), %rcx;
+ vaesenclast %ymm5, %ymm0, %ymm0;
+ vaesenclast %ymm6, %ymm1, %ymm1;
+ vaesenclast %ymm7, %ymm2, %ymm2;
+ vaesenclast %ymm4, %ymm3, %ymm3;
+ vmovdqu %ymm0, (0 * 16)(%rdx);
+ vmovdqu %ymm1, (2 * 16)(%rdx);
+ vmovdqu %ymm2, (4 * 16)(%rdx);
+ vmovdqu %ymm3, (6 * 16)(%rdx);
+ leaq (8 * 16)(%rdx), %rdx;
+
+ /* Handle trailing four blocks. */
+.align 8
+.Lctr32le_enc_blk4:
+ cmpq $4, %r8;
+ jb .Lctr32le_enc_blk1;
+
+ leaq -4(%r8), %r8;
+
+ vbroadcasti128 (0 * 16)(%rdi), %ymm4;
+
+ /* Increment counters. */
+ vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0;
+ vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1;
+
+ vpaddd .Lle_addd_4_2 rRIP, %ymm15, %ymm15;
+
+ /* AES rounds */
+ XOR2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (1 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (2 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (3 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (4 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (5 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (6 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (7 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (8 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (9 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (10 * 16)(%rdi), %ymm4;
+ cmpl $12, %r9d;
+ jb .Lctr32le_enc_blk4_last;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (11 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (12 * 16)(%rdi), %ymm4;
+ jz .Lctr32le_enc_blk4_last;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (13 * 16)(%rdi), %ymm4;
+ VAESENC2(%ymm4, %ymm0, %ymm1);
+ vbroadcasti128 (14 * 16)(%rdi), %ymm4;
+
+ /* Last round and output handling. */
+ .Lctr32le_enc_blk4_last:
+ vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */
+ vpxor (2 * 16)(%rcx), %ymm4, %ymm6;
+ leaq (4 * 16)(%rcx), %rcx;
+ vaesenclast %ymm5, %ymm0, %ymm0;
+ vaesenclast %ymm6, %ymm1, %ymm1;
+ vmovdqu %ymm0, (0 * 16)(%rdx);
+ vmovdqu %ymm1, (2 * 16)(%rdx);
+ leaq (4 * 16)(%rdx), %rdx;
+
+ /* Process trailing one to three blocks, one per loop. */
+.align 8
+.Lctr32le_enc_blk1:
+ cmpq $1, %r8;
+ jb .Ldone_ctr32le_enc;
+
+ leaq -1(%r8), %r8;
+
+ /* Load and increament counter. */
+ vmovdqu %xmm15, %xmm0;
+ vpaddd .Lle_addd_1 rRIP, %xmm15, %xmm15;
+
+ /* AES rounds. */
+ vpxor (0 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (1 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (2 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (3 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (4 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (5 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (6 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (7 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (8 * 16)(%rdi), %xmm0, %xmm0;
+ vaesenc (9 * 16)(%rdi), %xmm0, %xmm0;
+ vmovdqa (10 * 16)(%rdi), %xmm1;
+ cmpl $12, %r9d;
+ jb .Lctr32le_enc_blk1_last;
+ vaesenc %xmm1, %xmm0, %xmm0;
+ vaesenc (11 * 16)(%rdi), %xmm0, %xmm0;
+ vmovdqa (12 * 16)(%rdi), %xmm1;
+ jz .Lctr32le_enc_blk1_last;
+ vaesenc %xmm1, %xmm0, %xmm0;
+ vaesenc (13 * 16)(%rdi), %xmm0, %xmm0;
+ vmovdqa (14 * 16)(%rdi), %xmm1;
+
+ /* Last round and output handling. */
+ .Lctr32le_enc_blk1_last:
+ vpxor (%rcx), %xmm1, %xmm1; /* Xor src to last round key. */
+ leaq 16(%rcx), %rcx;
+ vaesenclast %xmm1, %xmm0, %xmm0; /* Last round and xor with xmm1. */
+ vmovdqu %xmm0, (%rdx);
+ leaq 16(%rdx), %rdx;
+
+ jmp .Lctr32le_enc_blk1;
+
+.align 8
+.Ldone_ctr32le_enc:
+ vmovdqu %xmm15, (%rsi);
+ vzeroall;
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_vaes_avx2_ctr32le_enc_amd64,.-_gcry_vaes_avx2_ctr32le_enc_amd64)
+
/**********************************************************************
OCB-mode encryption/decryption
**********************************************************************/
@@ -2677,6 +2961,50 @@ _gcry_vaes_consts:
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14
.Lbige_addb_15:
.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15
+
+.Lle_addd_0:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_1:
+ .byte 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_2:
+ .byte 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_3:
+ .byte 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_4:
+ .byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_5:
+ .byte 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_6:
+ .byte 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_7:
+ .byte 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_8:
+ .byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_9:
+ .byte 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_10:
+ .byte 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_11:
+ .byte 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_12:
+ .byte 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_13:
+ .byte 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_14:
+ .byte 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_15:
+ .byte 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+.Lle_addd_4_2:
+ .byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ .byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_8_2:
+ .byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ .byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_16_2:
+ .byte 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ .byte 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
.Lxts_gfmul_clmul:
.long 0x00, 0x87, 0x00, 0x00
.long 0x00, 0x87, 0x00, 0x00
diff --git a/cipher/rijndael-vaes.c b/cipher/rijndael-vaes.c
index 56afce17..0d7d1367 100644
--- a/cipher/rijndael-vaes.c
+++ b/cipher/rijndael-vaes.c
@@ -65,6 +65,14 @@ extern void _gcry_vaes_avx2_ctr_enc_amd64 (const void *keysched,
size_t nblocks,
unsigned int nrounds) ASM_FUNC_ABI;

+extern void _gcry_vaes_avx2_ctr32le_enc_amd64 (const void *keysched,
+ unsigned char *ctr,
+ void *outbuf_arg,
+ const void *inbuf_arg,
+ size_t nblocks,
+ unsigned int nrounds)
+ ASM_FUNC_ABI;
+
extern void _gcry_vaes_avx2_ocb_crypt_amd64 (const void *keysched,
unsigned int blkn,
void *outbuf_arg,
@@ -127,6 +135,19 @@ _gcry_aes_vaes_ctr_enc (void *context, unsigned char *iv,
_gcry_vaes_avx2_ctr_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds);
}

+void
+_gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *iv,
+ void *outbuf, const void *inbuf,
+ size_t nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ const void *keysched = ctx->keyschenc32;
+ unsigned int nrounds = ctx->rounds;
+
+ _gcry_vaes_avx2_ctr32le_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks,
+ nrounds);
+}
+
size_t
_gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks,
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 8df9aac3..c096321f 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -86,6 +86,9 @@ extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv,
extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr,
void *outbuf_arg, const void *inbuf_arg,
size_t nblocks);
+extern void _gcry_aes_aesni_ctr32le_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
size_t nblocks);
@@ -114,6 +117,9 @@ extern void _gcry_aes_vaes_cbc_dec (void *context, unsigned char *iv,
extern void _gcry_aes_vaes_ctr_enc (void *context, unsigned char *ctr,
void *outbuf_arg, const void *inbuf_arg,
size_t nblocks);
+extern void _gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
extern size_t _gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks,
int encrypt);
@@ -497,6 +503,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
bulk_ops->cbc_enc = _gcry_aes_aesni_cbc_enc;
bulk_ops->cbc_dec = _gcry_aes_aesni_cbc_dec;
bulk_ops->ctr_enc = _gcry_aes_aesni_ctr_enc;
+ bulk_ops->ctr32le_enc = _gcry_aes_aesni_ctr32le_enc;
bulk_ops->ocb_crypt = _gcry_aes_aesni_ocb_crypt;
bulk_ops->ocb_auth = _gcry_aes_aesni_ocb_auth;
bulk_ops->xts_crypt = _gcry_aes_aesni_xts_crypt;
@@ -509,6 +516,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
bulk_ops->cfb_dec = _gcry_aes_vaes_cfb_dec;
bulk_ops->cbc_dec = _gcry_aes_vaes_cbc_dec;
bulk_ops->ctr_enc = _gcry_aes_vaes_ctr_enc;
+ bulk_ops->ctr32le_enc = _gcry_aes_vaes_ctr32le_enc;
bulk_ops->ocb_crypt = _gcry_aes_vaes_ocb_crypt;
bulk_ops->xts_crypt = _gcry_aes_vaes_xts_crypt;
}
@@ -516,7 +524,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
}
#endif
#ifdef USE_PADLOCK
- else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8)
+ else if ((hwfeatures & HWF_PADLOCK_AES) && keylen == 128/8)
{
ctx->encrypt_fn = _gcry_aes_padlock_encrypt;
ctx->decrypt_fn = _gcry_aes_padlock_decrypt;
diff --git a/tests/basic.c b/tests/basic.c
index 148aaec6..4ce90165 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -5916,6 +5916,145 @@ check_gcm_siv_cipher (void)
"\x18\xce\x4f\x0b\x8c\xb4\xd0\xca\xc6\x5f\xea\x8f\x79\x25\x7b\x20"
"\x88\x8e\x53\xe7\x22\x99\xe5\x6d",
"\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ },
+ /* Large block testing */
+ {
+ GCRY_CIPHER_AES128,
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "",
+ 0,
+ "\x72\x94\x7b\x5d\x3c\x14\xc0\xa6\x27\x8d\x8d\xee\xbd\xe8\x8c\x6a"
+ "\x21\x34\xce\x64\x8f\x01\x01\xc6\xe4\x5d\xed\x2e\xb9\xec\xac\x53"
+ "\xf2\x07\xed\x60\xc8\xa2\x2f\x2e\x83\x0e\xf2\xbc\x42\x51\x24\x3b"
+ "\x41\x4f\x26\x84\xf0\x25\x69\x3f\x38\x29\xfb\xe9\xbb\x1a\x94\xd1"
+ "\x94\x0c\xce\xad\x8e\x66\xeb\xda\xc9\x1c\x72\x5a\x7f\x95\x4f\x9c"
+ "\x02\x27\x79\x8f\xe7\x51\x51\x3d\x1e\x2c\x4e\xcd\x07\xe5\xd1\xf0"
+ "\x6c\x95\x82\x37\x00\x50\x5e\xff\x82\xfb\x69\x0b\x4e\x7f\x10\x12"
+ "\x7d\x18\x7f\xa8\x88\x59\xfb\x55\x9b\x70\x36\xfc\xde\x75\xed\x77"
+ "\xf9\x09\x87\x29\x30\x7c\x81\x41\x12\xc2\xbd\xcd\x9f\x86\x98\x38"
+ "\x96\x44\x4c\xda\x2e\xbe\x7a\xfb\xdd\x4a\x4e\xa0\x84\x94\xd5\x76"
+ "\xa6\xae\x02\xcb\x1b\xd4\xd8\xcb\xa5\x24\x28\xe1\x3c\x1e\xdc\x3d"
+ "\x25\x50\xe7\xfb\x92\xad\xd9\x80\x33\xe0\xb2\x50\x07\xd4\x43\x40"
+ "\x41\x63\x98\x63\xa6\x1a\xfc\x56\x84\x3f\xf7\x4f\x31\xe7\xfe\xc5"
+ "\x73\x52\xfd\x6d\x9b\xbb\x9b\xf8\x19\xf8\xdc\x9f\x3a\x88\xa6\x7c"
+ "\xf3\x6b\xbe\xde\xda\x05\x2e\x79\x54\xb9\x3e\x59\x43\x0a\x1b\x16"
+ "\xcf\x94\x97\x71\x03\x74\x12\x37\xaf\xd4\x0a\x4b\x30\x16\x9b\x8b"
+ "\x9f\xae\x78\x46\x83\xde\x34\xc5\x31\x71\x67\x5e\xdb\x8d\x93\x71"
+ "\x90\x03\x72\x00\x9f\x4e\x1e\x7d\xf3\x3f\xf8\x31\xe7\xf6\xb4\x6d"
+ "\x8d\xdc\xa0\x85\x32\x7b\x32\x40\x8c\xa9\x90\x69\xac\x03\xdb\xd4"
+ "\xa5\x62\x9c\xfd\x78\xde\xc8\x4a\x18\x67\xa0\xee\x5e\x1e\xad\x1a"
+ "\x1c\xee\x78\xbd\xea\xdc\xc8\x34\xd1\x92\x20\xa7\x0d\x12\x90\x88"
+ "\x91\xe4\x6c\x3c\x06\x78\x13\x00\xdc\xc7\x3e\xd7\x91\xf7\xc1\xd6"
+ "\x5a\x99\x95\x23\xb5\xd8\x3d\x0f\x12\xaf\x25\xd8\xcf\xe8\x27\x7f"
+ "\xbc\x7c\xe2\xad\x34\x66\x7f\xfb\xf5\xa8\x11\xc1\xe6\x04\x37\x41"
+ "\xaf\x96\xb3\xb7\xee\x05\xf5\xd7\x7c\xc6\xfe\x2e\xa9\x07\x47\x08"
+ "\xa4\x50\x65\xc0\x2e\xd7\x27\xd8\x70\x8c\xf1\x12\x30\x4a\x82\xf6"
+ "\xb7\x68\xdb\x9d\x73\xc2\x82\x3d\x44\xda\xfb\xdd\x03\xc1\xdc\xfc"
+ "\x3f\x7f\x2e\xe2\xd3\x73\x24\xaf\xd1\x35\xa9\x4f\x3a\xad\x9d\x5c"
+ "\xd7\xc6\xa3\xb1\x11\xf1\xbb\xa0\x23\xe1\x22\x88\x5b\x10\xb3\xd6"
+ "\x01\x78\x5f\x9e\x4d\x96\x7b\xeb\x81\x6b\xce\x2d\xf5\x6a\xd1\xa8"
+ "\xb7\x56\xdd\xd0\x4b\xb0\xc9\x64\x7a\x2f\x63\xcb\xd6\x61\x84\x4b"
+ "\x9e\x4d\x0b\x2c\x99\xbc\xa2\x94\xf5\x07\x20\xe6\xe9\xc2\xd2\xa6"
+ "\x1c\x37\xd5\x88\x01\x71\xe2\x16\xcd\x10\x7a\x07\x8b\xf3\xb5\x49"
+ "\x75\xbe\x0b\xe1\xb2\x28\x15\x88\x2b\xb4\xee\x34\xfd\x67\x30\xd8"
+ "\xdc\x38\x90\x66\xb6\x51\x90\xb3\xdb\xee\x4e\x66\xc3\x05\xdf\xee"
+ "\x32\xac\x8b\xa2\x00\xcc\xff\xa2\x52\x19\x79\x7e\x6c\xc9\x68\xb2"
+ "\xab\xe4\x69\x11\xea\x00\xc9\x2b\x58\x77\x8b\x6c\x28\x0e\x40\x42"
+ "\xcc\xa7\xb2\x58\xed\x5e\x0b\x19\x49\xe5\x5e\xb1\xb5\x24\x61\x63"
+ "\x7d\x5b\x6a\x7d\x3d\xc1\x6e\x09\x64\x43\x66\x31\x3c\xb0\x26\x2e"
+ "\xc8\x27\xf6\x5a\x5f\x22\x94\x42\x62\x2a\xf6\x5a\x7d\xc2\x4a\x0d"
+ "\xd2\xad\xaa\x0e\xb2\xa4\x29\x1c\xb8\x3b\xaa\xc9\x1d\x1a\x30\xf8"
+ "\x0b\x35\xb2\x84\x75\xc3\x08\x0c\xe5\x36\xa9\xff\xfe\xb9\xc2\xb7"
+ "\x51\xab\x2d\x9d\x3e\x1c\x08\x8c\x6c\x64\xe1\xd9\x97\xf4\xfc\x4d"
+ "\x77\x6d\x0e\xce\x73\x0b\x7f\x57\x41\xed\xdf\x96\x11\xb3\xcc\x61"
+ "\xe8\x12\x31\x16\x72\x4c\x10\xd4\x52\x14\x4c\x83\xaa\x3c\x29\x6c"
+ "\x51\x40\x9a\x4d\x9b\xd0\xe6\x7f\xad\x31\x54\x88\x90\xe1\xa8\x0e"
+ "\xd8\xf4\x84\x11\xdb\x02\x41\xff\xb0\x8a\x92\x95\x97\xd6\x98\x8a"
+ "\xa0\x43\xda\x70\xbb\x17\xd0\x5a\x81\x3e\xf7\xcf\xc9\x33\xd9\x76"
+ "\x2f\x53\xa2\xac\xa0\x8a\x73\xe4\x0c\x81\xbe\x26\x01\x3f\x6d\x79"
+ "\x8a\x37\x59\x5b\x0a\x9a\x10\x6b\x04\x30\xed\xda\x11\x73\x73\xd9"
+ "\xa2\x9a\xf8\x8e\x67\x82\x5a\x8d\xc0\x52\xe8\x42\x89\xcd\x9c\xb1"
+ "\x5c\x3d\xd4\x75\x03\x71\x03\x3f\xdc\x6b\x79\xb4\x02\xb6\xac\xc4"
+ "\x11\x0f\x61\xc8\xf7\x5d\xc6\xbf\x48\x02\xa3\xdc\xa8\x37\x10\x85"
+ "\xb2\x8d\xbd\xb0\x79\x09\xb0\x5f\x30\x6c\x40\xba\x03\xbb\x22\xcc"
+ "\x80\xa1\xc3\x91\x88\x25\x92\xbe\xa6\xfa\x14\x77\x56\xb3\xc0\xb5"
+ "\x69\x8c\x6f\xed\x21\xaf\x0c\x79\x07\x64\xa2\xea\xeb\x47\x2c\x1e"
+ "\x7d\x6c\x12\xae\x75\xc4\xee\x12\x46\x72\x87\x65\x73\x51\xee\xf8"
+ "\x08\x63\x20\xa1\x61\xca\x73\x8f\xdf\xcb\x97\xf8\xfc\xb0\x56\xea"
+ "\x34\x9d\xce\xb8\x91\xb8\xfc\xec\x76\xd0\x71\xb7\x92\xc9\xb2\x28"
+ "\xee\x0b\x5d\x7c\x4a\xf6\x73\x4d\xc2\x5b\x5b\xae\x7b\xa6\x9c\xba"
+ "\x29\x7d\x7d\x3c\x29\x01\x04\x2d\xd1\x6c\x8d\x8d\xe5\xb4\x6b\xf9"
+ "\x2a\x83\xb8\x14\x00\x1c\x91\x72\x5e\x8f\x13\x56\x6d\x9b\x6d\x27"
+ "\xe8\x22\x55\x4b\x2f\x8a\x31\x16\x98\x03\x51\x73\xa7\x2e\x18\x81"
+ "\x51\x0a\x8f\x6d\x17\xd0\xea\x04\x1c\x11\xb9\x6b\x8e\xaa\x76",
+ 1023,
+ "\x24\x28\x57\xa0\x3c\x12\xe2\x6a\x65\x97\x96\x75\xb3\x75\x67\x4c"
+ "\xd0\xc8\xa7\x07\x7d\x55\x10\xbc\x11\xfe\x45\xbe\x74\x27\x74\xa3"
+ "\x8b\xb8\x51\x0d\x2e\xf0\x0c\x83\xed\xe4\x8b\x15\xf2\xae\xd8\xd5"
+ "\xed\xd8\x76\x0d\x0b\x5b\x7b\x5a\x17\x83\xf3\x37\xe5\x81\x90\xe8"
+ "\x15\xb4\xec\xf8\x5a\x00\x72\xf2\xbb\x68\x0a\xc9\x6c\x4a\x80\x45"
+ "\x04\xa5\x7e\xfa\xf3\x45\x08\x65\xd0\xd6\xcd\x08\xd1\x1f\x45\x6b"
+ "\x23\xa9\x0f\xe1\x10\x90\x26\x48\x23\x23\xd2\x60\xc4\x16\x31\x03"
+ "\x30\xbe\xf0\xd0\xa0\xa7\xcf\xaa\xe6\x27\x0e\xd6\x7b\x79\xf1\x2b"
+ "\x29\x27\x57\x5a\xb7\xf5\xf8\xb4\x35\x3c\xb5\x10\xb8\xbf\xbe\xad"
+ "\xdb\x9b\x3d\x35\x63\xac\x9b\xfe\x86\x69\x2c\x54\xf5\x7c\x7f\xd6"
+ "\xcd\x33\x9f\x57\x7f\xce\x72\x18\x60\x2e\x20\x33\xc9\x13\x9f\x60"
+ "\x5f\x67\x24\xc2\xbb\x9e\x63\x80\xcf\x96\xb9\xf0\xf1\x9e\xcc\x5a"
+ "\x61\x02\x6d\xab\x4c\xf7\x13\xe4\x48\x0f\x9f\xc9\x24\x8e\x40\x06"
+ "\x53\x30\xac\xd9\xe8\xf5\xcd\xd4\xcf\x99\x1f\x3c\x08\x74\x38\x7e"
+ "\x0b\x76\x0d\xc3\xbd\x2a\x75\x3a\x55\x0c\xc6\xd3\x50\x59\x53\xf2"
+ "\x14\x1d\x09\xb0\xfa\x8d\xc2\x5e\x6b\x79\xed\x5e\x10\xcc\x1c\xbe"
+ "\x03\x75\x6d\x23\x44\xe8\xd6\x4d\x8f\xe4\xd6\x1a\x16\x83\x79\x72"
+ "\xdc\x51\x25\x61\x75\xe7\x00\x09\xdf\xfe\x0c\x6c\x99\xa8\xb0\xfc"
+ "\xbf\xb6\x7f\xae\x0a\x75\x2e\xd4\x69\xfe\xf1\xb7\x68\xbe\x07\xf0"
+ "\x9c\xa3\x82\x1f\x4d\x06\xa7\x73\x53\xbd\x98\x99\x93\x1b\xc9\xb6"
+ "\x04\x5e\xc0\xc1\xd8\x53\x7e\x6f\xd9\x4e\xa0\x37\xab\x71\x92\xc7"
+ "\x97\x4b\x80\x40\x14\xd0\xd0\xee\x93\xfb\xd5\x76\xce\xd7\x9e\x74"
+ "\xee\x5d\xe6\x79\xb2\x92\xbb\xff\x63\x19\x61\x64\xcc\x60\x80\x8b"
+ "\x9c\x1f\x38\x01\x43\xf7\xa6\xcd\x20\x5d\x1d\x2a\x2a\x25\xf4\xd5"
+ "\x17\x3d\x9c\xd2\x56\x8c\x76\x4e\xa0\xba\x24\x55\x55\xd4\x87\x78"
+ "\xde\x30\xe8\x6f\x39\xa5\x22\x91\x2b\x7b\x20\x6f\xf6\x44\xff\xec"
+ "\x29\x4e\xc8\x30\xf7\x23\x18\xef\xb8\x33\xfb\x5f\xf2\xe2\xd8\xc1"
+ "\xe3\x0f\x24\x19\xff\x99\x7e\xa2\xdb\x78\xde\xc3\x92\x47\x9b\x32"
+ "\xd6\xfa\xb7\x34\x14\xa4\xde\xd0\xa4\x6f\x7b\x03\x90\x80\x7a\x1e"
+ "\xb7\xc7\xc3\x75\x98\xa6\x76\xfc\xa6\x38\xa3\xf6\x17\xe8\x90\x25"
+ "\x28\x66\x41\x78\xe9\x70\x44\xbc\x62\x64\xf5\xaa\xd8\x62\x09\xf3"
+ "\xff\x05\xd5\x4e\xea\x8d\xf0\x0e\x4e\x3c\x37\xbe\x30\xe6\x69\x15"
+ "\xc5\x7b\xa6\x67\x1a\x74\xca\x4f\x0f\x5c\xf3\xac\x20\xaa\xc3\xad"
+ "\xf5\xb3\x58\x8e\x22\x53\x3d\xe8\x0a\x1b\x33\x88\xf1\x8d\x9c\xc8"
+ "\x5a\xb6\xd3\xde\x1a\x7a\x21\x12\x1e\x70\x0e\x52\x90\x24\xe0\x1c"
+ "\xaa\x04\x79\xbc\x58\x42\xcb\xe1\x42\x82\xbe\xeb\x17\xd6\xd9\x8c"
+ "\xc5\xe8\x77\xde\x77\xb5\x31\xf5\x7f\x09\x8b\x7d\x59\x6e\xbd\xe0"
+ "\x7b\x0f\xe6\x29\x37\x7b\x19\x90\x69\x33\x0a\xbe\x50\xa5\x11\xba"
+ "\xc5\x90\x78\x31\xfc\x1e\x6c\x8e\x50\x99\x2b\xd9\x50\x39\xaa\x80"
+ "\x19\x59\xae\x1e\x7a\x7d\xea\xbe\x92\x0e\xc1\xd4\x99\x71\x50\xb2"
+ "\x46\x0e\x39\x73\x45\x92\x8e\xd7\xb3\xcd\xf7\x37\x8e\x78\x2b\x2b"
+ "\xba\x33\xc1\x3e\xdd\xac\x9d\x09\xcd\xb0\x7e\x78\x05\x70\x44\x98"
+ "\x8d\xcd\xf3\xf4\x55\x07\x6a\x75\x66\x6a\xd2\xf2\x4a\x95\x6b\x07"
+ "\xfc\x8d\x6d\xe9\x40\xc5\x94\x19\xb5\x29\x5c\xaa\xb0\x7b\x2b\x8d"
+ "\x64\x41\xfd\x10\x58\xba\x6c\x1f\x7e\x88\x5f\x77\x8c\xe0\x3a\xda"
+ "\x7d\xed\xc4\xf1\x30\xce\x8d\x47\xd8\xe2\x8c\xca\xea\xf8\xb7\x73"
+ "\x9d\xb4\xfc\x06\x09\x17\x20\x00\x96\xe4\xd2\x07\x01\x10\x44\xef"
+ "\x7e\x18\x74\xac\xba\xe3\x26\x0d\x11\x27\xbf\xf3\xbb\x06\x1c\x49"
+ "\xd7\xae\x79\xe1\xaf\xd8\x66\x48\x03\xb6\x08\x66\x79\x11\xc5\x68"
+ "\x47\xbc\x4b\xfe\xc4\xa6\x7b\x3a\x66\xcd\x9f\x93\x70\xc2\x42\xd9"
+ "\xac\x54\x36\x73\x1b\x3a\x89\x1f\x13\xc7\x63\x9e\x43\xbf\xdd\xd7"
+ "\x54\xc7\xda\x6f\x74\x83\x81\x27\x19\xb3\xde\x1a\x14\xec\x0b\x96"
+ "\xee\x12\x02\xd1\x9f\x30\xe1\xef\xb8\xb4\xe9\xa4\x72\xc1\x48\xbc"
+ "\x23\x21\x64\x32\x0d\xac\x49\x6e\x53\x80\x37\x10\x2d\xcf\x6f\x11"
+ "\xf3\xd0\xf3\x02\xb6\x9d\x6e\x3c\x44\x39\x4d\xee\x8b\x8f\xea\xfa"
+ "\x20\xf4\x98\x67\x9c\xe3\x12\x82\xa8\xbe\x1c\x3a\x1c\x51\x81\x9d"
+ "\xc0\xfe\x46\x79\xd0\x19\x6b\xf1\x5d\xbb\x4d\xde\x42\xc9\x72\x93"
+ "\x62\x65\xb5\x88\xb1\x5f\x92\xfe\x56\x56\x58\xfb\x7a\x81\x7c\x02"
+ "\xb0\xc0\x53\x84\x6f\x13\x20\x53\xec\x49\x93\xae\x7e\x3c\x3f\xdf"
+ "\xe7\xba\xa0\x40\x24\x10\xd4\xe6\xf5\xed\x65\xd3\x21\x36\xb1\xe6"
+ "\x11\x0a\x47\xbc\xd3\x21\x33\x30\x03\x37\x8c\x45\xe5\xdd\xb0\xd5"
+ "\xcb\x80\x42\xdd\x84\xd6\x70\xf0\xbb\x5b\x44\xe0\x84\x8b\x83\x7c"
+ "\xcb\xec\x6a\x28\xa3\xf3\x4a\x6c\x0d\xb0\x79\x34\x13\x10\x64\xfc"
+ "\xee\x12\x55\x82\x25\x25\x30\xb9\xa6\xf8\x3c\x81\x36\xcd\xef",
+ "\xce\xc3\x13\x6c\x40\x2a\xcc\x51\xa1\xce\xb3\xed\xe8\xa6\x5b\x04",
}
};

--
2.30.2


_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel