cryptopals_c

cryptopals crypto challenges solutions in pure c
git clone git://git.superpozycja.net/cryptopals_c
Log | Files | Refs | README

commit d6af37147d971612c349a27bc26f7fb8ba44b34d
parent 8a74c314a49ab1632f88a21970241dff0384e127
Author: superpozycja <anna@superpozycja.net>
Date:   Sun,  1 Sep 2024 19:42:58 +0200

add vigenere related functions and truly rename to analysis

Diffstat:
Mlib/analysis.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/analysis.h | 6++++--
2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/lib/analysis.c b/lib/analysis.c @@ -74,3 +74,63 @@ void encrypt_rkxor(ba *pt, ba *key) key_exp->val[i] = key->val[i % (key->len)]; ba_xor(pt, key_exp); } + +float index_of_coincidence(ba *ct) +{ + unsigned int occur[256]; + unsigned int i; + unsigned int t; + float res; + + res = 0; + memset(occur, 0, sizeof(occur)); + + for (i = 0; i < ct->len; i++) + occur[ct->val[i]]++; + + t = 0; + for (i = 0; i < 256; i++) + t += occur[i] * (occur[i] - 1); + + res = t / (float) (ct->len * (ct->len - 1)); + return res; +} + +static float get_i_c_m(ba *ct, unsigned int m) +{ + float res; + int i; + res = 0; + for (i = 0; i < m; i++) { + ba *chunk = (ba *) malloc(sizeof(ba)); + int j; + int k; + + chunk->len = ct->len / m; + chunk->val = (uint8_t *) malloc(sizeof(uint8_t) * chunk->len); + + for (j = 0, k = 0; j < chunk->len && k + i < ct->len; j++, k += m) + chunk->val[j] = ct->val[k + i]; + res += index_of_coincidence(chunk); + } + return res / m; +} + +unsigned int guess_vigenere_keylen(ba *ct) +{ + unsigned int best; + float max; + int m; + + max = 0; + for (m = 1; m < 40; m++) { + float avg; + + avg = get_i_c_m(ct, m); + if (avg > max) { + max = avg; + best = m; + } + } + return best; +} diff --git a/lib/analysis.h b/lib/analysis.h @@ -1,5 +1,5 @@ -#ifndef CRYPTANALYSIS_H -#define CRYPTANALYSIS_H +#ifndef ANALYSIS_H +#define ANALYSIS_H #include <ctype.h> #include <string.h> @@ -12,5 +12,7 @@ unsigned long score_letter(char c); unsigned long score_english(ba *text); ba *decrypt_scxor(ba *ct); void encrypt_rkxor(ba *pt, ba *key); +float index_of_coincidence(ba *ct); +unsigned int guess_vigenere_keylen(ba *ct); #endif