Created
December 14, 2014 05:59
-
-
Save allanlw/6fd37040bc8ae0275ba3 to your computer and use it in GitHub Desktop.
RC4 PRNG unrolled with C++ templates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <cstddef> | |
#include <cstdio> | |
#include <cstring> | |
struct RC4State { | |
uint8_t i, j; | |
uint8_t S[256]; | |
RC4State(uint8_t *key, size_t key_len) : i(0), j(0) { | |
size_t i2; | |
uint8_t j2 = 0; | |
for (i2 = 0; i2 < 256; i2++) { | |
S[i2] = i2; | |
} | |
for (i2 = 0; i2 < 256; i2++) { | |
j2 += S[i2] + key[i2 % key_len]; | |
Swap(i2, j2); | |
} | |
} | |
uint8_t GenerateOutput() { | |
i += 1; | |
j += S[i]; | |
Swap(i, j); | |
return S[(S[i] + S[j]) % 256]; | |
} | |
private: | |
void Swap(uint8_t i, uint8_t j) { | |
uint8_t temp = S[i]; | |
S[i] = S[j]; | |
S[j] = temp; | |
} | |
}; | |
// Fill out with n successive PRNG outputs | |
// return the last one. | |
template <size_t n> | |
struct RC4Output { | |
static uint8_t generate(RC4State& s, uint8_t *out) { | |
RC4Output<n-1>::generate(s, out); | |
uint8_t K = s.GenerateOutput(); | |
out[n-1] = K; | |
return K; | |
} | |
}; | |
template <> | |
struct RC4Output<0> { | |
static uint8_t generate(RC4State& s, uint8_t *out) { | |
return 0; | |
} | |
}; | |
int main(int argc, char **argv) { | |
if (argc != 2) { | |
puts("Supply one argument, key to use"); | |
return 1; | |
} | |
RC4State s((unsigned char *)argv[1], strlen(argv[1])); | |
uint8_t output[256]; | |
RC4Output<256>::generate(s, output); | |
for (int i = 0; i < 256; i++) { | |
printf("%02x", output[i]); | |
} | |
printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment