1
|
|
/*
|
2
|
|
*******************************************************************************
|
3
|
|
\file belt_lcl.c
|
4
|
|
\brief STB 34.101.31 (belt): local functions
|
5
|
|
\project bee2 [cryptographic library]
|
6
|
|
\author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
|
7
|
|
\created 2012.12.18
|
8
|
|
\version 2020.03.20
|
9
|
|
\license This program is released under the GNU General Public License
|
10
|
|
version 3. See Copyright Notices in bee2/info.h.
|
11
|
|
*******************************************************************************
|
12
|
|
*/
|
13
|
|
|
14
|
|
#include "bee2/core/mem.h"
|
15
|
|
#include "bee2/core/u32.h"
|
16
|
|
#include "bee2/core/util.h"
|
17
|
|
#include "bee2/crypto/belt.h"
|
18
|
|
#include "bee2/math/pp.h"
|
19
|
|
#include "bee2/math/ww.h"
|
20
|
|
#include "belt_lcl.h"
|
21
|
|
|
22
|
|
/*
|
23
|
|
*******************************************************************************
|
24
|
|
Арифметика чисел
|
25
|
|
*******************************************************************************
|
26
|
|
*/
|
27
|
|
|
28
|
1
|
void beltBlockAddBitSizeU32(u32 block[4], size_t count)
|
29
|
|
{
|
30
|
|
// block <- block + 8 * count
|
31
|
1
|
register u32 carry = (u32)count << 3;
|
32
|
|
#if (B_PER_S < 32)
|
33
|
|
carry = (block[0] += carry) < carry;
|
34
|
|
carry = (block[1] += carry) < carry;
|
35
|
|
carry = (block[2] += carry) < carry;
|
36
|
|
block[3] += carry;
|
37
|
|
#else
|
38
|
1
|
register size_t t = count >> 29;
|
39
|
1
|
carry = (block[0] += carry) < carry;
|
40
|
1
|
if ((block[1] += carry) < carry)
|
41
|
0
|
block[1] = (u32)t;
|
42
|
|
else
|
43
|
1
|
carry = (block[1] += (u32)t) < (u32)t;
|
44
|
1
|
t >>= 16, t >>= 16;
|
45
|
1
|
if ((block[2] += carry) < carry)
|
46
|
0
|
block[2] = (u32)t;
|
47
|
|
else
|
48
|
1
|
carry = (block[2] += (u32)t) < (u32)t;
|
49
|
1
|
t >>= 16, t >>= 16;
|
50
|
1
|
block[3] += carry;
|
51
|
1
|
block[3] += (u32)t;
|
52
|
1
|
t = 0;
|
53
|
|
#endif
|
54
|
1
|
carry = 0;
|
55
|
|
}
|
56
|
|
|
57
|
1
|
void beltHalfBlockAddBitSizeW(word block[W_OF_B(64)], size_t count)
|
58
|
|
{
|
59
|
|
// block <- block + 8 * count
|
60
|
1
|
register word carry = (word)count << 3;
|
61
|
|
#if (B_PER_W == 16)
|
62
|
|
register size_t t = count >> 13;
|
63
|
|
carry = (block[0] += carry) < carry;
|
64
|
|
if ((block[1] += carry) < carry)
|
65
|
|
block[1] = (word)t;
|
66
|
|
else
|
67
|
|
carry = (block[1] += (word)t) < (word)t;
|
68
|
|
t >>= 8, t >>= 8;
|
69
|
|
if ((block[2] += carry) < carry)
|
70
|
|
block[2] = (word)t;
|
71
|
|
else
|
72
|
|
carry = (block[2] += (word)t) < (word)t;
|
73
|
|
t >>= 8, t >>= 8;
|
74
|
|
block[3] += carry;
|
75
|
|
block[3] += (word)t;
|
76
|
|
#elif (B_PER_W == 32)
|
77
|
|
register size_t t = count;
|
78
|
|
carry = (block[0] += carry) < carry;
|
79
|
|
t >>= 15, t >>= 14;
|
80
|
|
block[1] += carry;
|
81
|
|
block[1] += (u32)t;
|
82
|
|
t = 0;
|
83
|
|
#elif (B_PER_W == 64)
|
84
|
1
|
block[0] += carry;
|
85
|
|
#else
|
86
|
|
#error "Unsupported word size"
|
87
|
|
#endif // B_PER_W
|
88
|
1
|
carry = 0;
|
89
|
|
}
|
90
|
|
|
91
|
|
/*
|
92
|
|
*******************************************************************************
|
93
|
|
Арифметика многочленов
|
94
|
|
*******************************************************************************
|
95
|
|
*/
|
96
|
|
|
97
|
1
|
void beltPolyMul(word c[], const word a[], const word b[], void* stack)
|
98
|
|
{
|
99
|
1
|
const size_t n = W_OF_B(128);
|
100
|
1
|
word* prod = (word*)stack;
|
101
|
1
|
stack = prod + 2 * n;
|
102
|
|
// умножить
|
103
|
1
|
ppMul(prod, a, n, b, n, stack);
|
104
|
|
// привести по модулю
|
105
|
1
|
ppRedBelt(prod);
|
106
|
1
|
wwCopy(c, prod, n);
|
107
|
|
}
|
108
|
|
|
109
|
1
|
size_t beltPolyMul_deep()
|
110
|
|
{
|
111
|
1
|
const size_t n = W_OF_B(128);
|
112
|
1
|
return O_OF_W(2 * n) + ppMul_deep(n, n);
|
113
|
|
}
|
114
|
|
|
115
|
|
/*
|
116
|
|
*******************************************************************************
|
117
|
|
Умножение на многочлен C(x) = x mod (x^128 + x^7 + x^2 + x + 1)
|
118
|
|
|
119
|
|
\remark t = (старший бит block ненулевой) ? x^7 + x^2 + x + 1 : 0 [регулярно].
|
120
|
|
*******************************************************************************
|
121
|
|
*/
|
122
|
|
|
123
|
1
|
void beltBlockMulC(u32 block[4])
|
124
|
|
{
|
125
|
1
|
register u32 t = ~((block[3] >> 31) - U32_1) & 0x00000087;
|
126
|
1
|
block[3] = (block[3] << 1) ^ (block[2] >> 31);
|
127
|
1
|
block[2] = (block[2] << 1) ^ (block[1] >> 31);
|
128
|
1
|
block[1] = (block[1] << 1) ^ (block[0] >> 31);
|
129
|
1
|
block[0] = (block[0] << 1) ^ t;
|
130
|
1
|
t = 0;
|
131
|
|
}
|