chiark / gitweb /
disorder-choose now uses an arcfour keystream as its RNG instead of
[disorder] / lib / arcfour.c
1 /* arcfour.c --- The arcfour stream cipher
2  * Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 Free Software
3  * Foundation, Inc.
4  *
5  * This file is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published
7  * by the Free Software Foundation; either version 2, or (at your
8  * option) any later version.
9  *
10  * This file is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this file; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA.
19  *
20  */
21
22 /* Code from Libgcrypt adapted for gnulib by Simon Josefsson. */
23
24 /*
25  * For a description of the algorithm, see:
26  *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
27  *   ISBN 0-471-11709-9. Pages 397 ff.
28  */
29
30 #include "arcfour.h"
31
32 void
33 arcfour_stream (arcfour_context * context, const char *inbuf, char *outbuf,
34                 size_t length)
35 {
36   uint8_t i = context->idx_i;
37   uint8_t j = context->idx_j;
38   char *sbox = context->sbox;
39
40   for (; length > 0; length--)
41     {
42       char t;
43
44       i++;
45       j += sbox[i];
46       t = sbox[i];
47       sbox[i] = sbox[j];
48       sbox[j] = t;
49       *outbuf++ = (*inbuf++
50                    ^ sbox[(0U + sbox[i] + sbox[j]) % ARCFOUR_SBOX_SIZE]);
51     }
52
53   context->idx_i = i;
54   context->idx_j = j;
55 }
56
57 void
58 arcfour_setkey (arcfour_context * context, const char *key, size_t keylen)
59 {
60   size_t i, j, k;
61   char *sbox = context->sbox;
62
63   context->idx_i = context->idx_j = 0;
64   for (i = 0; i < ARCFOUR_SBOX_SIZE; i++)
65     sbox[i] = i;
66   for (i = j = k = 0; i < ARCFOUR_SBOX_SIZE; i++)
67     {
68       char t;
69       j = (j + sbox[i] + key[k]) % ARCFOUR_SBOX_SIZE;
70       t = sbox[i];
71       sbox[i] = sbox[j];
72       sbox[j] = t;
73       if (++k == keylen)
74         k = 0;
75     }
76 }