1 /*
2 * Copyright (c) 2015-2018, Andrew Romanenko <melanhit@gmail.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdlib.h>
30 #include <stdint.h>
31
32 #include "../akmos.h"
33 #include "../bits.h"
34 #include "../cipher.h"
35
36 #include "threefish.h"
37 #include "threefish_mix.h"
38
39 #define WORDS_1024 AKMOS_THREEFISH_WORDS_1024
40 #define ROUNDS_1024 (80 / 8)
41 #define SKEYS_1024 ((ROUNDS_1024 * 2) + 1)
42
akmos_threefish_1024_setkey(akmos_cipher_algo_t * uctx,const uint8_t * key,size_t len)43 void akmos_threefish_1024_setkey(akmos_cipher_algo_t *uctx,
44 const uint8_t *key,
45 size_t __attribute__((unused)) len)
46 {
47 akmos_threefish_1024_t *ctx;
48 uint64_t *k, *S;
49 size_t i, j;
50
51 ctx = &uctx->tf_1024;
52
53 k = ctx->k;
54
55 for(i = 0; i < WORDS_1024; i++, key +=8)
56 k[i] = PACK64BE(key);
57
58 k[WORDS_1024] = AKMOS_THREEFISH_C240;
59 for(i = 0; i < WORDS_1024; i++)
60 k[WORDS_1024] ^= k[i];
61
62 for(i = 0, S = ctx->S; i < SKEYS_1024; i++, S += WORDS_1024) {
63 for(j = 0; j < WORDS_1024; j++)
64 S[j] = k[(i+j)%(WORDS_1024+1)];
65
66 S[WORDS_1024-1] += i;
67 }
68 }
69
akmos_threefish_1024_encrypt(akmos_cipher_algo_t * uctx,const uint8_t * in_blk,uint8_t * out_blk)70 void akmos_threefish_1024_encrypt(akmos_cipher_algo_t *uctx,
71 const uint8_t *in_blk,
72 uint8_t *out_blk)
73 {
74 akmos_threefish_1024_t *ctx;
75 uint64_t s[WORDS_1024], *S;
76 int i, j;
77
78 ctx = &uctx->tf_1024;
79
80 for(i = 0; i < WORDS_1024; i++, in_blk += 8)
81 s[i] = PACK64BE(in_blk);
82
83 for(i = 0, S = ctx->S; i < ROUNDS_1024; i++, S += WORDS_1024) {
84 for(j = 0; j < WORDS_1024; j++)
85 s[j] += S[j];
86
87 threefish_1024_emix1(s, 24, 13, 8, 47, 8, 17, 22, 37);
88 threefish_1024_emix2(s, 38, 19, 10, 55, 49, 18, 23, 52);
89 threefish_1024_emix3(s, 33, 4, 51, 13, 34, 41, 59, 17);
90 threefish_1024_emix4(s, 5, 20, 48, 41, 47, 28, 16, 25);
91
92 for(j = 0, S += WORDS_1024; j < WORDS_1024; j++)
93 s[j] += S[j];
94
95 threefish_1024_emix1(s, 41, 9, 37, 31, 12, 47, 44, 30);
96 threefish_1024_emix2(s, 16, 34, 56, 51, 4, 53, 42, 41);
97 threefish_1024_emix3(s, 31, 44, 47, 46, 19, 42, 44, 25);
98 threefish_1024_emix4(s, 9, 48, 35, 52, 23, 31, 37, 20);
99 }
100
101 for(i = 0; i < WORDS_1024; i++, out_blk += 8)
102 UNPACK64BE(out_blk, s[i] + S[i]);
103 }
104
akmos_threefish_1024_decrypt(akmos_cipher_algo_t * uctx,const uint8_t * in_blk,uint8_t * out_blk)105 void akmos_threefish_1024_decrypt(akmos_cipher_algo_t *uctx,
106 const uint8_t *in_blk,
107 uint8_t *out_blk)
108 {
109 akmos_threefish_1024_t *ctx;
110 uint64_t s[WORDS_1024], *S;
111 int i, j;
112
113 ctx = &uctx->tf_1024;
114
115 for(i = 0; i < WORDS_1024; i++, in_blk += 8)
116 s[i] = PACK64BE(in_blk);
117
118 S = ctx->S + (WORDS_1024 * (SKEYS_1024 - 1));
119 for(i = 0; i < WORDS_1024; i++)
120 s[i] -= S[i];
121
122 for(i = ROUNDS_1024; i > 0; i--) {
123 threefish_1024_dmix1(s, 20, 37, 31, 23, 52, 35, 48, 9);
124 threefish_1024_dmix2(s, 25, 44, 42, 19, 46, 47, 44, 31);
125 threefish_1024_dmix3(s, 41, 42, 53, 4, 51, 56, 34, 16);
126 threefish_1024_dmix4(s, 30, 44, 47, 12, 31, 37, 9, 41);
127
128 for(j = 0, S -= WORDS_1024; j < WORDS_1024; j++)
129 s[j] -= S[j];
130
131 threefish_1024_dmix1(s, 25, 16, 28, 47, 41, 48, 20, 5);
132 threefish_1024_dmix2(s, 17, 59, 41, 34, 13, 51, 4, 33);
133 threefish_1024_dmix3(s, 52, 23, 18, 49, 55, 10, 19, 38);
134 threefish_1024_dmix4(s, 37, 22, 17, 8, 47, 8, 13, 24);
135
136 for(j = 0, S -= WORDS_1024; j < WORDS_1024; j++)
137 s[j] -= S[j];
138 }
139
140 for(i = 0; i < WORDS_1024; i++, out_blk += 8)
141 UNPACK64BE(out_blk, s[i]);
142 }
143