2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
18 #include <kripto/cast.h>
19 #include <kripto/loadstore.h>
20 #include <kripto/rotate.h>
21 #include <kripto/memwipe.h>
22 #include <kripto/block.h>
23 #include <kripto/desc/block.h>
24 #include <kripto/object/block.h>
26 #include <kripto/block/simon128.h>
30 struct kripto_block_object obj
;
36 #define F(X) ((ROL64_01(X) & ROL64_08(X)) ^ ROL64_02(X))
38 static void simon128_encrypt
40 const kripto_block
*s
,
50 b
= LOAD64B(CU8(pt
) + 8);
54 b
^= F(a
) ^ s
->k
[i
++];
58 STORE64B(a
, U8(ct
) + 8);
63 a
^= F(b
) ^ s
->k
[i
++];
67 STORE64B(b
, U8(ct
) + 8);
70 static void simon128_decrypt
72 const kripto_block
*s
,
79 unsigned int i
= s
->rounds
;
82 b
= LOAD64B(CU8(ct
) + 8);
86 a
^= F(b
) ^ s
->k
[--i
];
90 STORE64B(a
, U8(pt
) + 8);
95 b
^= F(a
) ^ s
->k
[--i
];
99 STORE64B(b
, U8(pt
) + 8);
102 static const uint64_t z
[3] =
109 static void simon128_setup
123 for(i
= 0; i
< m
; i
++)
126 for(i
= 0; i
< len
; i
++)
127 s
->k
[m
- 1 - (i
>> 3)] |=
128 (uint64_t)key
[i
] << (56 - ((i
& 7) << 3));
130 for(i
= m
; i
< s
->rounds
; i
++)
132 t
= ROR64_03(s
->k
[i
- 1]);
133 if(m
== 4) t
^= s
->k
[i
- 3];
134 t
^= ROR64_01(t
) ^ ~s
->k
[i
- m
] ^ 3;
135 s
->k
[i
] = t
^ ((z
[m
- 2] >> ((i
- m
) % 62)) & 1);
138 kripto_memwipe(&t
, sizeof(uint64_t));
141 static kripto_block
*simon128_create
152 switch((key_len
+ 7) >> 3)
154 case 3: r
= 69; break;
155 case 4: r
= 72; break;
156 default: r
= 68; break;
160 s
= malloc(sizeof(kripto_block
) + (r
<< 3));
163 s
->obj
.desc
= kripto_block_simon128
;
164 s
->size
= sizeof(kripto_block
) + (r
<< 3);
165 s
->k
= (uint64_t *)(((uint8_t *)s
) + sizeof(kripto_block
));
168 simon128_setup(s
, key
, key_len
);
173 static void simon128_destroy(kripto_block
*s
)
175 kripto_memwipe(s
, s
->size
);
179 static kripto_block
*simon128_recreate
189 switch((key_len
+ 7) >> 3)
191 case 3: r
= 69; break;
192 case 4: r
= 72; break;
193 default: r
= 68; break;
197 if(sizeof(kripto_block
) + (r
<< 3) > s
->size
)
200 s
= simon128_create(r
, key
, key_len
);
205 simon128_setup(s
, key
, key_len
);
211 static const kripto_block_desc simon128
=
223 const kripto_block_desc
*const kripto_block_simon128
= &simon128
;