summaryrefslogtreecommitdiff
path: root/create_mt19937_stream_cipher_s3.c
diff options
context:
space:
mode:
authorJack Sangdahl <[email protected]>2024-06-15 22:27:25 -0600
committerJack Sangdahl <[email protected]>2024-06-15 22:27:25 -0600
commita59a5d144cc31cc8386e60dcc97be45a0dfd5256 (patch)
tree076d0adc9bc53538e7283e0248adef57ce2a9a51 /create_mt19937_stream_cipher_s3.c
downloadcryptopals-a59a5d144cc31cc8386e60dcc97be45a0dfd5256.tar.gz
cryptopals-a59a5d144cc31cc8386e60dcc97be45a0dfd5256.zip
Diffstat (limited to 'create_mt19937_stream_cipher_s3.c')
-rw-r--r--create_mt19937_stream_cipher_s3.c53
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;
+}