-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwarp.c
240 lines (213 loc) · 6.81 KB
/
warp.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
/*********************************************
* Reference implementation by WARP Team *
**********************************************/
#include <stdio.h>
#include <stdlib.h> // rand(), srand()
#include <time.h> // time()
#include <sys/random.h>
// #define R 41 /*round number*/
#define RN 6 /*rotation number*/
#define BR 32 /*brunch number*/
#define BR_HALF (BR / 2) /*half of the branch number*/
int Sbox[BR_HALF] = { 0xc, 0xa, 0xd, 0x3, 0xe, 0xb, 0xf, 0x7, 0x8, 0x9, 0x1, 0x5, 0x0, 0x2, 0x4, 0x6 };
int perm[BR] = { 31, 6, 29, 14, 1, 12, 21, 8, 27, 2, 3, 0, 25, 4, 23, 10, 15, 22, 13, 30, 17, 28, 5, 24, 11, 18, 19, 16, 9, 20, 7, 26, };
int RC0[41] = { 0x0U, 0x0U, 0x1U, 0x3U, 0x7U, 0xfU, 0xfU, 0xfU, 0xeU, 0xdU, 0xaU, 0x5U, 0xaU, 0x5U, 0xbU, 0x6U, 0xcU, 0x9U, 0x3U, 0x6U, 0xdU, 0xbU, 0x7U, 0xeU, 0xdU, 0xbU, 0x6U, 0xdU, 0xaU, 0x4U, 0x9U, 0x2U, 0x4U, 0x9U, 0x3U, 0x7U, 0xeU, 0xcU, 0x8U, 0x1U, 0x2U};
int RC1[41] = { 0x4U, 0xcU, 0xcU, 0xcU, 0xcU, 0xcU, 0x8U, 0x4U, 0x8U, 0x4U, 0x8U, 0x4U, 0xcU, 0x8U, 0x0U, 0x4U, 0xcU, 0x8U, 0x4U, 0xcU, 0xcU, 0x8U, 0x4U, 0xcU, 0x8U, 0x4U, 0x8U, 0x0U, 0x4U, 0x8U, 0x0U, 0x4U, 0xcU, 0xcU, 0x8U, 0x0U, 0x0U, 0x4U, 0x8U, 0x4U, 0xcU};
void enc(int *m, int *c, int *k, int nr);
void sboxkey(int *state, int *k, int r);
void permutation(int *state);
#define PRINT_INTER 0
void init_prng() {
unsigned int initial_seed = -1;
ssize_t temp;
temp = getrandom(&initial_seed, sizeof(initial_seed), 0);
srand(initial_seed); // Initialization, should only be called once. int r = rand();
printf("[x] PRNG initialized by %lu random bytes: 0x%08X\n", temp, initial_seed);
}
void print_target_bits(int *collected_ciphers, int ns, int *selected_positions)
{
int random_position;
int nibble;
int bp;
int target_bit;
printf("target positions: ");
for (int bit = 0; bit < ns; bit++)
{
nibble = selected_positions[bit] / 4;
bp = selected_positions[bit] % 4;
target_bit = ((collected_ciphers[nibble]) >> (3 - bp)) & 0x1;
printf("%d", target_bit);
}
printf("\nrandom positions: ");
for (int bit = 0; bit < ns; bit++)
{
random_position = rand() % 128;
nibble = random_position / 4;
bp = random_position % 4;
target_bit = ((collected_ciphers[nibble]) >> (4 - bp)) & 0x1;
printf("%d", target_bit);
}
printf("\n");
}
void print_state(int *m)
{
for (int i = 0; i < BR; i++)
{
printf("%x ", m[i]&0xf);
}
printf("\n");
};
void printState(int *state)
{
printf("L: ");
for (int x = 0; x < BR_HALF; x++)
{
printf("%x ", state[2 * x + 0]);
}
printf("R: ");
for (int x = 0; x < BR_HALF; x++)
{
printf("%x ", state[2 * x + 1]);
}
printf("\n");
}
int main()
{
init_prng();
// Randomly generate master key
int k[BR];
for (int i = 0; i < BR; i++)
k[i] = rand() & 0xf;
// Randomly generate a plaintext
int m[BR];
for (int i = 0; i < BR; i++)
m[i] = rand() & 0xf;
// Randomly generate a ciphertext
int c[BR];
for (int i = 0; i < BR; i++)
c[i] = rand() & 0xf;
int collected_ciphers[BR] = {0};
//####################################################
//####################################################
//####################################################
// Output of our Python program:
int NUMBER_OF_ROUNDS = 14;
int na = 5;
int nb = 20;
int active_nibbles[5] = {6, 7, 8, 9, 29};
int balanced_positions[20] = {52, 53, 54, 55, 60, 61, 62, 63, 68, 69, 70, 71, 100, 101, 102, 103, 124, 125, 126, 127};
//####################################################
//####################################################
//####################################################
// /*key*/
// printf("key :\n");
// print_state(k);
// /*plaintext*/
// printf("plaintext :\n");
// print_state(m);
// enc(m, c, k, NUMBER_OF_ROUNDS);
// /*ciphertext*/
// printf("ciphertext :\n");
// print_state(c);
// printf("\n");
unsigned long long int upper_bound = (long long int) 1 << (4*na);
for (unsigned long long int ti = 0; ti < upper_bound; ti++)
{
for (int nibble = 0; nibble < na; nibble++)
{
m[active_nibbles[nibble]] = (ti >> 4*nibble) & 0xf;
}
enc(m, c, k, NUMBER_OF_ROUNDS);
// print_state(c);
for (int output_nibble = 0; output_nibble < BR; output_nibble++)
{
collected_ciphers[output_nibble] ^= c[output_nibble];
}
}
print_state(collected_ciphers);
print_target_bits(collected_ciphers, nb, balanced_positions);
return 0;
}
void enc(int *m, int *c, int *k, int R)
{
/*intermediate value*/
int state[BR];
/*left half intermediate value*/
int temp[BR_HALF];
for (int i = 0; i < BR; i++)
{
state[i] = m[i];
}
/*round function(1 to 40 round)*/
for (int i = 0; i < R; i++)
{
#if PRINT_INTER
printf("%d round\n", i + 1);
printState(state);
#endif
for (int j = 0; j < BR_HALF; j++)
{
temp[j] = state[j * 2];
}
/*insert key and Sbox*/
sboxkey(temp, k, i);
/*XOR*/
for (int j = 0; j < BR_HALF; j++)
{
state[2 * j + 1] = state[2 * j + 1] ^ temp[j];
}
/*add round constants*/
state[1] = state[1] ^ RC0[i];
state[3] = state[3] ^ RC1[i];
/*permutation*/
permutation(state);
}
/*last round function */
#if PRINT_INTER
printf("%d round\n", R);
printState(state);
#endif
// Deactivate last partial round
// for (int j = 0; j < BR_HALF; j++)
// {
// temp[j] = state[j * 2];
// }
// /*input key and Sbox*/
// sboxkey(temp, k, R - 1);
// /*xor*/
// for (int j = 0; j < BR_HALF; j++)
// {
// state[2 * j + 1] = state[2 * j + 1] ^ temp[j];
// }
// /*add round constants*/
// state[1] = state[1] ^ RC0[R-1];
// state[3] = state[3] ^ RC1[R-1];
#if PRINT_INTER
printState(state);
#endif
/*no permutation in the last round*/
/*copy ciphertext*/
for (int i = 0; i < BR; i++)
{
c[i] = state[i];
}
}
void sboxkey(int *state, int *k, int r)
{
for (int i = 0; i < BR_HALF; i++)
{
state[i] = Sbox[state[i]] ^ k[(r % 2) * 16 + i];
}
}
void permutation(int *state)
{
int temp[BR];
for (int j = 0; j < BR; j++)
{
temp[j] = state[j];
}
for (int j = 0; j < BR; j++)
{
state[perm[j]] = temp[j];
}
}