From 574d8527d1cc983cf96cda236113363b8f07837f Mon Sep 17 00:00:00 2001 From: mdw Date: Sun, 13 Jan 2002 13:37:59 +0000 Subject: [PATCH] Add support for Twofish family keys. --- twofish.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- twofish.h | 42 +++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 10 deletions(-) diff --git a/twofish.c b/twofish.c index 4ba4860..566ee1e 100644 --- a/twofish.c +++ b/twofish.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: twofish.c,v 1.2 2000/06/22 18:58:00 mdw Exp $ + * $Id: twofish.c,v 1.3 2002/01/13 13:37:59 mdw Exp $ * * Implementation of the Twofish cipher * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: twofish.c,v $ + * Revision 1.3 2002/01/13 13:37:59 mdw + * Add support for Twofish family keys. + * * Revision 1.2 2000/06/22 18:58:00 mdw * Twofish can handle keys with any byte-aligned size. * @@ -102,19 +105,22 @@ static uint32 h(uint32 x, const uint32 *l, unsigned k) qmds[2][U8(x >> 16)] ^ qmds[3][U8(x >> 24)]); } -/* --- @twofish_init@ --- * +/* --- @twofish_initfk@ --- * * * Arguments: @twofish_ctx *k@ = pointer to key block to fill in * @const void *buf@ = pointer to buffer of key material * @size_t sz@ = size of key material + * @const twofish_fk *fk@ = family-key information * * Returns: --- * - * Use: Initializes a Twofish key buffer. Twofish accepts key sizes - * of up to 256 bits (32 bytes). + * Use: Does the underlying Twofish key initialization with family + * key. Pass in a family-key structure initialized to + * all-bits-zero for a standard key schedule. */ -void twofish_init(twofish_ctx *k, const void *buf, size_t sz) +void twofish_initfk(twofish_ctx *k, const void *buf, size_t sz, + const twofish_fk *fk) { # define KMAX 4 @@ -170,8 +176,8 @@ void twofish_init(twofish_ctx *k, const void *buf, size_t sz) /* --- Extract the easy subkeys --- */ - me[i] = LOAD32_L(q); - mo[i] = LOAD32_L(q + 4); + me[i] = LOAD32_L(q) ^ fk->t0[2 * i]; + mo[i] = LOAD32_L(q + 4) ^ fk->t0[2 * i + 1]; /* --- Now do the Reed-Solomon thing --- */ @@ -181,8 +187,8 @@ void twofish_init(twofish_ctx *k, const void *buf, size_t sz) int k; for (k = 0; k < 8; k++) { - if (*qq) - a ^= rsexp[rslog[*qq] + *r]; + unsigned char x = *qq ^ fk->t1[i * 8 + k]; + if (x) a ^= rsexp[rslog[x] + *r]; qq++; r++; } @@ -215,6 +221,13 @@ void twofish_init(twofish_ctx *k, const void *buf, size_t sz) k->k[i + 1] = ROL32(b, 9); ip += 2 * p; } + + for (i = 0; i < 8; i++) + k->k[i] ^= fk->t23[i]; + for (i = 8; i < 40; i += 2) { + k->k[i] ^= fk->t4[0]; + k->k[i + 1] ^= fk->t4[1]; + } } /* --- Construct the S-box tables --- */ @@ -259,6 +272,64 @@ void twofish_init(twofish_ctx *k, const void *buf, size_t sz) BURN(s); } +/* --- @twofish_init@ --- * + * + * Arguments: @twofish_ctx *k@ = pointer to key block to fill in + * @const void *buf@ = pointer to buffer of key material + * @size_t sz@ = size of key material + * + * Returns: --- + * + * Use: Initializes a Twofish key buffer. Twofish accepts key sizes + * of up to 256 bits (32 bytes). + */ + +void twofish_init(twofish_ctx *k, const void *buf, size_t sz) +{ + static twofish_fk fk = { { 0 } }; + twofish_initfk(k, buf, sz, &fk); +} + +/* --- @twofish_fkinit@ --- * + * + * Arguments: @twofish_fk *fk@ = pointer to family key block + * @const void *buf@ = pointer to buffer of key material + * @size_t sz@ = size of key material + * + * Returns: --- + * + * Use: Initializes a family-key buffer. This implementation allows + * family keys of any size acceptable to the Twofish algorithm. + */ + +void twofish_fkinit(twofish_fk *fk, const void *buf, size_t sz) +{ + twofish_ctx k; + uint32 pt[4], ct[4]; + const octet *kk; + unsigned i; + + twofish_init(&k, buf, sz); + + for (i = 0; i < 4; i++) pt[i] = (uint32)-1; + twofish_eblk(&k, pt, fk->t0 + 4); + + kk = buf; sz /= 4; + for (i = 0; i < sz; i++) { fk->t0[i] = LOAD32_L(kk); kk += 4; } + + for (i = 0; i < 4; i++) pt[i] = 0; twofish_eblk(&k, pt, ct); + for (i = 0; i < 4; i++) STORE32_L(fk->t1 + i * 4, ct[i]); + pt[0] = 1; twofish_eblk(&k, pt, ct); + for (i = 0; i < 4; i++) STORE32_L(fk->t1 + 4 + i * 4, ct[i]); + + pt[0] = 2; twofish_eblk(&k, pt, fk->t23 + 0); + pt[0] = 3; twofish_eblk(&k, pt, fk->t23 + 4); + pt[0] = 4; twofish_eblk(&k, pt, ct); + fk->t4[0] = ct[0]; fk->t4[1] = ct[1]; + + BURN(k); +} + /*----- Main encryption ---------------------------------------------------*/ /* --- Feistel function --- */ diff --git a/twofish.h b/twofish.h index 42736bd..79c697b 100644 --- a/twofish.h +++ b/twofish.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: twofish.h,v 1.3 2001/04/29 18:12:43 mdw Exp $ + * $Id: twofish.h,v 1.4 2002/01/13 13:37:59 mdw Exp $ * * The Twofish block cipher * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: twofish.h,v $ + * Revision 1.4 2002/01/13 13:37:59 mdw + * Add support for Twofish family keys. + * * Revision 1.3 2001/04/29 18:12:43 mdw * Fix formatting. * @@ -79,8 +82,30 @@ typedef struct twofish_ctx { uint32 g[4][256]; } twofish_ctx; +typedef struct twofish_fk { + uint32 t0[8], t23[8], t4[2]; + octet t1[32]; +} twofish_fk; + /*----- Functions provided ------------------------------------------------*/ +/* --- @twofish_initfk@ --- * + * + * Arguments: @twofish_ctx *k@ = pointer to key block to fill in + * @const void *buf@ = pointer to buffer of key material + * @size_t sz@ = size of key material + * @const twofish_fk *fk@ = family-key information + * + * Returns: --- + * + * Use: Does the underlying Twofish key initialization with family + * key. Pass in a family-key structure initialized to + * all-bits-zero for a standard key schedule. + */ + +extern void twofish_initfk(twofish_ctx */*k*/, const void */*buf*/, + size_t /*sz*/, const twofish_fk */*fk*/); + /* --- @twofish_init@ --- * * * Arguments: @twofish_ctx *k@ = pointer to key block to fill in @@ -96,6 +121,21 @@ typedef struct twofish_ctx { extern void twofish_init(twofish_ctx */*k*/, const void */*buf*/, size_t /*sz*/); +/* --- @twofish_fkinit@ --- * + * + * Arguments: @twofish_fk *fk@ = pointer to family key block + * @const void *buf@ = pointer to buffer of key material + * @size_t sz@ = size of key material + * + * Returns: --- + * + * Use: Initializes a family-key buffer. This implementation allows + * family keys of any size acceptable to the Twofish algorithm. + */ + +extern void twofish_fkinit(twofish_fk */*fk*/, + const void */*buf*/, size_t /*sz*/); + /* --- @twofish_eblk@, @twofish_dblk@ --- * * * Arguments: @const twofish_ctx *k@ = pointer to key block -- 2.11.0