summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/cipher/serpent.c
Side-by-side diff
Diffstat (limited to 'pwmanager/libcrypt/cipher/serpent.c') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/libcrypt/cipher/serpent.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/pwmanager/libcrypt/cipher/serpent.c b/pwmanager/libcrypt/cipher/serpent.c
index d606d9f..fb5df20 100644
--- a/pwmanager/libcrypt/cipher/serpent.c
+++ b/pwmanager/libcrypt/cipher/serpent.c
@@ -292,688 +292,688 @@ typedef struct serpent_context
}
#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t09; \
register unsigned long t10, t11, t12, t13, t15, t01; \
t01 = b | d ; \
t02 = c | d ; \
t03 = a & t01; \
t04 = b ^ t02; \
t05 = c ^ d ; \
t06 = ~ t03; \
t07 = a & t04; \
x = t05 ^ t07; \
t09 = x | t06; \
t10 = a ^ t07; \
t11 = t01 ^ t09; \
t12 = d ^ t04; \
t13 = c | t10; \
z = t03 ^ t12; \
t15 = a ^ t04; \
y = t11 ^ t13; \
w = t15 ^ t09; \
}
#define SBOX5(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t07, t08, t09; \
register unsigned long t10, t11, t12, t13, t14, t01; \
t01 = b ^ d ; \
t02 = b | d ; \
t03 = a & t01; \
t04 = c ^ t02; \
t05 = t03 ^ t04; \
w = ~ t05; \
t07 = a ^ t01; \
t08 = d | w ; \
t09 = b | t05; \
t10 = d ^ t08; \
t11 = b | t07; \
t12 = t03 | w ; \
t13 = t07 | t10; \
t14 = t01 ^ t11; \
y = t09 ^ t13; \
x = t07 ^ t08; \
z = t12 ^ t14; \
}
#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t07, t08, t09; \
register unsigned long t10, t12, t13, t15, t16, t01; \
t01 = a & d ; \
t02 = c ^ t01; \
t03 = a ^ d ; \
t04 = b & t02; \
t05 = a & c ; \
w = t03 ^ t04; \
t07 = a & w ; \
t08 = t01 ^ w ; \
t09 = b | t05; \
t10 = ~ b ; \
x = t08 ^ t09; \
t12 = t10 | t07; \
t13 = w | x ; \
z = t02 ^ t12; \
t15 = t02 ^ t13; \
t16 = b ^ d ; \
y = t16 ^ t15; \
}
#define SBOX6(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t07, t08, t09, t10; \
register unsigned long t11, t12, t13, t15, t17, t18, t01; \
t01 = a & d ; \
t02 = b ^ c ; \
t03 = a ^ d ; \
t04 = t01 ^ t02; \
t05 = b | c ; \
x = ~ t04; \
t07 = t03 & t05; \
t08 = b & x ; \
t09 = a | c ; \
t10 = t07 ^ t08; \
t11 = b | d ; \
t12 = c ^ t11; \
t13 = t09 ^ t10; \
y = ~ t13; \
t15 = x & t03; \
z = t12 ^ t07; \
t17 = a ^ b ; \
t18 = y ^ t15; \
w = t17 ^ t18; \
}
#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t07, t08, t09; \
register unsigned long t12, t13, t14, t15, t16, t17, t01; \
t01 = a ^ c ; \
t02 = ~ c ; \
t03 = b & t01; \
t04 = b | t02; \
t05 = d | t03; \
t06 = b ^ d ; \
t07 = a & t04; \
t08 = a | t02; \
t09 = t07 ^ t05; \
x = t06 ^ t08; \
w = ~ t09; \
t12 = b & w ; \
t13 = t01 & t05; \
t14 = t01 ^ t12; \
t15 = t07 ^ t13; \
t16 = d | t02; \
t17 = a ^ x ; \
z = t17 ^ t15; \
y = t16 ^ t14; \
}
#define SBOX7(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \
register unsigned long t11, t13, t14, t15, t16, t17, t01; \
t01 = a & c ; \
t02 = ~ d ; \
t03 = a & t02; \
t04 = b | t01; \
t05 = a & b ; \
t06 = c ^ t04; \
z = t03 ^ t06; \
t08 = c | z ; \
t09 = d | t05; \
t10 = a ^ t08; \
t11 = t04 & z ; \
x = t09 ^ t10; \
t13 = b ^ x ; \
t14 = t01 ^ x ; \
t15 = c ^ t05; \
t16 = t11 | t13; \
t17 = t02 | t14; \
w = t15 ^ t17; \
y = a ^ t16; \
}
#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
{ \
register unsigned long t02, t03, t04, t06, t07, t08, t09; \
register unsigned long t10, t11, t13, t14, t15, t16, t01; \
t01 = a & b ; \
t02 = a | b ; \
t03 = c | t01; \
t04 = d & t02; \
z = t03 ^ t04; \
t06 = b ^ t04; \
t07 = d ^ z ; \
t08 = ~ t07; \
t09 = t06 | t08; \
t10 = b ^ d ; \
t11 = a | d ; \
x = a ^ t09; \
t13 = c ^ t06; \
t14 = c & t11; \
t15 = d | x ; \
t16 = t01 | t10; \
w = t13 ^ t15; \
y = t14 ^ t16; \
}
/* XOR BLOCK1 into BLOCK0. */
#define BLOCK_XOR(block0, block1) \
{ \
block0[0] ^= block1[0]; \
block0[1] ^= block1[1]; \
block0[2] ^= block1[2]; \
block0[3] ^= block1[3]; \
}
/* Copy BLOCK_SRC to BLOCK_DST. */
#define BLOCK_COPY(block_dst, block_src) \
{ \
block_dst[0] = block_src[0]; \
block_dst[1] = block_src[1]; \
block_dst[2] = block_src[2]; \
block_dst[3] = block_src[3]; \
}
/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
INDEX, writing the output to the block found in ARRAY1 at index
INDEX. */
#define SBOX(which, array0, array1, index) \
SBOX##which (array0[index + 0], array0[index + 1], \
array0[index + 2], array0[index + 3], \
array1[index + 0], array1[index + 1], \
array1[index + 2], array1[index + 3]);
/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
index INDEX, writing the output to the block found in ARRAY1 at
index INDEX. */
#define SBOX_INVERSE(which, array0, array1, index) \
SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \
array0[index + 2], array0[index + 3], \
array1[index + 0], array1[index + 1], \
array1[index + 2], array1[index + 3]);
/* Apply the linear transformation to BLOCK. */
#define LINEAR_TRANSFORMATION(block) \
{ \
block[0] = rol (block[0], 13); \
block[2] = rol (block[2], 3); \
block[1] = block[1] ^ block[0] ^ block[2]; \
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
block[1] = rol (block[1], 1); \
block[3] = rol (block[3], 7); \
block[0] = block[0] ^ block[1] ^ block[3]; \
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
block[0] = rol (block[0], 5); \
block[2] = rol (block[2], 22); \
}
/* Apply the inverse linear transformation to BLOCK. */
#define LINEAR_TRANSFORMATION_INVERSE(block) \
{ \
block[2] = ror (block[2], 22); \
block[0] = ror (block[0] , 5); \
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
block[0] = block[0] ^ block[1] ^ block[3]; \
block[3] = ror (block[3], 7); \
block[1] = ror (block[1], 1); \
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
block[1] = block[1] ^ block[0] ^ block[2]; \
block[2] = ror (block[2], 3); \
block[0] = ror (block[0], 13); \
}
/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage.
This macro increments `round'. */
#define ROUND(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round++; \
SBOX (which, block, block_tmp, 0); \
LINEAR_TRANSFORMATION (block_tmp); \
BLOCK_COPY (block, block_tmp); \
}
/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
storage. The result will be stored in BLOCK_TMP. This macro
increments `round'. */
#define ROUND_LAST(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round++; \
SBOX (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkeys[round]); \
round++; \
}
/* Apply an inverse Serpent round to BLOCK, using the SBOX number
WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as
temporary storage. This macro increments `round'. */
#define ROUND_INVERSE(which, subkey, block, block_tmp) \
{ \
LINEAR_TRANSFORMATION_INVERSE (block); \
SBOX_INVERSE (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkey[round]); \
round--; \
BLOCK_COPY (block, block_tmp); \
}
/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
storage. The result will be stored in BLOCK_TMP. This macro
increments `round'. */
#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
{ \
BLOCK_XOR (block, subkeys[round]); \
round--; \
SBOX_INVERSE (which, block, block_tmp, 0); \
BLOCK_XOR (block_tmp, subkeys[round]); \
round--; \
}
/* Convert the user provided key KEY of KEY_LENGTH bytes into the
internally used format. */
static void
serpent_key_prepare (const byte_t *key, unsigned int key_length,
serpent_key_t key_prepared)
{
int i;
/* Copy key. */
for (i = 0; i < key_length / 4; i++)
{
#ifdef WORDS_BIGENDIAN
key_prepared[i] = byte_swap_32 (((u32_t *) key)[i]);
#else
key_prepared[i] = ((u32_t *) key)[i];
#endif
}
if (i < 8)
{
/* Key must be padded according to the Serpent
specification. */
key_prepared[i] = 0x00000001;
for (i++; i < 8; i++)
key_prepared[i] = 0;
}
}
/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */
static void
serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
{
u32_t w_real[140]; /* The `prekey'. */
u32_t k[132];
u32_t *w = &w_real[8];
int i, j;
/* Initialize with key values. */
for (i = 0; i < 8; i++)
w[i - 8] = key[i];
/* Expand to intermediate key using the affine recurrence. */
for (i = 0; i < 132; i++)
w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
/* Calculate subkeys via S-Boxes, in bitslice mode. */
SBOX (3, w, k, 0);
SBOX (2, w, k, 4);
SBOX (1, w, k, 8);
SBOX (0, w, k, 12);
SBOX (7, w, k, 16);
SBOX (6, w, k, 20);
SBOX (5, w, k, 24);
SBOX (4, w, k, 28);
SBOX (3, w, k, 32);
SBOX (2, w, k, 36);
SBOX (1, w, k, 40);
SBOX (0, w, k, 44);
SBOX (7, w, k, 48);
SBOX (6, w, k, 52);
SBOX (5, w, k, 56);
SBOX (4, w, k, 60);
SBOX (3, w, k, 64);
SBOX (2, w, k, 68);
SBOX (1, w, k, 72);
SBOX (0, w, k, 76);
SBOX (7, w, k, 80);
SBOX (6, w, k, 84);
SBOX (5, w, k, 88);
SBOX (4, w, k, 92);
SBOX (3, w, k, 96);
SBOX (2, w, k, 100);
SBOX (1, w, k, 104);
SBOX (0, w, k, 108);
SBOX (7, w, k, 112);
SBOX (6, w, k, 116);
SBOX (5, w, k, 120);
SBOX (4, w, k, 124);
SBOX (3, w, k, 128);
/* Renumber subkeys. */
for (i = 0; i < ROUNDS + 1; i++)
for (j = 0; j < 4; j++)
subkeys[i][j] = k[4 * i + j];
}
/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */
static void
serpent_setkey_internal (serpent_context_t *context,
const byte_t *key, unsigned int key_length)
{
serpent_key_t key_prepared;
serpent_key_prepare (key, key_length, key_prepared);
serpent_subkeys_generate (key_prepared, context->keys);
_gcry_burn_stack (272 * sizeof (u32_t));
}
-
+ static const char *serpent_test (void);
/* Initialize CTX with the key KEY of KEY_LENGTH bytes. */
static gcry_err_code_t
serpent_setkey (void *ctx,
const byte_t *key, unsigned int key_length)
{
serpent_context_t *context = ctx;
static const char *serpent_test_ret;
static int serpent_init_done;
gcry_err_code_t ret = GPG_ERR_NO_ERROR;
if (! serpent_init_done)
{
/* Execute a self-test the first time, Serpent is used. */
- static const char *serpent_test (void);
+
serpent_test_ret = serpent_test ();
if (serpent_test_ret)
log_error ("Serpent test failure: %s\n", serpent_test_ret);
serpent_init_done = 1;
}
if (serpent_test_ret)
ret = GPG_ERR_SELFTEST_FAILED;
else
{
serpent_setkey_internal (context, key, key_length);
_gcry_burn_stack (sizeof (serpent_key_t));
}
return ret;
}
static void
serpent_encrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
{
serpent_block_t b, b_next;
int round = 0;
#ifdef WORDS_BIGENDIAN
b[0] = byte_swap_32 (input[0]);
b[1] = byte_swap_32 (input[1]);
b[2] = byte_swap_32 (input[2]);
b[3] = byte_swap_32 (input[3]);
#else
b[0] = input[0];
b[1] = input[1];
b[2] = input[2];
b[3] = input[3];
#endif
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND (7, context->keys, b, b_next);
ROUND (0, context->keys, b, b_next);
ROUND (1, context->keys, b, b_next);
ROUND (2, context->keys, b, b_next);
ROUND (3, context->keys, b, b_next);
ROUND (4, context->keys, b, b_next);
ROUND (5, context->keys, b, b_next);
ROUND (6, context->keys, b, b_next);
ROUND_LAST (7, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
#endif
}
static void
serpent_decrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
{
serpent_block_t b, b_next;
int round = ROUNDS;
#ifdef WORDS_BIGENDIAN
b_next[0] = byte_swap_32 (input[0]);
b_next[1] = byte_swap_32 (input[1]);
b_next[2] = byte_swap_32 (input[2]);
b_next[3] = byte_swap_32 (input[3]);
#else
b_next[0] = input[0];
b_next[1] = input[1];
b_next[2] = input[2];
b_next[3] = input[3];
#endif
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
ROUND_INVERSE (7, context->keys, b, b_next);
ROUND_INVERSE (6, context->keys, b, b_next);
ROUND_INVERSE (5, context->keys, b, b_next);
ROUND_INVERSE (4, context->keys, b, b_next);
ROUND_INVERSE (3, context->keys, b, b_next);
ROUND_INVERSE (2, context->keys, b, b_next);
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
#endif
}
static void
serpent_encrypt (void *ctx, byte_t *buffer_out, const byte_t *buffer_in)
{
serpent_context_t *context = ctx;
serpent_encrypt_internal (context,
(const u32_t *) buffer_in, (u32_t *) buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
static void
serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
serpent_context_t *context = ctx;
serpent_decrypt_internal (context,
(const u32_t *) buffer_in,
(u32_t *) buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
/* Serpent test. */
static const char *
serpent_test (void)
{
serpent_context_t context;
unsigned char scratch[16];
unsigned int i;
static struct test
{
int key_length;
unsigned char key[32];
unsigned char text_plain[16];
unsigned char text_cipher[16];
} test_data[] =
{
{
16,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
"\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
},
{
24,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
"\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
},
{
32,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
"\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
},
{
32,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
"\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
},
{
0
},
};
for (i = 0; test_data[i].key_length; i++)
{
serpent_setkey_internal (&context, test_data[i].key,
test_data[i].key_length);
serpent_encrypt_internal (&context,
(const u32_t *) test_data[i].text_plain,
(u32_t *) scratch);
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
case 16:
return "Serpent-128 test encryption failed.";
case 24:
return "Serpent-192 test encryption failed.";
case 32:
return "Serpent-256 test encryption failed.";
}
serpent_decrypt_internal (&context,
(const u32_t *) test_data[i].text_cipher,
(u32_t *) scratch);
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
case 16:
return "Serpent-128 test decryption failed.";
case 24:
return "Serpent-192 test decryption failed.";
case 32:
return "Serpent-256 test decryption failed.";
}
}
return NULL;
}
/* "SERPENT" is an alias for "SERPENT128". */
static const char *cipher_spec_serpent128_aliases[] =
{
"SERPENT",
NULL,
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
{
"SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt,
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
{
"SERPENT192", NULL, NULL, 16, 192,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt,
};
gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
{
"SERPENT256", NULL, NULL, 16, 256,
sizeof (serpent_context_t),
serpent_setkey, serpent_encrypt, serpent_decrypt,
};