-
Notifications
You must be signed in to change notification settings - Fork 12
/
simon.h
136 lines (119 loc) · 3.48 KB
/
simon.h
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
// ===========================================================================
// SIMON implementation and cryptanalytic methods
// =========================================================================
// Copyright (c) 2013 Martin M. Lauridsen and Hoda A. Alkhzaimi.
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef _SIMON_H_
#define _SIMON_H_
#include <stdint.h>
#include <string>
// Cipher setup parameters
#define BLOCK_SIZE (16)
#define KEY_WORDS (4)
#define PRINT_ROUND_KEYS (0)
// Rest of parameters are automated
#if (BLOCK_SIZE == 64)
#define WORD_MASK (0xffffffffffffffffull)
#else
#define WORD_MASK ((0x1ull << (BLOCK_SIZE&63)) - 1)
#endif
#define CONST_C ((0xffffffffffffffffull ^ 0x3ull) & WORD_MASK)
#if (BLOCK_SIZE == 4)
#define ROUNDS (32)
#define CONST_J (0)
#elif (BLOCK_SIZE == 16)
#define ROUNDS (32)
#define CONST_J (0)
#elif (BLOCK_SIZE == 24)
#if (KEY_WORDS == 3)
#define ROUNDS (36)
#define CONST_J (0)
#elif (KEY_WORDS == 4)
#define ROUNDS (36)
#define CONST_J (1)
#endif
#elif (BLOCK_SIZE == 32)
#if (KEY_WORDS == 3)
#define ROUNDS (42)
#define CONST_J (2)
#elif (KEY_WORDS == 4)
#define ROUNDS (44)
#define CONST_J (3)
#endif
#elif (BLOCK_SIZE == 48)
#if (KEY_WORDS == 2)
#define ROUNDS (52)
#define CONST_J (2)
#elif (KEY_WORDS == 3)
#define ROUNDS (54)
#define CONST_J (3)
#endif
#elif (BLOCK_SIZE == 64)
#if (KEY_WORDS == 2)
#define ROUNDS (68)
#define CONST_J (2)
#elif (KEY_WORDS == 3)
#define ROUNDS (69)
#define CONST_J (3)
#elif (KEY_WORDS == 4)
#define ROUNDS (72)
#define CONST_J (4)
#endif
#endif
#define STATE_MASK ((WORD_MASK << BLOCK_SIZE) | WORD_MASK)
typedef uint64_t u64;
extern u64 z[5][62];
extern u64 k[ROUNDS];
// HELPERS
char* binary(u64);
int weight(u64);
unsigned char lcs(char *, char *);
// CIPHER STUFF
u64 rotate(u64, int);
u64 F(u64);
u64 F_toy(u64);
void key_schedule();
void encrypt(u64 &, u64 &, int);
void encrypt(u64 &, u64 &);
void decrypt(u64 &, u64 &, int);
void decrypt(u64 &, u64 &);
void setup_random_key();
// TESTING
void run_test_vectors();
void test_enc();
// DIFFERENTIAL STUFF
void distribution_test();
void diff_dist_table();
void test_differential(u64, u64, u64, u64, int);
void diff_attack(u64, u64, u64, u64, int);
void test_2r_difference(u64);
void ddt_diagonal();
void differences_to_zero_diff();
// ROTATIONAL STUFF
void rotational_approx();
// WEAK KEYS STUFF
void weak_keys();
void test_rotational();
void test_key_rotation();
void is_F_balanced();
void generate_key_relations(unsigned int);
void key_difference();
// IMPOSSIBLE DIFFERENTIAL STUFF
std::string rotchar(std::string, unsigned int);
unsigned short cweight(std::string);
std::string cxor(std::string, std::string);
std::string rot_func(std::string);
void impossible_diff_attack();
int impossible_diff(std::string, std::string);
void imp_diff_attack2();
#endif