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