diff options
author | Jack Sangdahl <[email protected]> | 2024-06-15 22:27:25 -0600 |
---|---|---|
committer | Jack Sangdahl <[email protected]> | 2024-06-15 22:27:25 -0600 |
commit | a59a5d144cc31cc8386e60dcc97be45a0dfd5256 (patch) | |
tree | 076d0adc9bc53538e7283e0248adef57ce2a9a51 /create_mt19937_stream_cipher_s3.c | |
download | cryptopals-a59a5d144cc31cc8386e60dcc97be45a0dfd5256.tar.gz cryptopals-a59a5d144cc31cc8386e60dcc97be45a0dfd5256.zip |
Diffstat (limited to 'create_mt19937_stream_cipher_s3.c')
-rw-r--r-- | create_mt19937_stream_cipher_s3.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/create_mt19937_stream_cipher_s3.c b/create_mt19937_stream_cipher_s3.c new file mode 100644 index 0000000..a5e65a7 --- /dev/null +++ b/create_mt19937_stream_cipher_s3.c @@ -0,0 +1,53 @@ +// https://cryptopals.com/sets/3/challenges/24 +#include "util/mersenne_twister.h" +#include "util/random.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* + * a trivial stream cipher can be created out of any PRNG; use it to generate + * a sequence of 8-bit outputs and call those outputs 'keystream'. XOR each byte + * of plaintext with each successive byte of keystream. + */ + +void mt_encrypt(unsigned char *in, int in_len, uint16_t key, + unsigned char *out) { + unsigned char keystream[4]; + seed((uint32_t)key); + // extract 4 bytes at a time and use it as + // a keystream to XOR with plaintext + for (int i = 0; i < in_len; i++) { + if (i % 4 == 0) { + // prepare next 4 bytes of keystream + uint32_t k = extract(); + keystream[0] = (unsigned char)(k & 0x000000FF); + keystream[1] = (unsigned char)((k & 0x0000FFFF) >> 8); + keystream[2] = (unsigned char)((k & 0x00FFFFFF) >> 16); + keystream[3] = (unsigned char)(k >> 24); + } + out[i] = in[i] ^ keystream[i % 4]; + } +} + +void mt_decrypt(unsigned char *in, int in_len, uint16_t key, + unsigned char *out) { + mt_encrypt(in, in_len, key, out); +} + +int main() { + char *test = "a long test string, longer than 4 characters!"; + size_t len = strlen(test) + 1; + unsigned char *encr = malloc(len), *decr = malloc(len); + if (encr == NULL || decr == NULL) { + printf("out of memory D:\n"); + exit(1); + } + uint16_t key = (uint16_t)arc4random(); + mt_encrypt((unsigned char *)test, len, key, encr); + mt_decrypt(encr, len, key, decr); + printf("after turnaround: %s\n", decr); + free(encr); + free(decr); + return 0; +} |