forked from antirez/rax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rc4rand.c
77 lines (68 loc) · 3.79 KB
/
rc4rand.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/* A simple RC4 based RNG that sucks less than the certain libc rand()
* implementations, notably the incredibly bad MacOS() implementation.
*
* Copyright (c) 2018, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
/* Initialize the sbox with an initial seed. */
static unsigned char rc4_sbox[256] = {244, 223, 67, 241, 181, 90, 95, 76, 248, 141, 130, 109, 92, 230, 238, 131, 111, 26, 75, 196, 186, 185, 51, 4, 40, 156, 11, 23, 15, 101, 144, 128, 173, 121, 123, 124, 218, 89, 187, 29, 178, 7, 0, 1, 217, 113, 235, 33, 182, 158, 94, 221, 100, 53, 140, 172, 139, 24, 162, 143, 229, 202, 36, 37, 39, 35, 45, 231, 87, 103, 198, 14, 255, 83, 93, 136, 165, 64, 3, 16, 49, 219, 155, 183, 233, 73, 215, 10, 159, 247, 212, 99, 106, 74, 154, 72, 22, 19, 65, 52, 46, 195, 134, 197, 69, 209, 34, 91, 137, 115, 102, 135, 63, 211, 47, 56, 127, 161, 27, 9, 118, 220, 191, 54, 21, 216, 18, 253, 81, 148, 42, 213, 114, 12, 190, 245, 129, 8, 41, 201, 168, 177, 204, 32, 242, 82, 13, 117, 2, 152, 60, 66, 166, 193, 164, 79, 142, 133, 126, 30, 85, 252, 184, 20, 17, 205, 236, 174, 226, 138, 38, 62, 222, 157, 77, 145, 250, 6, 249, 78, 192, 132, 170, 189, 176, 86, 153, 97, 125, 50, 254, 44, 61, 240, 203, 225, 246, 88, 234, 150, 179, 149, 122, 25, 104, 214, 105, 199, 228, 200, 163, 5, 112, 84, 55, 206, 251, 31, 98, 167, 108, 116, 175, 194, 171, 188, 58, 210, 237, 96, 147, 208, 110, 80, 169, 71, 180, 243, 239, 59, 28, 227, 160, 146, 48, 107, 68, 151, 224, 119, 43, 57, 207, 120, 232, 70};
void rc4srand(uint64_t seed) {
/* To seed the RNG in a reproducible way we use a simple
* hashing function, together with the swapping idea of the
* original RC4 key scheduling algorithm. */
for (int j = 0; j < 255; j++) rc4_sbox[j] = j;
seed ^= 5381;
for (int j = 0; j < 256; j++) {
seed = ((seed << 5) + seed) + j + 1;
int i = seed & 0xff;
/* Swap sbox[i] and sbox[j]. */
unsigned char t = rc4_sbox[j];
rc4_sbox[j] = rc4_sbox[i];
rc4_sbox[i] = t;
}
}
static void rc4(unsigned char *buf, unsigned long len) {
static unsigned int i = 0, j = 0;
unsigned int si, sj, x;
for (x = 0; x < len; x++) {
i = (i+1) & 0xff;
si = rc4_sbox[i];
j = (j + si) & 0xff;
sj = rc4_sbox[j];
rc4_sbox[i] = sj;
rc4_sbox[j] = si;
*buf++ = rc4_sbox[(si+sj)&0xff];
}
}
uint32_t rc4rand(void) {
uint32_t r;
rc4((unsigned char*)&r,sizeof(r));
return r;
}
uint64_t rc4rand64(void) {
uint64_t r;
rc4((unsigned char*)&r,sizeof(r));
return r;
}