1
/*
2
*******************************************************************************
3
\file u16.c
4
\brief 16-bit unsigned words
5
\project bee2 [cryptographic library]
6
\author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
7
\created 2015.10.28
8
\version 2019.07.08
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/u16.h"
16
#include "bee2/core/util.h"
17

18
/*
19
*******************************************************************************
20
Операции
21

22
Реализованные алгоритмы прокомментированы в u32.c.
23
*******************************************************************************
24
*/
25

26 1
u16 u16Rev(u16 w)
27
{
28 1
	return w << 8 | w >> 8;
29
}
30

31 1
void u16Rev2(u16 buf[], size_t count)
32
{
33 1
	ASSERT(memIsValid(buf, count * 2));
34 1
	while (count--)
35 1
		buf[count] = u16Rev(buf[count]);
36
}
37

38 1
size_t u16Weight(register u16 w)
39
{
40 1
	w -= ((w >> 1) & 0x5555);
41 1
	w = (w & 0x3333) + ((w >> 2) & 0x3333);
42 1
	w = (w + (w >> 4)) & 0x0F0F;
43 1
	w += w >> 8;
44 1
	return (size_t)(w & 0x001F);
45
}
46

47 1
bool_t u16Parity(register u16 w)
48
{
49 1
	w ^= w >> 1;
50 1
	w ^= w >> 2;
51 1
	w ^= w >> 4;
52 1
	w ^= w >> 8;
53 1
	return (bool_t)(w & U16_1);
54
}
55

56 1
size_t SAFE(u16CTZ)(register u16 w)
57
{
58 1
	return 16 - u16Weight(w | (U16_0 - w));
59
}
60

61 1
size_t FAST(u16CTZ)(register u16 w)
62
{
63 1
	register size_t l = 16;
64
	register u16 t;
65 1
	if (t = w << 8)
66 1
		l -= 8, w = t;
67 1
	if (t = w << 4)
68 1
		l -= 4, w = t;
69 1
	if (t = w << 2)
70 1
		l -= 2, w = t;
71 1
	t = 0;
72 1
	return ((u16)(w << 1)) ? l - 2 : l - (w ? 1 : 0);
73
}
74

75 1
size_t SAFE(u16CLZ)(register u16 w)
76
{
77 1
	w = w | w >> 1;
78 1
	w = w | w >> 2;
79 1
	w = w | w >> 4;
80 1
	w = w | w >> 8;
81 1
	return u16Weight(~w);
82
}
83

84 1
size_t FAST(u16CLZ)(register u16 w)
85
{
86 1
	register size_t l = 16;
87
	register u16 t;
88 1
	if (t = w >> 8)
89 1
		l -= 8, w = t;
90 1
	if (t = w >> 4)
91 1
		l -= 4, w = t;
92 1
	if (t = w >> 2)
93 1
		l -= 2, w = t;
94 1
	t = 0;
95 1
	return (w >> 1) ? l - 2 : l - (w ? 1 : 0);
96
}
97

98 1
u16 u16Shuffle(register u16 w)
99
{
100
	register u16 t;
101 1
	t = (w ^ (w >> 4)) & 0x00F0, w ^= t ^ (t << 4);
102 1
	t = (w ^ (w >> 2)) & 0x0C0C, w ^= t ^ (t << 2);
103 1
	t = (w ^ (w >> 1)) & 0x2222, w ^= t ^ (t << 1);
104 1
	t = 0;
105 1
	return w;
106
}
107

108 1
u16 u16Deshuffle(register u16 w)
109
{
110
	register u16 t;
111 1
	t = (w ^ (w >> 1)) & 0x2222, w ^= t ^ (t << 1);
112 1
	t = (w ^ (w >> 2)) & 0x0C0C, w ^= t ^ (t << 2);
113 1
	t = (w ^ (w >> 4)) & 0x00F0, w ^= t ^ (t << 4);
114 1
	t = 0;
115 1
	return w;
116
}
117

118 1
u16 u16NegInv(register u16 w)
119
{
120 1
	register u16 ret = w;
121 1
	ASSERT(w & 1);
122 1
	ret = ret * (w * ret + 2);
123 1
	ret = ret * (w * ret + 2);
124 1
	ret = ret * (w * ret + 2);
125 1
	ret = ret * (w * ret + 2);
126 1
	w = 0;
127 1
	return ret;
128
}
129

130 1
void u16From(u16 dest[], const void* src, size_t count)
131
{
132 1
	ASSERT(memIsValid(src, count));
133 1
	ASSERT(memIsValid(dest, count + count % 2));
134 1
	memMove(dest, src, count);
135 1
	if (count % 2)
136 1
		((octet*)dest)[count] = 0;
137
#if (OCTET_ORDER == BIG_ENDIAN)
138
	for (count = (count + 1) / 2; count--;)
139
		dest[count] = u16Rev(dest[count]);
140
#endif // OCTET_ORDER
141
}
142

143 1
void u16To(void* dest, size_t count, const u16 src[])
144
{
145 1
	ASSERT(memIsValid(src, count + count % 2));
146 1
	ASSERT(memIsValid(dest, count));
147 1
	memMove(dest, src, count);
148
#if (OCTET_ORDER == BIG_ENDIAN)
149
	if (count % 2)
150
	{
151
		register u16 u = src[--count / 2];
152
		((octet*)dest)[count] = (octet)u;
153
		u = 0;
154
	}
155
	for (count /= 2; count--;)
156
		((u16*)dest)[count] = u16Rev(((u16*)dest)[count]);
157
#endif // OCTET_ORDER
158
}

Read our documentation on viewing source code .

Loading