Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
58 views
1
#include <stdio.h>
2
#include <string.h>
3
#include <stdlib.h>
4
#include "hex.h"
5
#include <assert.h>
6
7
8
9
/*The block cipher*/
10
char cipher(unsigned char block, char key)
11
{ //this is an affine cipher where "a" is fixed at 11 and b=key
12
return (key+11*block)%256;
13
}
14
15
/*The inverse of the block cipher*/
16
char inv_cipher(unsigned char block, char key)
17
{ // 163 is the inverse of 11 mod 256
18
return (163*(block-key+256))%256;
19
}
20
21
/*Code for galois multiplication borrowed from http://www.samiam.org/galois.html*/
22
unsigned char gmul(unsigned char a, unsigned char b) {
23
unsigned char p = 0;
24
unsigned char counter;
25
unsigned char hi_bit_set;
26
for(counter = 0; counter < 8; counter++) {
27
if((b & 1) == 1)
28
p ^= a;
29
hi_bit_set = (a & 0x80);
30
a <<= 1;
31
if(hi_bit_set == 0x80)
32
a ^= 0x1b;
33
b >>= 1;
34
}
35
return p;
36
}
37
38
39
unsigned char simple_gcm(char* pt, char key, char iv, int len, char aad)
40
{
41
/*Encrypts pt in CTR mode and returns a GCM MAC tag for the ciphertext*/
42
/*Please use the gmul() function, above, for Galois multiplication*/
43
/*Follow the diagram on page 135 of Understanding Cryptography to implement this function*/
44
iv &= 0xF8; //use only left 5 bits
45
unsigned char g; //the GCM mac value
46
int i =0, ctr=0;
47
/*missing things here*/
48
for(i=0; i < len;i++)
49
{
50
ctr &= 0x7; //use only right 3 bits
51
/*missing things here*/
52
ctr++;
53
}
54
/*missing things here*/
55
return g;
56
}
57
58
#define VALID 1
59
#define INVALID 0
60
61
/*This function replaces each byte of ct with the decrypted plaintext.
62
It returns VALID if the gcm tag of ct matches the parameter called "tag".
63
It returns INVALID otherwise */
64
int gcm_decrypt_and_validate(char* ct, char key, char iv, int len, char aad, char tag)
65
{
66
return VALID;
67
}
68
69
void print_ct(char* ct,int len)
70
{
71
printf("ciphertext: 0x%s\n",bin2hex(ct,len));
72
}
73
74
/*Book errata: http://wiki.crypto.rub.de/Buch/en/download/Errata.pdf*/
75
76
77
/* Desired output:
78
79
~/Crypto_Spring_18/proj4$ gcc *.c
80
~/Crypto_Spring_18/proj4$ ./a.out
81
plaintext: vote
82
ciphertext: 0x3D391509
83
tag: 0x8D
84
validating tag: valid
85
plaintext: outside
86
ciphertext: 0xC4C3B5BFBE8688
87
tag: 0xC4
88
validating tag: valid
89
plaintext: plate
90
ciphertext: 0xFBFAC0D8D2
91
tag: 0x45
92
validating tag: valid
93
plaintext: estate
94
ciphertext: 0xEEE5D5CDC3A7
95
tag: 0xAB
96
replacing tag with 0xAC
97
a.out: modes.c:160: main: Assertion `valid==VALID' failed.
98
validating tag: Aborted (core dumped)
99
100
*/
101
102
int main()
103
{
104
char key = 8;
105
char iv = 0xaa;
106
int len;
107
int a = 6;
108
char ct[1000] = {0};
109
char pt[12][100] = {"wife", "mother", "soldier", "risk", "endless", "hair", "vote", "outside", "plate", "estate", "slow", "baby"};
110
char ct_ark[12][100] = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}};
111
char aad = 37;
112
113
len = strlen(pt[a]);
114
strncpy(ct,pt[a],len);
115
printf("plaintext: %s\n",pt[a]);
116
char tag = simple_gcm(ct,key,iv,len,aad);
117
printf("ciphertext: 0x%s\n",bin2hex(ct,len));
118
printf("tag: 0x%s\n",bin2hex(&tag,1));
119
strncpy(ct_ark[a],ct,len);
120
printf("validating tag: ");
121
int valid = gcm_decrypt_and_validate(ct,key,iv,len,aad,tag);
122
assert(valid==VALID);
123
assert(strncmp(ct,pt[a],len)==0);
124
printf(" valid\n");
125
126
a++;
127
iv = 0xc9;
128
aad = 22;
129
len = strlen(pt[a]);
130
strncpy(ct,pt[a],len);
131
printf("plaintext: %s\n",pt[a]);
132
tag = simple_gcm(ct,key,iv,len,aad);
133
printf("ciphertext: 0x%s\n",bin2hex(ct,len));
134
printf("tag: 0x%s\n",bin2hex(&tag,1));
135
strncpy(ct_ark[a],ct,len);
136
printf("validating tag: ");
137
valid = gcm_decrypt_and_validate(ct,key,iv,len,aad,tag);
138
assert(valid==VALID);
139
assert(strncmp(ct,pt[a],len)==0);
140
printf(" valid\n");
141
142
a++;
143
iv = 0x69;
144
aad = 200;
145
len = strlen(pt[a]);
146
strncpy(ct,pt[a],len);
147
printf("plaintext: %s\n",pt[a]);
148
tag = simple_gcm(ct,key,iv,len,aad);
149
printf("ciphertext: 0x%s\n",bin2hex(ct,len));
150
printf("tag: 0x%s\n",bin2hex(&tag,1));
151
strncpy(ct_ark[a],ct,len);
152
printf("validating tag: ");
153
valid = gcm_decrypt_and_validate(ct,key,iv,len,aad,tag);
154
assert(valid==VALID);
155
assert(strncmp(ct,pt[a],len)==0);
156
printf(" valid\n");
157
158
a++;
159
iv = 0x69;
160
aad = 200;
161
len = strlen(pt[a]);
162
strncpy(ct,pt[a],len);
163
printf("plaintext: %s\n",pt[a]);
164
tag = simple_gcm(ct,key,iv,len,aad);
165
printf("ciphertext: 0x%s\n",bin2hex(ct,len));
166
printf("tag: 0x%s\n",bin2hex(&tag,1));
167
strncpy(ct_ark[a],ct,len);
168
tag++;
169
printf("replacing tag with 0x%s\n",bin2hex(&tag,1));
170
printf("validating tag: ");
171
valid = gcm_decrypt_and_validate(ct,key,iv,len,aad,tag);
172
assert(valid==VALID);
173
assert(strncmp(ct,pt[a],len)==0);
174
printf(" valid\n");
175
}
176