1 | /* |
2 | * ccn.h |
3 | * corecrypto |
4 | * |
5 | * Created on 11/16/2010 |
6 | * |
7 | * Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved. |
8 | * |
9 | */ |
10 | |
11 | #ifndef _CORECRYPTO_CCN_H_ |
12 | #define _CORECRYPTO_CCN_H_ |
13 | |
14 | #include <corecrypto/cc.h> |
15 | #include <stdint.h> |
16 | #include <stdarg.h> |
17 | |
18 | typedef uint8_t cc_byte; |
19 | typedef size_t cc_size; |
20 | |
21 | #if CCN_UNIT_SIZE == 8 |
22 | typedef uint64_t cc_unit; // 64 bit unit |
23 | typedef int64_t cc_int; |
24 | #define CCN_LOG2_BITS_PER_UNIT 6 // 2^6 = 64 bits |
25 | #define CC_UNIT_C(x) UINT64_C(x) |
26 | #if CCN_UINT128_SUPPORT_FOR_64BIT_ARCH |
27 | typedef unsigned cc_dunit __attribute__((mode(TI))); // 128 bit double width unit |
28 | typedef signed cc_dint __attribute__((mode(TI))); |
29 | #else |
30 | typedef struct cc_dunit { |
31 | uint64_t l; //do not change the order of the variables. cc_dunit must be little endian |
32 | uint64_t h; |
33 | } cc_dunit; |
34 | |
35 | typedef struct cc_dint { |
36 | uint64_t l; |
37 | uint64_t h; |
38 | } cc_dint; |
39 | #endif |
40 | |
41 | #elif CCN_UNIT_SIZE == 4 |
42 | typedef uint32_t cc_unit; // 32 bit unit |
43 | typedef uint64_t cc_dunit; // 64 bit double width unit |
44 | typedef int64_t cc_dint; |
45 | typedef int32_t cc_int; |
46 | #define CCN_LOG2_BITS_PER_UNIT 5 // 2^5 = 32 bits |
47 | #define CC_UNIT_C(x) UINT32_C(x) |
48 | |
49 | #elif CCN_UNIT_SIZE == 2 |
50 | typedef uint16_t cc_unit; // 16 bit unit |
51 | typedef uint32_t cc_dunit; // 32 bit double width unit |
52 | #define CCN_LOG2_BITS_PER_UNIT 4 // 2^4 = 16 bits |
53 | #define CC_UNIT_C(x) UINT16_C(x) |
54 | |
55 | #elif CCN_UNIT_SIZE == 1 |
56 | typedef uint8_t cc_unit; // 8 bit unit |
57 | typedef uint16_t cc_dunit; // 16 bit double width unit |
58 | #define CCN_LOG2_BITS_PER_UNIT 3 // 2^3 = 8 bits |
59 | #define CC_UNIT_C(x) UINT8_C(x) |
60 | |
61 | #else |
62 | #error invalid CCN_UNIT_SIZE |
63 | #endif |
64 | |
65 | // All mp types have units in little endian unit order. |
66 | typedef cc_unit *ccn_t; // n unit long mp |
67 | typedef cc_unit *ccnp1_t; // n + 1 unit long mp |
68 | typedef cc_unit *cc2n_t; // 2 * n unit long mp |
69 | typedef cc_unit *cc2np2_t; // 2 * n + 2 unit long mp |
70 | typedef const cc_unit *ccn_in_t; // n unit long mp |
71 | typedef const cc_unit *ccnp1_in_t; // n + 1 unit long mp |
72 | typedef const cc_unit *cc2n_in_t; // 2 * n unit long mp |
73 | typedef const cc_unit *cc2np2_in_t; // 2 * n + 2 unit long mp |
74 | |
75 | #define CCN_UNIT_BITS (sizeof(cc_unit) * 8) |
76 | #define CCN_UNIT_MASK ((cc_unit)~0) |
77 | |
78 | typedef struct { |
79 | cc_unit *start; // First cc_unit of the workspace |
80 | cc_unit *end; // address and beyond NOT TO BE TOUCHED |
81 | } cc_ws,*cc_ws_t; |
82 | |
83 | /* Conversions between n sizeof and bits */ |
84 | |
85 | /* Returns the sizeof a ccn vector of length _n_ units. */ |
86 | #define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_)) |
87 | |
88 | /* Returns the count (n) of a ccn vector that can represent _bits_. */ |
89 | #define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) >> CCN_LOG2_BITS_PER_UNIT) |
90 | |
91 | /* Returns the sizeof a ccn vector that can represent _bits_. */ |
92 | #define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_))) |
93 | |
94 | /* Returns the count (n) of a ccn vector that can represent _size_ bytes. */ |
95 | #define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE) |
96 | |
97 | #define ccn_nof_sizeof(_expr_) ccn_nof_size(sizeof (_expr_)) |
98 | |
99 | /* Return the max number of bits a ccn vector of _n_ units can hold. */ |
100 | #define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS) |
101 | |
102 | /* Return the max number of bits a ccn vector of _size_ bytes can hold. */ |
103 | #define ccn_bitsof_size(_size_) ((_size_) * 8) |
104 | |
105 | /* Return the size of a ccn of size bytes in bytes. */ |
106 | #define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_)) |
107 | |
108 | /* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */ |
109 | #define ccn_bit(_ccn_, _k_) ({__typeof__ (_k_) __k = (_k_); \ |
110 | 1 & ((_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] >> (__k & (CCN_UNIT_BITS - 1)));}) |
111 | |
112 | /* Set the value of bit _k_ of _ccn_ to the value _v_ */ |
113 | #define ccn_set_bit(_ccn_, _k_, _v_) ({__typeof__ (_k_) __k = (_k_); \ |
114 | if (_v_) \ |
115 | (_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \ |
116 | else \ |
117 | (_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] &= ~(CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1))); \ |
118 | }) |
119 | |
120 | /* Macros for making ccn constants. You must use list of CCN64_C() instances |
121 | separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or |
122 | CCN8_C() instance at the end of the list, when making macros to declare |
123 | larger sized constants. */ |
124 | #define CCN8_C(a0) CC_UNIT_C(0x##a0) |
125 | |
126 | #if CCN_UNIT_SIZE >= 2 |
127 | #define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0) |
128 | #define ccn16_v(a0) (a0) |
129 | #elif CCN_UNIT_SIZE == 1 |
130 | #define CCN16_C(a1,a0) CCN8_C(a0),CCN8_C(a1) |
131 | #define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8) |
132 | #endif |
133 | |
134 | #if CCN_UNIT_SIZE >= 4 |
135 | #define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0) |
136 | #define ccn32_v(a0) (a0) |
137 | #else |
138 | #define CCN32_C(a3,a2,a1,a0) CCN16_C(a1,a0),CCN16_C(a3,a2) |
139 | #define ccn32_v(a0) ccn16_v(a0 & UINT16_C(0xffff)),ccn16_v(a0 >> 16) |
140 | #endif |
141 | |
142 | #if CCN_UNIT_SIZE == 8 |
143 | #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0) |
144 | #define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0) |
145 | #define ccn64_v(a0) (a0) |
146 | //#define ccn64_32(a1,a0) ((a1 << 32) | a0) |
147 | //#define ccn_uint64(a,i) (a[i]) |
148 | #else |
149 | #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4) |
150 | #define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4) |
151 | #define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32) |
152 | //#define ccn64_32(a1,a0) ccn32_v(a0),ccn32_v(a1) |
153 | //#define ccn_uint64(a,i) ((uint64_t)ccn_uint32(a, i << 1 + 1) << 32 | (uint64_t)ccn_uint32(a, i << 1)) |
154 | #endif |
155 | |
156 | /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or |
157 | 64 bit units respectively. */ |
158 | #if CCN_UNIT_SIZE == 8 |
159 | /* #define ccn_uint16(a,i) ((i & 3) == 3 ? ((uint16_t)(a[i >> 2] >> 48)) : \ |
160 | (i & 3) == 2 ? ((uint16_t)(a[i >> 2] >> 32) & UINT16_C(0xffff)) : \ |
161 | (i & 3) == 1 ? ((uint16_t)(a[i >> 2] >> 16) & UINT16_C(0xffff)) : \ |
162 | ((uint16_t)(a[i >> 1] & UINT16_C(0xffff)))) |
163 | */ |
164 | //#define ccn_uint32(a,i) (i & 1 ? ((uint32_t)(a[i >> 1] >> 32)) : ((uint32_t)(a[i >> 1] & UINT32_C(0xffffffff)))) |
165 | #elif CCN_UNIT_SIZE == 4 |
166 | //#define ccn16_v(a0) (a0) |
167 | //#define ccn32_v(a0) (a0) |
168 | //#define ccn_uint16(a,i) (i & 1 ? ((uint16_t)(a[i >> 1] >> 16)) : ((uint16_t)(a[i >> 1] & UINT16_C(0xffff)))) |
169 | //#define ccn_uint32(a,i) (a[i]) |
170 | #elif CCN_UNIT_SIZE == 2 |
171 | //#define ccn16_v(a0) (a0) |
172 | //#define ccn32_v(a0,a1) (a1,a0) |
173 | //#define ccn_uint16(a,i) (a[i]) |
174 | //#define ccn_uint32(a,i) (((uint32_t)a[i << 1 + 1]) << 16 | (uint32_t)a[i << 1])) |
175 | #elif CCN_UNIT_SIZE == 1 |
176 | //#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8) |
177 | //#define ccn_uint16(a,i) ((uint16_t)((a[i << 1 + 1] << 8) | a[i << 1])) |
178 | //#define ccn_uint32(a,i) ((uint32_t)ccn_uint16(a, i << 1 + 1) << 16 | (uint32_t)ccn_uint16(a, i << 1)) |
179 | #endif |
180 | |
181 | /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or |
182 | 64 bit units respectively. */ |
183 | #if CCN_UNIT_SIZE == 8 |
184 | |
185 | #define ccn64_32(a1,a0) (((const cc_unit)a1) << 32 | ((const cc_unit)a0)) |
186 | #define ccn32_32(a0) a0 |
187 | #if __LITTLE_ENDIAN__ |
188 | #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i]) |
189 | #else |
190 | #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i^1]) |
191 | #endif |
192 | #define ccn32_32_null 0 |
193 | |
194 | #define ccn64_64(a0) a0 |
195 | #define ccn64_64_parse(p,i) p[i] |
196 | #define ccn64_64_null 0 |
197 | |
198 | #elif CCN_UNIT_SIZE == 4 |
199 | |
200 | #define ccn32_32(a0) a0 |
201 | #define ccn32_32_parse(p,i) p[i] |
202 | #define ccn32_32_null 0 |
203 | #define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1) |
204 | |
205 | #define ccn64_64(a1,a0) a0,a1 |
206 | #define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1] |
207 | #define ccn64_64_null 0,0 |
208 | |
209 | #elif CCN_UNIT_SIZE == 2 |
210 | |
211 | #define ccn32_32(a1,a0) a0,a1 |
212 | #define ccn32_32_parse(p,i) p[1+(i<<1)],p[i<<1] |
213 | #define ccn32_32_null 0,0 |
214 | #define ccn64_32(a3,a2,a1,a0) ccn32_32(a1,a0),ccn32_32(a3,a2) |
215 | |
216 | #define ccn64_64(a3,a2,a1,a0) a0,a1,a2,a3 |
217 | #define ccn64_64_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2] |
218 | #define ccn64_64_null 0,0,0,0 |
219 | |
220 | #elif CCN_UNIT_SIZE == 1 |
221 | |
222 | #define ccn32_32(a3,a2,a1,a0) a0,a1,a2,a3 |
223 | #define ccn32_32_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2] |
224 | #define ccn32_32_null 0,0,0,0 |
225 | #define ccn64_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn32_32(a3,a2,a1,a0),ccn32_32(a7,a6,a5,a4) |
226 | |
227 | #define ccn64_64(a7,a6,a5,a4,a3,a2,a1,a0) a0,a1,a2,a3,a4,a5,a6,a7 |
228 | #define ccn64_64_parse(p,i) p[7+(i<<3)],p[6+(i<<3)],p[5+(i<<3)],p[4+(i<<3)],p[3+(i<<3)],p[2+(i<<3)],p[1+(i<<3)],p[i<<3] |
229 | #define ccn64_64_null 0,0,0,0,0,0,0,0 |
230 | |
231 | #endif |
232 | |
233 | |
234 | /* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */ |
235 | #define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2) |
236 | #define ccn224_32(a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn32_32(a6) |
237 | #define ccn256_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6) |
238 | #define ccn384_32(a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6),ccn64_32(a9,a8),ccn64_32(a11,a10) |
239 | |
240 | |
241 | #define CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
242 | CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\ |
243 | CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\ |
244 | CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0) |
245 | |
246 | #define CCN200_C(d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
247 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
248 | CCN8_C(d0) |
249 | |
250 | #define CCN224_C(d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
251 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
252 | CCN32_C(d3,d2,d1,d0) |
253 | |
254 | #define CCN232_C(d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
255 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
256 | CCN40_C(d4,d3,d2,d1,d0) |
257 | |
258 | #define CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
259 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
260 | CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0) |
261 | |
262 | #define CCN264_C(e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
263 | CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
264 | CCN8_C(e0) |
265 | |
266 | #define CCN384_C(f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
267 | CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
268 | CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\ |
269 | CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0) |
270 | |
271 | #define CCN392_C(g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
272 | CCN384_C(f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
273 | CCN8_C(g0) |
274 | |
275 | #define CCN528_C(i1,i0,h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
276 | CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
277 | CCN256_C(h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0),\ |
278 | CCN16_C(i1,i0) |
279 | |
280 | #define CCN192_N ccn_nof(192) |
281 | #define CCN224_N ccn_nof(224) |
282 | #define CCN256_N ccn_nof(256) |
283 | #define CCN384_N ccn_nof(384) |
284 | #define CCN512_N ccn_nof(512) |
285 | #define CCN521_N ccn_nof(521) |
286 | |
287 | /* Return the number of used units after stripping leading 0 units. */ |
288 | CC_PURE CC_NONNULL((2)) |
289 | cc_size ccn_n(cc_size n, const cc_unit *s); |
290 | |
291 | /* s >> k -> r return bits shifted out of least significant word in bits [0, n> |
292 | { N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8 |
293 | the _multi version doesn't return the shifted bits, but does support multiple |
294 | word shifts. */ |
295 | CC_NONNULL((2, 3)) |
296 | cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k); |
297 | |
298 | /* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most |
299 | significant bit that is 1. |
300 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
301 | CC_NONNULL((2)) |
302 | size_t ccn_bitlen(cc_size n, const cc_unit *s); |
303 | |
304 | /* s == 0 -> return true | s != 0 -> return false |
305 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
306 | #define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_)) |
307 | |
308 | /* s == 1 -> return true | s != 1 -> return false |
309 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
310 | #define ccn_is_one(_n_, _s_) (ccn_n(_n_, _s_) == 1 && _s_[0] == 1) |
311 | |
312 | #define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n(_n_, _s_) <= 1) && (_s_[0] <= 1))) |
313 | |
314 | /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1 |
315 | { N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */ |
316 | CC_PURE CC_NONNULL((2, 3)) |
317 | int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t); |
318 | |
319 | /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1 |
320 | { N bit, M bit -> int } N = ns * sizeof(cc_unit) * 8 M = nt * sizeof(cc_unit) * 8 */ |
321 | CC_INLINE CC_NONNULL((2, 4)) |
322 | int ccn_cmpn(cc_size ns, const cc_unit *s, |
323 | cc_size nt, const cc_unit *t) { |
324 | if (ns > nt) { |
325 | return 1; |
326 | } else if (ns < nt) { |
327 | return -1; |
328 | } |
329 | return ccn_cmp(ns, s, t); |
330 | } |
331 | |
332 | /* s - t -> r return 1 iff t > s |
333 | { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
334 | CC_NONNULL((2, 3, 4)) |
335 | cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t); |
336 | |
337 | /* s - v -> r return 1 iff v > s return 0 otherwise. |
338 | { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
339 | CC_NONNULL((2, 3)) |
340 | cc_unit ccn_sub1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v); |
341 | |
342 | /* s - t -> r return 1 iff t > s |
343 | { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */ |
344 | CC_INLINE |
345 | CC_NONNULL((2, 3, 5)) |
346 | cc_unit ccn_subn(cc_size n, cc_unit *r, const cc_unit *s, |
347 | cc_size nt, const cc_unit *t) { |
348 | assert(n >= nt); |
349 | return ccn_sub1(n - nt, r + nt, s + nt, ccn_sub(nt, r, s, t)); |
350 | } |
351 | |
352 | |
353 | /* s + t -> r return carry if result doesn't fit in n bits. |
354 | { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
355 | CC_NONNULL((2, 3, 4)) |
356 | cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t); |
357 | |
358 | /* s + v -> r return carry if result doesn't fit in n bits. |
359 | { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
360 | CC_NONNULL((2, 3)) |
361 | cc_unit ccn_add1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v); |
362 | |
363 | /* s + t -> r return carry if result doesn't fit in n bits |
364 | { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */ |
365 | CC_INLINE |
366 | CC_NONNULL((2, 3, 5)) |
367 | cc_unit ccn_addn(cc_size n, cc_unit *r, const cc_unit *s, |
368 | cc_size nt, const cc_unit *t) { |
369 | assert(n >= nt); |
370 | return ccn_add1(n - nt, r + nt, s + nt, ccn_add(nt, r, s, t)); |
371 | } |
372 | |
373 | |
374 | /* s * t -> r_2n r_2n must not overlap with s nor t |
375 | { n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8 |
376 | { N bit, N bit -> 2N bit } N = ccn_bitsof(n) */ |
377 | CC_NONNULL((2, 3, 4)) |
378 | void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t); |
379 | |
380 | /* s[0..n) * v -> r[0..n)+return value |
381 | { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */ |
382 | CC_NONNULL((2, 3)) |
383 | cc_unit ccn_mul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v); |
384 | |
385 | /* s[0..n) * v + r[0..n) -> r[0..n)+return value |
386 | { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */ |
387 | CC_NONNULL((2, 3)) |
388 | cc_unit ccn_addmul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v); |
389 | |
390 | #if 0 |
391 | /* a % d -> n |
392 | {2 * n bit, n bit -> n bit } n = count * sizeof(cc_unit) * 8 */ |
393 | CC_NONNULL((2, 3, 4)) |
394 | void ccn_mod(cc_size n, cc_unit *r, const cc_unit *a_2n, const cc_unit *d); |
395 | #endif |
396 | |
397 | /* r = (data, len) treated as a big endian byte array, return -1 if data |
398 | doesn't fit in r, return 0 otherwise. */ |
399 | CC_NONNULL((2, 4)) |
400 | int ccn_read_uint(cc_size n, cc_unit *r, size_t data_size, const uint8_t *data); |
401 | |
402 | /* r = (data, len) treated as a big endian byte array, return -1 if data |
403 | doesn't fit in r, return 0 otherwise. |
404 | ccn_read_uint strips leading zeroes and doesn't care about sign. */ |
405 | #define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data) |
406 | |
407 | /* Return actual size in bytes needed to serialize s. */ |
408 | CC_PURE CC_NONNULL((2)) |
409 | size_t ccn_write_uint_size(cc_size n, const cc_unit *s); |
410 | |
411 | /* Serialize s, to out. |
412 | First byte of byte stream is the m.s. byte of s, |
413 | regardless of the size of cc_unit. |
414 | |
415 | No assumption is made about the alignment of out. |
416 | |
417 | The out_size argument should be the value returned from ccn_write_uint_size, |
418 | and is also the exact number of bytes this function will write to out. |
419 | If out_size if less than the value returned by ccn_write_uint_size, only the |
420 | first out_size non-zero most significant octets of s will be written. */ |
421 | CC_NONNULL((2, 4)) |
422 | void ccn_write_uint(cc_size n, const cc_unit *s, size_t out_size, void *out); |
423 | |
424 | |
425 | CC_INLINE CC_NONNULL((2, 4)) |
426 | cc_size ccn_write_uint_padded(cc_size n, const cc_unit* s, size_t out_size, uint8_t* to) |
427 | { |
428 | size_t bytesInKey = ccn_write_uint_size(n, s); |
429 | cc_size offset = (out_size > bytesInKey) ? out_size - bytesInKey : 0; |
430 | |
431 | cc_zero(offset, to); |
432 | ccn_write_uint(n, s, out_size - offset, to + offset); |
433 | |
434 | return offset; |
435 | } |
436 | |
437 | |
438 | /* Return actual size in bytes needed to serialize s as int |
439 | (adding leading zero if high bit is set). */ |
440 | CC_PURE CC_NONNULL((2)) |
441 | size_t ccn_write_int_size(cc_size n, const cc_unit *s); |
442 | |
443 | /* Serialize s, to out. |
444 | First byte of byte stream is the m.s. byte of s, |
445 | regardless of the size of cc_unit. |
446 | |
447 | No assumption is made about the alignment of out. |
448 | |
449 | The out_size argument should be the value returned from ccn_write_int_size, |
450 | and is also the exact number of bytes this function will write to out. |
451 | If out_size if less than the value returned by ccn_write_int_size, only the |
452 | first out_size non-zero most significant octets of s will be written. */ |
453 | CC_NONNULL((2, 4)) |
454 | void ccn_write_int(cc_size n, const cc_unit *s, size_t out_size, void *out); |
455 | |
456 | /* s -> r |
457 | { n bit -> n bit } */ |
458 | CC_NONNULL((2, 3)) |
459 | void ccn_set(cc_size n, cc_unit *r, const cc_unit *s); |
460 | |
461 | CC_INLINE CC_NONNULL((2)) |
462 | void ccn_zero(cc_size n, cc_unit *r) { |
463 | cc_zero(ccn_sizeof_n(n),r); |
464 | } |
465 | |
466 | CC_INLINE CC_NONNULL((2)) |
467 | void ccn_clear(cc_size n, cc_unit *r) { |
468 | cc_clear(ccn_sizeof_n(n),r); |
469 | } |
470 | |
471 | CC_NONNULL((2)) |
472 | void ccn_zero_multi(cc_size n, cc_unit *r, ...); |
473 | |
474 | CC_INLINE CC_NONNULL((2)) |
475 | void ccn_seti(cc_size n, cc_unit *r, cc_unit v) { |
476 | /* assert(n > 0); */ |
477 | r[0] = v; |
478 | ccn_zero(n - 1, r + 1); |
479 | } |
480 | |
481 | CC_INLINE CC_NONNULL((2, 4)) |
482 | void ccn_setn(cc_size n, cc_unit *r, const cc_size s_size, const cc_unit *s) { |
483 | /* FIXME: assert not available in kernel. |
484 | assert(n > 0); |
485 | assert(s_size > 0); |
486 | assert(s_size <= n); |
487 | */ |
488 | ccn_set(s_size, r, s); |
489 | ccn_zero(n - s_size, r + s_size); |
490 | } |
491 | |
492 | #define CC_SWAP_HOST_BIG_64(x) \ |
493 | ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ |
494 | (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ |
495 | (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ |
496 | (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ |
497 | (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ |
498 | (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ |
499 | (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ |
500 | (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) |
501 | #define CC_SWAP_HOST_BIG_32(x) \ |
502 | ((((x) & 0xff000000) >> 24) | \ |
503 | (((x) & 0x00ff0000) >> 8) | \ |
504 | (((x) & 0x0000ff00) << 8) | \ |
505 | (((x) & 0x000000ff) << 24)) |
506 | #define CC_SWAP_HOST_BIG_16(x) \ |
507 | ((((x) & 0xff00) >> 8) | \ |
508 | (((x) & 0x00ff) << 8)) |
509 | |
510 | /* This should probably move if we move ccn_swap out of line. */ |
511 | #if CCN_UNIT_SIZE == 8 |
512 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x) |
513 | #elif CCN_UNIT_SIZE == 4 |
514 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x) |
515 | #elif CCN_UNIT_SIZE == 2 |
516 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_16(x) |
517 | #elif CCN_UNIT_SIZE == 1 |
518 | #define CC_UNIT_TO_BIG(x) (x) |
519 | #else |
520 | #error unsupported CCN_UNIT_SIZE |
521 | #endif |
522 | |
523 | /* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */ |
524 | CC_INLINE CC_NONNULL((2)) |
525 | void ccn_swap(cc_size n, cc_unit *r) { |
526 | cc_unit *e; |
527 | for (e = r + n - 1; r < e; ++r, --e) { |
528 | cc_unit t = CC_UNIT_TO_BIG(*r); |
529 | *r = CC_UNIT_TO_BIG(*e); |
530 | *e = t; |
531 | } |
532 | if (n & 1) |
533 | *r = CC_UNIT_TO_BIG(*r); |
534 | } |
535 | |
536 | CC_INLINE CC_NONNULL((2, 3, 4)) |
537 | void ccn_xor(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) { |
538 | while (n--) { |
539 | r[n] = s[n] ^ t[n]; |
540 | } |
541 | } |
542 | |
543 | /* Debugging */ |
544 | CC_NONNULL((2)) |
545 | void ccn_print(cc_size n, const cc_unit *s); |
546 | CC_NONNULL((3)) |
547 | void ccn_lprint(cc_size n, const char *label, const cc_unit *s); |
548 | |
549 | /* Forward declaration so we don't depend on ccrng.h. */ |
550 | struct ccrng_state; |
551 | |
552 | #if 0 |
553 | CC_INLINE CC_NONNULL((2, 3)) |
554 | int ccn_random(cc_size n, cc_unit *r, struct ccrng_state *rng) { |
555 | return (RNG)->generate((RNG), ccn_sizeof_n(n), (unsigned char *)r); |
556 | } |
557 | #else |
558 | #define ccn_random(_n_,_r_,_ccrng_ctx_) \ |
559 | ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_) |
560 | #endif |
561 | |
562 | /* Make a ccn of size ccn_nof(nbits) units with up to nbits sized random value. */ |
563 | CC_NONNULL((2, 3)) |
564 | int ccn_random_bits(cc_size nbits, cc_unit *r, struct ccrng_state *rng); |
565 | |
566 | CC_NONNULL((6, 8)) |
567 | int ccn_div_euclid(cc_size nq, cc_unit *q, cc_size nr, cc_unit *r, cc_size na, const cc_unit *a, cc_size nd, const cc_unit *d); |
568 | |
569 | #define ccn_div(nq, q, na, a, nd, d) ccn_div_euclid(nq, q, 0, NULL, na, a, nd, d) |
570 | #define ccn_mod(nr, r, na, a, nd, d) ccn_div_euclid(0 , NULL, nr, r, na, a, nd, d) |
571 | |
572 | #endif /* _CORECRYPTO_CCN_H_ */ |
573 | |