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