cryptopals_c

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

block.c (1609B)


      1 #include "block.h"
      2 
      3 
      4 static int split_to_chunks(ba *src, uint16_t block_size, uint16_t chunks_n,
      5                            ba *dest[chunks_n])
      6 {
      7 	int i;
      8 
      9 	for (i = 0; i < chunks_n; i++)
     10 		dest[i] = ba_alloc(block_size);
     11 
     12 	i = 0;
     13 	while (i < src->len)
     14 		dest[(i)/block_size]->val[(i++)%block_size] = src->val[i];
     15 
     16 	while (i < block_size * chunks_n)
     17 		dest[i/chunks_n]->val[(i++)%chunks_n] = 0;
     18 
     19 	return 0;
     20 }
     21 
     22 static int unsplit_from_chunks(ba **dest, uint16_t block_size, uint16_t chunks_n,
     23                                ba *src[chunks_n])
     24 {
     25 	int ct_size;
     26 	int i;
     27 
     28 	ct_size = block_size * chunks_n;
     29 	*dest = ba_alloc(ct_size);
     30 
     31 	i = 0;
     32 	while (i < ct_size)
     33 		(*dest)->val[i++] = src[(i)/block_size]->val[(i)%block_size];
     34 
     35 	return 0;
     36 }
     37 
     38 int encrypt_ecb(ba *plaintext, ba *key, ba **ciphertext, uint16_t block_size,
     39                 int (* encrypt) (ba *, ba *, ba **))
     40 {
     41 	uint16_t chunks_n = (plaintext->len / block_size) +
     42 	                    (plaintext->len % block_size == 1);
     43 	ba *ct_chunks[chunks_n];
     44 	ba *chunks[chunks_n];
     45 
     46 	split_to_chunks(plaintext, block_size, chunks_n, chunks);
     47 	for (int i = 0; i < chunks_n; i++) {
     48 		ct_chunks[i] = ba_alloc(block_size);
     49 
     50 		encrypt(chunks[i], key, &ct_chunks[i]);
     51 		ba_free(chunks[i]);
     52 	}
     53 
     54 	unsplit_from_chunks(ciphertext, block_size, chunks_n, ct_chunks);
     55 
     56 	for (int i = 0; i < chunks_n; i++)
     57 		ba_free(ct_chunks[i]);
     58 
     59 	return 0;
     60 }
     61 
     62 int decrypt_ecb(ba *ciphertext, ba *key, ba **plaintext, uint16_t block_size,
     63                 int (* decrypt) (ba *, ba *, ba **))
     64 {
     65 	/* this is symmetric */
     66 	return encrypt_ecb(ciphertext, key, plaintext, block_size, decrypt);
     67 }