-
Notifications
You must be signed in to change notification settings - Fork 1
/
Extract.c
280 lines (231 loc) · 6.7 KB
/
Extract.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#include <stdio.h>
#include <stdlib.h>
#include "eccwrapper.h"
#include "FeistelPRP.h"
#include "encwrapper.h"
#include "math.h"
#define alpha 10
#define delta 0.25
#define BLOCK_SIZE 32
#define n 255
#define k 233
#define d 32
#define w 4096
#define v 1024
//Challenge structure
typedef struct {
int j;
int k_j_c;
int u;
}chal;
//decoding file blocks structure
typedef struct {
char ** file_blocks;
int * frequency;
} decoding;
void inner_decoding(decoding *d1, char * codeword, int * v_chal_indices);
int extract(int t,unsigned char * masterkey, int * prptable, char * filename){
decoding * d1;
int i,j,u,size,index;
char * codeword,mac;
chal * c;
unsigned char * k_chal, k_j_c, k_ecc_perm, k_ecc_enc, k_mac;
char ** F;
char str[999];
FILE *fp1,*fp2;
char * r_file="recovered";
int * v_chal_indices;
//use master key and call keygen to generate all the keys here.
//use new function written by Jie.
keygen(masterkey);
//open encoded file for reading
if ((fp1 = fopen(filename, "r")) == NULL){
printf("couldn't open input file for reading.\n");
return -1;
}
//open output file for writing
if ((fp2 = fopen(r_file, "w")) == NULL){
printf("couldn't open output file for writing.\n");
return -1;
}
//allocate memory for d1
d1 = (decoding *) malloc (sizeof(decoding)*alpha*t);
if(d1 == NULL) {
fprintf(stderr, "failed to allocate memory for d.\n");
return -1;
}
size = alpha*(t/v);
//allocate memory for the challenge set
if ((c = (chal *)malloc(sizeof(chal)*size))== NULL) {
fprintf(stderr, "failed to allocate memory for challenges.\n");
return -1;
}
// populate challenge set
for (j=0;j<size;j++){
k_j_c = generateSeed(k_chal);
c[j].j = j;
c[j].k_j_c = k_j_c;
}
//execute each challenge w times
for (i=0;i<size;i++){
//not sure if output of the challenge is a single array or double
unsigned char * codeword = (unsigned char *) malloc(sizeof(unsigned char)*32*w);
if (codeword == NULL) {
fprintf(stderr, "failed to allocate memory for codeword.\n");
return -1;
}
if((v_chal_indices=(int *)malloc(sizeof(int)*v))==NULL){
fprintf(stderr, "failed to allocate memory for v indices.\n");
return -1;
}
index = 0;
for(u=1;u<=w;u++){
//execute challenge returns Qj : call up function of Rucha
codeword[index] = execute_challenge(c[i].j, c[i].k_j_c, u, v_chal_indices);
index=index+32;
}
// inner code decoding
inner_decoding(d1,codeword,v_chal_indices);
}
//array to store byte location of the erasures
int * erasureLocs = (int *) malloc(sizeof(int)*t);
int e_index=0;
for (i=1;i<=t;i++){
int max_frequency=0;
int max_index=0;
for(j=0;j<sizeof(d1[i].frequency);j++){
if(d1[i].frequency[j] > max_frequency){
max_frequency = d1[i].frequency[j];
max_index = j;
}
}
//check if the location can be corrected or has erasure
if(ceil(max_frequency / sizeof(d1[i].frequency)) > (delta+0.5)){
F[i] = (char *) malloc ( sizeof(char)*sizeof(d1[i].file_blocks[j]));
strcpy(F[i],d1[i].file_blocks[j]);
}else{
erasureLocs[e_index++] = j;
}
}
//perform outer decoding
outer_decoding(F,fp2,prptable,k_ecc_perm,k_ecc_enc);
//compute new mac and verify against old one
unsigned char originalmac[16];
int bufLength=16;
fseek(fp1, 0, SEEK_END);
long fileLength=ftell(fp1);
fseek(fp1, fileLength-bufLength, SEEK_SET);
fread(&originalmac, sizeof(originalmac), 1, fp1);
//compute mac
unsigned char * newmac;
hmac(r_file,newmac,k_mac);
//if verified, print the file. Else output the error
if (strcmp(newmac,originalmac)==0){
printf("Your file is recovered");
while (fscanf(fp2, "%s", str)!=EOF){
printf("%s",str);
}
}else{
printf("Your file can not be recovered.");
return -1;
}
fclose(fp1);
fclose(fp2);
return 0;
}
/* 1. decrypt the parity block using key k3
2. decode using key k2
3. unpermute all parity blocks and store
4. for the permutted message, get each of the strip , append it with parity.
5. deocode using ecc out
6. we will get permutted file
7. unpermute it using pRP table
*/
/*Input parameters :
1. original file pointer
2. int array for erasure locations
3. recovered data from challenges
4. prp table
5. keys for permutation and encryption*/
int outer_decoding (FILE* fp,int * erasureLocs,char ** r_data,int* prptable,unsigned char* k_ecc_perm,unsigned char* k_ecc_enc)
{
int i,j,blocks,fileLen,index;
//find the numebr of blocks in the file
fseek(fp,0,SEEK_END);
fileLen = ftell(fp);
if(fileLen % k==0)
blocks = fileLen/k;
else
blocks = fileLen/k+1;
char message[k];
char codeword[n];
char parity[blocks][d];
char decodedfile[blocks][k];
//read all the parity blocks, decrypt and unpermute
prptable =(int *)malloc(sizeof(int)*blocks);
prptable = prp(blocks, k_ecc_perm);
enc_init(k_ecc_enc);
//decrypt parity part
for (i=0;i<blocks;i++) {
unsigned char ct[d];
decrypt(ct,r_data[i+blocks]);
for(j=0;j<d;j++){
parity[i][j]=ct[j];
}
}
//get the message and the parity, create codeword and decode it
for(i=0;i<blocks;i++) {
index=0;
for(j=0;j<k;j++) {
codeword[index++] = r_data[i][j];
}
//calculate block index of the parity part
int original_index = prptable[i];
int parity_index = (original_index*32);
for(j=0;j<d;j++){
codeword[index++]=parity[parity_index][j];
}
decode_data(codeword,n);
strcpy(decodedfile[i*k],codeword);
}
//correct erasures
unsigned char * r_erasure;
correct_errors_erasures(r_erasure, sizeof(erasureLocs)*k,sizeof(erasureLocs), erasureLocs);
// write data to the file
for(i=0;i<blocks;i++){
int index=0;
if(erasureLocs[i] == i){
fwrite(r_erasure,k,1,fp);
index++;
}
else{
fwrite(r_data[i-index],k,1,fp);
}
}
fclose(fp);
return 0;
}
void inner_decoding(decoding *d1, char * codeword, int * v_chal_indices){
int i=0,j=0;
char block[32];
//erasure should be empty array?
int erasure[1];
//corrected codeword would be in first parameter as well
correct_errors_erasures (codeword,sizeof(codeword),0,erasure);
//divide decoded message into v blocks from f1 to fv.
for(i=0;i<v;i++){
//divide codeword into 32 byte blocks
int fi = v_chal_indices[i];
for(j=0;j<32;j++){
block[j]=codeword[(i*32)+j];
}
for(j=0;j<sizeof(d1[fi].file_blocks);j++){
if(strcmp(d1[fi].file_blocks[j],block)){
int freq = d1[fi].frequency[j];
d1[fi].frequency[j] = freq++;
}
}
d1[fi].file_blocks[j] = block;
d1[fi].frequency[j] = 1;
}
}