chiark / gitweb /
cleanup: Big pile of whitespace fixes, all at once.
[catacomb] / noekeon.c
1 /* -*-c-*-
2  *
3  * $Id: noekeon.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
4  *
5  * The Noekeon block cipher
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------*
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  *
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Header files ------------------------------------------------------*/
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include <mLib/bits.h>
36
37 #include "blkc.h"
38 #include "gcipher.h"
39 #include "noekeon.h"
40
41 /*----- Global variables --------------------------------------------------*/
42
43 const octet noekeon_keysz[] = { KSZ_SET, NOEKEON_KEYSZ, 0 };
44
45 /*----- Magic constants ---------------------------------------------------*/
46
47 /* --- To generate the magic --- *
48  *
49  * perl -e'@@r=();$x=0x80;for(0..16){push(@@r,$x);$x<<=1;$x^=0x11b
50  * if$x&0x100;};print join(", ",map{sprintf"0x%02x",$_}@@r),"\n";'
51  */
52
53 static const octet rcon[17] = {
54   0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
55   0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a,
56   0xd4
57 };
58
59 /*----- Main code ---------------------------------------------------------*/
60
61 /* --- @noekeon_init@--- *
62  *
63  * Arguments:   @noekeon_ctx *k@ = pointer to key block to fill in
64  *              @const void *buf@ = pointer to buffer of key material
65  *              @size_t sz@ = size of key material
66  *
67  * Returns:     ---
68  *
69  * Use:         Initializes a Noekeon key buffer.  Noekeon accepts a 128-bit
70  *              key.
71  */
72
73 void noekeon_init(noekeon_ctx *k, const void *buf, size_t sz)
74 {
75   const octet *p = buf;
76   static const noekeon_ctx nullkey = { { 0, 0, 0, 0 } };
77
78   KSZ_ASSERT(noekeon, sz);
79   k->k[0] = LOAD32(p +  0);
80   k->k[1] = LOAD32(p +  4);
81   k->k[2] = LOAD32(p +  8);
82   k->k[3] = LOAD32(p + 12);
83   noekeon_eblk(&nullkey, k->k, k->k);
84 }
85
86 /* --- @noekeon_eblk@, @noekeon_dblk@ --- *
87  *
88  * Arguments:   @const noekeon_ctx *k@ = pointer to key block
89  *              @const uint32 s[2]@ = pointer to source block
90  *              @uint32 d[2]@ = pointer to destination block
91  *
92  * Returns:     ---
93  *
94  * Use:         Low-level block encryption and decryption.
95  */
96
97 #define GAMMA(a, b, c, d) do {                                          \
98   uint32 _x;                                                            \
99   b ^= ~(c | d); a ^= b & c;                                            \
100   _x = d; d = a; a = _x;                                                \
101   c ^= a ^ b ^ d;                                                       \
102   b ^= ~(c | d); a ^= b & c;                                            \
103 } while (0)
104
105 #define THETA(ka, kb, kc, kd, a, b, c, d) do {                          \
106   uint32 _x;                                                            \
107   _x = a ^ c; _x ^= ROR32(_x, 8) ^ ROL32(_x, 8); b ^= _x; d ^= _x;      \
108   a ^= ka; b ^= kb; c ^= kc; d ^= kd;                                   \
109   _x = b ^ d; _x ^= ROR32(_x, 8) ^ ROL32(_x, 8); a ^= _x; c ^= _x;      \
110 } while (0)
111
112 #define ITHETA(ka, kb, kc, kd, a, b, c, d) do {                         \
113   uint32 _x;                                                            \
114   _x = b ^ d; _x ^= ROR32(_x, 8) ^ ROL32(_x, 8); a ^= _x; c ^= _x;      \
115   a ^= ka; b ^= kb; c ^= kc; d ^= kd;                                   \
116   _x = a ^ c; _x ^= ROR32(_x, 8) ^ ROL32(_x, 8); b ^= _x; d ^= _x;      \
117 } while (0)
118
119 #define PI1(a, b, c, d) do {                                            \
120   b = ROL32(b, 1); c = ROL32(c, 5); d = ROL32(d, 2);                    \
121 } while (0)
122
123 #define PI2(a, b, c, d) do {                                            \
124   b = ROR32(b, 1); c = ROR32(c, 5); d = ROR32(d, 2);                    \
125 } while (0)
126
127 #define ROUND(r, ka, kb, kc, kd, a, b, c, d) do {                       \
128   a ^= *r++; THETA(ka, kb, kc, kd, a, b, c, d);                         \
129   PI1(a, b, c, d); GAMMA(a, b, c, d); PI2(a, b, c, d);                  \
130 } while (0)
131
132 #define IROUND(r, ka, kb, kc, kd, a, b, c, d) do {                      \
133   ITHETA(ka, kb, kc, kd, a, b, c, d); a ^= *--r;                        \
134   PI1(a, b, c, d); GAMMA(a, b, c, d); PI2(a, b, c, d);                  \
135 } while (0)
136
137 void noekeon_eblk(const noekeon_ctx *k, const uint32 *src, uint32 *dst)
138 {
139   uint32 ka = k->k[0], kb = k->k[1], kc = k->k[2], kd = k->k[3];
140   uint32 a = src[0], b = src[1], c = src[2], d = src[3];
141   const octet *r = rcon;
142
143   ROUND(r, ka, kb, kc, kd, a, b, c, d);
144   ROUND(r, ka, kb, kc, kd, a, b, c, d);
145   ROUND(r, ka, kb, kc, kd, a, b, c, d);
146   ROUND(r, ka, kb, kc, kd, a, b, c, d);
147   ROUND(r, ka, kb, kc, kd, a, b, c, d);
148   ROUND(r, ka, kb, kc, kd, a, b, c, d);
149   ROUND(r, ka, kb, kc, kd, a, b, c, d);
150   ROUND(r, ka, kb, kc, kd, a, b, c, d);
151   ROUND(r, ka, kb, kc, kd, a, b, c, d);
152   ROUND(r, ka, kb, kc, kd, a, b, c, d);
153   ROUND(r, ka, kb, kc, kd, a, b, c, d);
154   ROUND(r, ka, kb, kc, kd, a, b, c, d);
155   ROUND(r, ka, kb, kc, kd, a, b, c, d);
156   ROUND(r, ka, kb, kc, kd, a, b, c, d);
157   ROUND(r, ka, kb, kc, kd, a, b, c, d);
158   ROUND(r, ka, kb, kc, kd, a, b, c, d);
159
160   a ^= *r++; THETA(ka, kb, kc, kd, a, b, c, d);
161
162   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
163 }
164
165 void noekeon_dblk(const noekeon_ctx *k, const uint32 *src, uint32 *dst)
166 {
167   uint32 ka = k->k[0], kb = k->k[1], kc = k->k[2], kd = k->k[3];
168   uint32 a = src[0], b = src[1], c = src[2], d = src[3];
169   const octet *r = rcon + sizeof(rcon);
170
171   IROUND(r, ka, kb, kc, kd, a, b, c, d);
172   IROUND(r, ka, kb, kc, kd, a, b, c, d);
173   IROUND(r, ka, kb, kc, kd, a, b, c, d);
174   IROUND(r, ka, kb, kc, kd, a, b, c, d);
175   IROUND(r, ka, kb, kc, kd, a, b, c, d);
176   IROUND(r, ka, kb, kc, kd, a, b, c, d);
177   IROUND(r, ka, kb, kc, kd, a, b, c, d);
178   IROUND(r, ka, kb, kc, kd, a, b, c, d);
179   IROUND(r, ka, kb, kc, kd, a, b, c, d);
180   IROUND(r, ka, kb, kc, kd, a, b, c, d);
181   IROUND(r, ka, kb, kc, kd, a, b, c, d);
182   IROUND(r, ka, kb, kc, kd, a, b, c, d);
183   IROUND(r, ka, kb, kc, kd, a, b, c, d);
184   IROUND(r, ka, kb, kc, kd, a, b, c, d);
185   IROUND(r, ka, kb, kc, kd, a, b, c, d);
186   IROUND(r, ka, kb, kc, kd, a, b, c, d);
187
188   ITHETA(ka, kb, kc, kd, a, b, c, d); a ^= *--r;
189
190   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
191 }
192
193 BLKC_TEST(NOEKEON, noekeon)
194
195 /*----- That's all, folks -------------------------------------------------*/