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