X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/405497f7089f296c20eb4ce233feda5b51f5d16b..ab9168949ec2762698d6293adf17b637f30b891e:/twofish.c diff --git a/twofish.c b/twofish.c index 4ba4860..ad4882f 100644 --- a/twofish.c +++ b/twofish.c @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: twofish.c,v 1.2 2000/06/22 18:58:00 mdw Exp $ + * $Id: twofish.c,v 1.5 2004/04/08 01:36:15 mdw Exp $ * * Implementation of the Twofish cipher * * (c) 2000 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,29 +15,18 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * Catacomb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with Catacomb; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: twofish.c,v $ - * Revision 1.2 2000/06/22 18:58:00 mdw - * Twofish can handle keys with any byte-aligned size. - * - * Revision 1.1 2000/06/17 12:10:17 mdw - * New cipher. - * - */ - /*----- Header files ------------------------------------------------------*/ #include @@ -79,8 +68,8 @@ static uint32 h(uint32 x, const uint32 *l, unsigned k) /* --- Apply a series of @q@ tables to an integer --- */ # define Q(x, qa, qb, qc, qd) \ - ((qa[((x) >> 0) & 0xff] << 0) | \ - (qb[((x) >> 8) & 0xff] << 8) | \ + ((qa[((x) >> 0) & 0xff] << 0) | \ + (qb[((x) >> 8) & 0xff] << 8) | \ (qc[((x) >> 16) & 0xff] << 16) | \ (qd[((x) >> 24) & 0xff] << 24)) @@ -102,19 +91,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 +162,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,12 +173,12 @@ 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++; } - + s[j][sz - 1 - i] = ss[j] = a; } q += 8; @@ -215,6 +207,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,17 +258,75 @@ 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 const 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 --- */ #define GG(k, t0, t1, x, y, kk) do { \ - t0 = (k->g[0][U8(x >> 0)] ^ \ - k->g[1][U8(x >> 8)] ^ \ + t0 = (k->g[0][U8(x >> 0)] ^ \ + k->g[1][U8(x >> 8)] ^ \ k->g[2][U8(x >> 16)] ^ \ k->g[3][U8(x >> 24)]); \ - t1 = (k->g[1][U8(y >> 0)] ^ \ - k->g[2][U8(y >> 8)] ^ \ + t1 = (k->g[1][U8(y >> 0)] ^ \ + k->g[2][U8(y >> 8)] ^ \ k->g[3][U8(y >> 16)] ^ \ k->g[0][U8(y >> 24)]); \ t0 += t1; \