chiark / gitweb /
Add some more vectors, and a whinge about how Skipjack test vectors are.
[catacomb] / rc4.h
1 /* -*-c-*-
2  *
3  * $Id: rc4.h,v 1.3 2000/06/17 11:55:13 mdw Exp $
4  *
5  * The alleged RC4 stream cipher
6  *
7  * (c) 1999 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 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: rc4.h,v $
33  * Revision 1.3  2000/06/17 11:55:13  mdw
34  * New key size interface.  Allow key material to be combined with an
35  * existing initialized context.
36  *
37  * Revision 1.2  1999/12/10 23:27:46  mdw
38  * Generic cipher and RNG interfaces.
39  *
40  * Revision 1.1  1999/09/03 08:41:12  mdw
41  * Initial import.
42  *
43  */
44
45 /*----- Notes on RC4 ------------------------------------------------------*
46  *
47  * RC4 is a stream cipher desgigned by Ron Rivest.  For a while RC4 was a
48  * trade secret of RSA Data Security, Inc., but somehow source code for a
49  * cipher which interworks with RC4 was posted to the Cypherpunks mailing
50  * list.
51  */
52
53 #ifndef CATACOMB_RC4_H
54 #define CATACOMB_RC4_H
55
56 #ifdef __cplusplus
57   extern "C" {
58 #endif
59
60 /*----- Header files ------------------------------------------------------*/
61
62 #include <assert.h>
63
64 #include <mLib/bits.h>
65
66 #ifndef CATACOMB_GCIPHER_H
67 #  include "gcipher.h"
68 #endif
69
70 #ifndef CATACOMB_GRAND_H
71 #  include "grand.h"
72 #endif
73
74 /*----- Data structures ---------------------------------------------------*/
75
76 typedef struct rc4_ctx {
77   unsigned i, j;                        /* Indices into the @S@ table */
78   unsigned f;                           /* Flags word */
79   octet s[256];                         /* The ever-changing @S@ table */
80 } rc4_ctx;
81
82 #define RC4F_OPEN 1u
83
84 /*----- Macros ------------------------------------------------------------*/
85
86 /* --- @RC4_OPEN@ --- *
87  *
88  * Arguments:   @ctx@ = pointer to an RC4 context
89  *              @guts@ = code to perform within the RC4 context
90  *
91  * Use:         Performs some code within an RC4 context.  Some of the
92  *              parameters are extracted from the context and held in local
93  *              variables for speed.  Multiple calls to @RC4_BYTE@ may be
94  *              made within the open context.  A context must only be
95  *              opened once at a time.
96  */
97
98 #define RC4_OPEN(ctx, guts) do {                                        \
99   unsigned _rc4_i = (ctx)->i;                                           \
100   unsigned _rc4_j = (ctx)->j;                                           \
101   octet *_rc4_s = (ctx)->s;                                             \
102                                                                         \
103   assert(((void)"RC4 context may only be opened once at a time",        \
104           ((ctx)->f & RC4F_OPEN) == 0));                                \
105   (ctx)->f |= RC4F_OPEN;                                                \
106                                                                         \
107   guts                                                                  \
108                                                                         \
109   (ctx)->f &= ~RC4F_OPEN;                                               \
110   (ctx)->i = _rc4_i;                                                    \
111   (ctx)->j = _rc4_j;                                                    \
112 } while (0)
113
114 /* --- @RC4_BYTE@ --- *
115  *
116  * Arguments:   @x@ = output variable to set
117  *
118  * Use:         Extracts an octet from the lexically innermost open RC4
119  *              context and places it in the variable @x@.
120  */
121
122 #define RC4_BYTE(x) do {                                                \
123   unsigned _si, _sj;                                                    \
124   _rc4_i = (_rc4_i + 1) & 0xff;                                         \
125   _si = _rc4_s[_rc4_i];                                                 \
126   _rc4_j = (_rc4_j + _si) & 0xff;                                       \
127   _sj = _rc4_s[_rc4_j];                                                 \
128   _rc4_s[_rc4_i] = _sj;                                                 \
129   _rc4_s[_rc4_j] = _si;                                                 \
130   (x) = _rc4_s[(_si + _sj) & 0xff];                                     \
131 } while (0)
132
133 /*----- Functions provided ------------------------------------------------*/
134
135 /* --- @rc4_addkey@ --- *
136  *
137  * Arguments:   @rc4_ctx *ctx@ = pointer to context to key
138  *              @const void *k@ = pointer to key data to use
139  *              @size_t sz@ = size of the key data
140  *
141  * Returns:     ---
142  *
143  * Use:         Mixes key data with an RC4 context.  The RC4 context is not
144  *              reset before mixing.  This may be used to mix new key
145  *              material with an existing RC4 context.
146  */
147
148 extern void rc4_addkey(rc4_ctx */*ctx*/, const void */*k*/, size_t /*sz*/);
149
150 /* --- @rc4_init@ --- *
151  *
152  * Arguments:   @rc4_ctx *ctx@ = pointer to context to initialize
153  *              @const void *k@ = pointer to key data to use
154  *              @size_t sz@ = size of the key data
155  *
156  * Returns:     ---
157  *
158  * Use:         Initializes an RC4 context ready for use.
159  */
160
161 extern void rc4_init(rc4_ctx */*ctx*/, const void */*k*/, size_t /*sz*/);
162
163 /* --- @rc4_encrypt@ --- *
164  *
165  * Arguments:   @rc4_ctx *ctx@ = pointer to context to use
166  *              @const void *src@ = pointer to the source block
167  *              @void *dest@ = pointer to the destination block
168  *              @size_t sz@ = size of the block
169  *
170  * Returns:     ---
171  *
172  * Use:         Encrypts or decrypts a block of data.  The destination may
173  *              be null to just grind the generator around for a while.  It's
174  *              recommended that you say `@rc4_encrypt(&ctx, 0, 0, 1024)@'
175  *              after initializing a new context, to prevent keystream
176  *              guessing attacks.  The source may be null to just extract a
177  *              big lump of data from the generator.
178  */
179
180 extern void rc4_encrypt(rc4_ctx */*ctx*/,
181                         const void */*src*/, void */*dest*/,
182                         size_t /*sz*/);
183
184 /*----- Generic cipher interface ------------------------------------------*/
185
186 #define RC4_KEYSZ 16
187 extern const octet rc4_keysz[];
188
189 extern const gccipher rc4;
190
191 /*----- Generic random number generator interface -------------------------*/
192
193 /* --- @rc4_rand@ --- *
194  *
195  * Arguments:   @const void *k@ = pointer to key material
196  *              @size_t sz@ = size of key material
197  *
198  * Returns:     Pointer to generic random number generator interface.
199  *
200  * Use:         Creates a random number interface wrapper around an
201  *              OFB-mode block cipher.
202  */
203
204 extern grand *rc4_rand(const void */*k*/, size_t /*sz*/);
205
206 /*----- That's all, folks -------------------------------------------------*/
207
208 #ifdef __cplusplus
209   }
210 #endif
211
212 #endif