serpent-sboxes-bitslice.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /* serpent-sboxes-bitslice.c */
  2. /*
  3. This file is part of the ARM-Crypto-Lib.
  4. Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /* serpent-sboxes.c
  17. * a bitsliced implementation of the serpent sboxes
  18. * author: Daniel Otte
  19. * email: daniel.otte@rub.de
  20. * license: GPLv3
  21. */
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include <crypto/serpent-sboxes.h>
  25. /* S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12 */
  26. /* depth = 5,7,4,2, Total gates=18 */
  27. static
  28. void sb0(uint8_t* out, const uint8_t* in){
  29. // (a,b,c,d,w,x,y,z)
  30. uint8_t t01, t02, t03, t05, t06, t07, t08, t09, t11, t12, t13, t14, t15, t17;
  31. t01 = in[4*1] ^ in[4*2];
  32. t02 = in[4*0] | in[4*3];
  33. t03 = in[4*0] ^ in[4*1];
  34. out[4*3] = t02 ^ t01;
  35. t05 = in[4*2] | out[4*3];
  36. t06 = in[4*0] ^ in[4*3];
  37. t07 = in[4*1] | in[4*2];
  38. t08 = in[4*3] & t05;
  39. t09 = t03 & t07;
  40. out[4*2] = t09 ^ t08;
  41. t11 = t09 & out[4*2];
  42. t12 = in[4*2] ^ in[4*3];
  43. t13 = t07 ^ t11;
  44. t14 = in[4*1] & t06;
  45. t15 = t06 ^ t13;
  46. out[4*0] = ~ t15;
  47. t17 = out[4*0] ^ t14;
  48. out[4*1] = t12 ^ t17;
  49. }
  50. /* InvS0: 13 3 11 0 10 6 5 12 1 14 4 7 15 9 8 2 */
  51. /* depth = 8,4,3,6, Total gates=19 */
  52. static
  53. void sb0_inv(uint8_t* out, const uint8_t* in){
  54. uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t12, t13, t14, t15, t17, t18, t01;
  55. t01 = in[4*2] ^ in[4*3];
  56. t02 = in[4*0] | in[4*1];
  57. t03 = in[4*1] | in[4*2];
  58. t04 = in[4*2] & t01;
  59. t05 = t02 ^ t01;
  60. t06 = in[4*0] | t04;
  61. out[4*2] = ~ t05;
  62. t08 = in[4*1] ^ in[4*3];
  63. t09 = t03 & t08;
  64. t10 = in[4*3] | out[4*2];
  65. out[4*1] = t09 ^ t06;
  66. t12 = in[4*0] | t05;
  67. t13 = out[4*1] ^ t12;
  68. t14 = t03 ^ t10;
  69. t15 = in[4*0] ^ in[4*2];
  70. out[4*3] = t14 ^ t13;
  71. t17 = t05 & t13;
  72. t18 = t14 | t17;
  73. out[4*0] = t15 ^ t18;
  74. }
  75. /* S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4 */
  76. /* depth = 10,7,3,5, Total gates=18 */
  77. static
  78. void sb1(uint8_t* out, const uint8_t* in){
  79. uint8_t t02, t03, t04, t05, t06, t07, t08, t10, t11, t12, t13, t16, t17, t01;
  80. t01 = in[4*0] | in[4*3];
  81. t02 = in[4*2] ^ in[4*3];
  82. t03 = ~ in[4*1];
  83. t04 = in[4*0] ^ in[4*2];
  84. t05 = in[4*0] | t03;
  85. t06 = in[4*3] & t04;
  86. t07 = t01 & t02;
  87. t08 = in[4*1] | t06;
  88. out[4*2] = t02 ^ t05;
  89. t10 = t07 ^ t08;
  90. t11 = t01 ^ t10;
  91. t12 = out[4*2] ^ t11;
  92. t13 = in[4*1] & in[4*3];
  93. out[4*3] = ~ t10;
  94. out[4*1] = t13 ^ t12;
  95. t16 = t10 | out[4*1];
  96. t17 = t05 & t16;
  97. out[4*0] = in[4*2] ^ t17;
  98. }
  99. /* InvS1: 5 8 2 14 15 6 12 3 11 4 7 9 1 13 10 0 */
  100. /* depth = 7,4,5,3, Total gates=18 */
  101. static void sb1_inv(uint8_t* out, const uint8_t* in){
  102. uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t14, t15, t17, t01;
  103. t01 = in[4*0] ^ in[4*1];
  104. t02 = in[4*1] | in[4*3];
  105. t03 = in[4*0] & in[4*2];
  106. t04 = in[4*2] ^ t02;
  107. t05 = in[4*0] | t04;
  108. t06 = t01 & t05;
  109. t07 = in[4*3] | t03;
  110. t08 = in[4*1] ^ t06;
  111. t09 = t07 ^ t06;
  112. t10 = t04 | t03;
  113. t11 = in[4*3] & t08;
  114. out[4*2] = ~ t09;
  115. out[4*1] = t10 ^ t11;
  116. t14 = in[4*0] | out[4*2];
  117. t15 = t06 ^ out[4*1];
  118. out[4*3] = t01 ^ t04;
  119. t17 = in[4*2] ^ t15;
  120. out[4*0] = t14 ^ t17;
  121. }
  122. /* S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2 */
  123. /* depth = 3,8,11,7, Total gates=16 */
  124. static void sb2(uint8_t* out, const uint8_t* in){
  125. uint8_t t02, t03, t05, t06, t07, t08, t09, t10, t12, t13, t14, t01;
  126. t01 = in[4*0] | in[4*2];
  127. t02 = in[4*0] ^ in[4*1];
  128. t03 = in[4*3] ^ t01;
  129. out[4*0] = t02 ^ t03;
  130. t05 = in[4*2] ^ out[4*0];
  131. t06 = in[4*1] ^ t05;
  132. t07 = in[4*1] | t05;
  133. t08 = t01 & t06;
  134. t09 = t03 ^ t07;
  135. t10 = t02 | t09;
  136. out[4*1] = t10 ^ t08;
  137. t12 = in[4*0] | in[4*3];
  138. t13 = t09 ^ out[4*1];
  139. t14 = in[4*1] ^ t13;
  140. out[4*3] = ~ t09;
  141. out[4*2] = t12 ^ t14;
  142. }
  143. /* InvS2: 12 9 15 4 11 14 1 2 0 3 6 13 5 8 10 7 */
  144. /* depth = 3,6,8,3, Total gates=18 */
  145. static void sb2_inv(uint8_t* out, const uint8_t* in){
  146. uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t12, t15, t16, t17, t01;
  147. t01 = in[4*0] ^ in[4*3];
  148. t02 = in[4*2] ^ in[4*3];
  149. t03 = in[4*0] & in[4*2];
  150. t04 = in[4*1] | t02;
  151. out[4*0] = t01 ^ t04;
  152. t06 = in[4*0] | in[4*2];
  153. t07 = in[4*3] | out[4*0];
  154. t08 = ~ in[4*3];
  155. t09 = in[4*1] & t06;
  156. t10 = t08 | t03;
  157. t11 = in[4*1] & t07;
  158. t12 = t06 & t02;
  159. out[4*3] = t09 ^ t10;
  160. out[4*1] = t12 ^ t11;
  161. t15 = in[4*2] & out[4*3];
  162. t16 = out[4*0] ^ out[4*1];
  163. t17 = t10 ^ t15;
  164. out[4*2] = t16 ^ t17;
  165. }
  166. /* S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14 */
  167. /* depth = 8,3,5,5, Total gates=18 */
  168. static void sb3(uint8_t* out, const uint8_t* in){
  169. uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t13, t14, t15, t01;
  170. t01 = in[4*0] ^ in[4*2];
  171. t02 = in[4*0] | in[4*3];
  172. t03 = in[4*0] & in[4*3];
  173. t04 = t01 & t02;
  174. t05 = in[4*1] | t03;
  175. t06 = in[4*0] & in[4*1];
  176. t07 = in[4*3] ^ t04;
  177. t08 = in[4*2] | t06;
  178. t09 = in[4*1] ^ t07;
  179. t10 = in[4*3] & t05;
  180. t11 = t02 ^ t10;
  181. out[4*3] = t08 ^ t09;
  182. t13 = in[4*3] | out[4*3];
  183. t14 = in[4*0] | t07;
  184. t15 = in[4*1] & t13;
  185. out[4*2] = t08 ^ t11;
  186. out[4*0] = t14 ^ t15;
  187. out[4*1] = t05 ^ t04;
  188. }
  189. /* InvS3: 0 9 10 7 11 14 6 13 3 5 12 2 4 8 15 1 */
  190. /* depth = 3,6,4,4, Total gates=17 */
  191. static void sb3_inv(uint8_t* out, const uint8_t* in){
  192. uint8_t t02, t03, t04, t05, t06, t07, t09, t11, t12, t13, t14, t16, t01;
  193. t01 = in[4*2] | in[4*3];
  194. t02 = in[4*0] | in[4*3];
  195. t03 = in[4*2] ^ t02;
  196. t04 = in[4*1] ^ t02;
  197. t05 = in[4*0] ^ in[4*3];
  198. t06 = t04 & t03;
  199. t07 = in[4*1] & t01;
  200. out[4*2] = t05 ^ t06;
  201. t09 = in[4*0] ^ t03;
  202. out[4*0] = t07 ^ t03;
  203. t11 = out[4*0] | t05;
  204. t12 = t09 & t11;
  205. t13 = in[4*0] & out[4*2];
  206. t14 = t01 ^ t05;
  207. out[4*1] = in[4*1] ^ t12;
  208. t16 = in[4*1] | t13;
  209. out[4*3] = t14 ^ t16;
  210. }
  211. /* S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13 */
  212. /* depth = 6,7,5,3, Total gates=19 */
  213. static void sb4(uint8_t* out, const uint8_t* in){
  214. uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t12, t13, t14, t15, t16, t01;
  215. t01 = in[4*0] | in[4*1];
  216. t02 = in[4*1] | in[4*2];
  217. t03 = in[4*0] ^ t02;
  218. t04 = in[4*1] ^ in[4*3];
  219. t05 = in[4*3] | t03;
  220. t06 = in[4*3] & t01;
  221. out[4*3] = t03 ^ t06;
  222. t08 = out[4*3] & t04;
  223. t09 = t04 & t05;
  224. t10 = in[4*2] ^ t06;
  225. t11 = in[4*1] & in[4*2];
  226. t12 = t04 ^ t08;
  227. t13 = t11 | t03;
  228. t14 = t10 ^ t09;
  229. t15 = in[4*0] & t05;
  230. t16 = t11 | t12;
  231. out[4*2] = t13 ^ t08;
  232. out[4*1] = t15 ^ t16;
  233. out[4*0] = ~ t14;
  234. }
  235. /* InvS4: 5 0 8 3 10 9 7 14 2 12 11 6 4 15 13 1 */
  236. /* depth = 6,4,7,3, Total gates=17 */
  237. static void sb4_inv(uint8_t* out, const uint8_t* in){
  238. uint8_t t02, t03, t04, t05, t06, t07, t09, t10, t11, t12, t13, t15, t01;
  239. t01 = in[4*1] | in[4*3];
  240. t02 = in[4*2] | in[4*3];
  241. t03 = in[4*0] & t01;
  242. t04 = in[4*1] ^ t02;
  243. t05 = in[4*2] ^ in[4*3];
  244. t06 = ~ t03;
  245. t07 = in[4*0] & t04;
  246. out[4*1] = t05 ^ t07;
  247. t09 = out[4*1] | t06;
  248. t10 = in[4*0] ^ t07;
  249. t11 = t01 ^ t09;
  250. t12 = in[4*3] ^ t04;
  251. t13 = in[4*2] | t10;
  252. out[4*3] = t03 ^ t12;
  253. t15 = in[4*0] ^ t04;
  254. out[4*2] = t11 ^ t13;
  255. out[4*0] = t15 ^ t09;
  256. }
  257. /* S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1 */
  258. /* depth = 4,6,8,6, Total gates=17 */
  259. static void sb5(uint8_t* out, const uint8_t* in){
  260. uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t14, t01;
  261. t01 = in[4*1] ^ in[4*3];
  262. t02 = in[4*1] | in[4*3];
  263. t03 = in[4*0] & t01;
  264. t04 = in[4*2] ^ t02;
  265. t05 = t03 ^ t04;
  266. out[4*0] = ~ t05;
  267. t07 = in[4*0] ^ t01;
  268. t08 = in[4*3] | out[4*0];
  269. t09 = in[4*1] | t05;
  270. t10 = in[4*3] ^ t08;
  271. t11 = in[4*1] | t07;
  272. t12 = t03 | out[4*0];
  273. t13 = t07 | t10;
  274. t14 = t01 ^ t11;
  275. out[4*2] = t09 ^ t13;
  276. out[4*1] = t07 ^ t08;
  277. out[4*3] = t12 ^ t14;
  278. }
  279. /* InvS5: 8 15 2 9 4 1 13 14 11 6 5 3 7 12 10 0 */
  280. /* depth = 4,6,9,7, Total gates=17 */
  281. static void sb5_inv(uint8_t* out, const uint8_t* in){
  282. uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t12, t13, t15, t16, t01;
  283. t01 = in[4*0] & in[4*3];
  284. t02 = in[4*2] ^ t01;
  285. t03 = in[4*0] ^ in[4*3];
  286. t04 = in[4*1] & t02;
  287. t05 = in[4*0] & in[4*2];
  288. out[4*0] = t03 ^ t04;
  289. t07 = in[4*0] & out[4*0];
  290. t08 = t01 ^ out[4*0];
  291. t09 = in[4*1] | t05;
  292. t10 = ~ in[4*1];
  293. out[4*1] = t08 ^ t09;
  294. t12 = t10 | t07;
  295. t13 = out[4*0] | out[4*1];
  296. out[4*3] = t02 ^ t12;
  297. t15 = t02 ^ t13;
  298. t16 = in[4*1] ^ in[4*3];
  299. out[4*2] = t16 ^ t15;
  300. }
  301. /* S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0 */
  302. /* depth = 8,3,6,3, Total gates=19 */
  303. static void sb6(uint8_t* out, const uint8_t* in){
  304. uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t15, t17, t18, t01;
  305. t01 = in[4*0] & in[4*3];
  306. t02 = in[4*1] ^ in[4*2];
  307. t03 = in[4*0] ^ in[4*3];
  308. t04 = t01 ^ t02;
  309. t05 = in[4*1] | in[4*2];
  310. out[4*1] = ~ t04;
  311. t07 = t03 & t05;
  312. t08 = in[4*1] & out[4*1];
  313. t09 = in[4*0] | in[4*2];
  314. t10 = t07 ^ t08;
  315. t11 = in[4*1] | in[4*3];
  316. t12 = in[4*2] ^ t11;
  317. t13 = t09 ^ t10;
  318. out[4*2] = ~ t13;
  319. t15 = out[4*1] & t03;
  320. out[4*3] = t12 ^ t07;
  321. t17 = in[4*0] ^ in[4*1];
  322. t18 = out[4*2] ^ t15;
  323. out[4*0] = t17 ^ t18;
  324. }
  325. /* InvS6: 15 10 1 13 5 3 6 0 4 9 14 7 2 12 8 11 */
  326. /* depth = 5,3,8,6, Total gates=19 */
  327. static void sb6_inv(uint8_t* out, const uint8_t* in){
  328. uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t12, t13, t14, t15, t16, t17, t01;
  329. t01 = in[4*0] ^ in[4*2];
  330. t02 = ~ in[4*2];
  331. t03 = in[4*1] & t01;
  332. t04 = in[4*1] | t02;
  333. t05 = in[4*3] | t03;
  334. t06 = in[4*1] ^ in[4*3];
  335. t07 = in[4*0] & t04;
  336. t08 = in[4*0] | t02;
  337. t09 = t07 ^ t05;
  338. out[4*1] = t06 ^ t08;
  339. out[4*0] = ~ t09;
  340. t12 = in[4*1] & out[4*0];
  341. t13 = t01 & t05;
  342. t14 = t01 ^ t12;
  343. t15 = t07 ^ t13;
  344. t16 = in[4*3] | t02;
  345. t17 = in[4*0] ^ out[4*1];
  346. out[4*3] = t17 ^ t15;
  347. out[4*2] = t16 ^ t14;
  348. }
  349. /* S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6 */
  350. /* depth = 10,7,10,4, Total gates=19 */
  351. static void sb7(uint8_t* out, const uint8_t* in){
  352. uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t13, t14, t15, t16, t17, t01;
  353. t01 = in[4*0] & in[4*2];
  354. t02 = ~ in[4*3];
  355. t03 = in[4*0] & t02;
  356. t04 = in[4*1] | t01;
  357. t05 = in[4*0] & in[4*1];
  358. t06 = in[4*2] ^ t04;
  359. out[4*3] = t03 ^ t06;
  360. t08 = in[4*2] | out[4*3];
  361. t09 = in[4*3] | t05;
  362. t10 = in[4*0] ^ t08;
  363. t11 = t04 & out[4*3];
  364. out[4*1] = t09 ^ t10;
  365. t13 = in[4*1] ^ out[4*1];
  366. t14 = t01 ^ out[4*1];
  367. t15 = in[4*2] ^ t05;
  368. t16 = t11 | t13;
  369. t17 = t02 | t14;
  370. out[4*0] = t15 ^ t17;
  371. out[4*2] = in[4*0] ^ t16;
  372. }
  373. /* InvS7: 3 0 6 13 9 14 15 8 5 12 11 7 10 1 4 2 */
  374. /* depth = 9,7,3,3, Total gates=18 */
  375. static void sb7_inv(uint8_t* out, const uint8_t* in){
  376. uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t13, t14, t15, t16, t01;
  377. t01 = in[4*0] & in[4*1];
  378. t02 = in[4*0] | in[4*1];
  379. t03 = in[4*2] | t01;
  380. t04 = in[4*3] & t02;
  381. out[4*3] = t03 ^ t04;
  382. t06 = in[4*1] ^ t04;
  383. t07 = in[4*3] ^ out[4*3];
  384. t08 = ~ t07;
  385. t09 = t06 | t08;
  386. t10 = in[4*1] ^ in[4*3];
  387. t11 = in[4*0] | in[4*3];
  388. out[4*1] = in[4*0] ^ t09;
  389. t13 = in[4*2] ^ t06;
  390. t14 = in[4*2] & t11;
  391. t15 = in[4*3] | out[4*1];
  392. t16 = t01 | t10;
  393. out[4*0] = t13 ^ t15;
  394. out[4*2] = t14 ^ t16;
  395. }
  396. typedef void(*sb_fpt)(uint8_t*, const uint8_t*);
  397. const sb_fpt sf_tab[]= {
  398. sb0, sb1, sb2, sb3,
  399. sb4, sb5, sb6, sb7
  400. };
  401. const sb_fpt sinvf_tab[] = {
  402. sb0_inv, sb1_inv, sb2_inv, sb3_inv,
  403. sb4_inv, sb5_inv, sb6_inv, sb7_inv
  404. };
  405. void sbox128(void * w, uint8_t box){
  406. uint8_t i, buffer[16];
  407. box &= 0x7;
  408. sb_fpt fp;
  409. fp = (sb_fpt)(sf_tab[box]);
  410. for(i=0; i<4; ++i){
  411. fp(buffer+i, (uint8_t*)w+i);
  412. }
  413. memcpy(w, buffer, 16);
  414. }
  415. void inv_sbox128(void * w, uint8_t box){
  416. uint8_t i, buffer[16];
  417. box &= 0x7;
  418. sb_fpt fp;
  419. fp = (sb_fpt)(sinvf_tab[box]);
  420. for(i=0; i<4; ++i){
  421. fp(buffer+i, (uint8_t*)w+i);
  422. }
  423. memcpy(w, buffer, 16);
  424. }