From 5a30f34558d0d1bcf98ed62a9dc46279844df924 Mon Sep 17 00:00:00 2001 From: Dimitri Lozeve Date: Tue, 2 Jun 2020 22:37:52 +0200 Subject: [PATCH] Solve challenge 3 --- ex03/main.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 4 ++++ 2 files changed, 67 insertions(+) create mode 100644 ex03/main.c diff --git a/ex03/main.c b/ex03/main.c new file mode 100644 index 0000000..c2bb5bd --- /dev/null +++ b/ex03/main.c @@ -0,0 +1,63 @@ +#include "utils.h" +#include +#include +#include +#include +#include + +double frequency_score(unsigned char *buf, size_t len) { + static const double english_freqs[26] = { + 0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, // A-G + 0.06094, 0.06966, 0.00153, 0.00772, 0.04025, 0.02406, 0.06749, // H-N + 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758, // O-U + 0.00978, 0.02360, 0.00150, 0.01974, 0.00074 // V-Z + }; + + unsigned int counts[26] = {0}; + for (size_t i = 0; i < len; ++i) { + unsigned char c = tolower(buf[i]) - 'a'; + if (c < 26) { + counts[c]++; + } + } + + double chi2 = 0; + for (size_t i = 0; i < 26; ++i) { + double expected = len * english_freqs[i]; + chi2 += pow(counts[i] - expected, 2) / expected; + } + return chi2; +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + printf("Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + unsigned char buf[512] = {0}; + size_t len = hex_to_bytes(buf, argv[1]); + + unsigned char cur[512]; + double min_score = INFINITY; + unsigned char key; + unsigned char best[512]; + // Test for keys from A to z + for (char c = 65; c < 127; ++c) { + for (size_t i = 0; i < len; ++i) { + cur[i] = buf[i] ^ c; + } + double score = frequency_score(cur, len); + if (score < min_score) { + min_score = score; + key = c; + memcpy(best, cur, len); + } + } + for (size_t i = 0; i < len; ++i) { + printf("%c", best[i]); + } + printf(" (key = %c, score = %.2f)\n", key, min_score); + + return EXIT_SUCCESS; +} diff --git a/meson.build b/meson.build index 2a1ef2b..6e54cf9 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,8 @@ project('cryptopals', 'c') +cc = meson.get_compiler('c') +m_dep = cc.find_library('m', required : false) + executable('ex01', ['ex01/main.c', 'utils.c']) executable('ex02', ['ex02/main.c', 'utils.c']) +executable('ex03', ['ex03/main.c', 'utils.c'], dependencies: m_dep)