5 * Created by Michael Brouwer on 7/25/10.
6 * Copyright 2010,2011 Apple Inc. All rights reserved.
10 #ifndef _CORECRYPTO_CCN_H_
11 #define _CORECRYPTO_CCN_H_
13 #include <corecrypto/cc_config.h>
14 #include <corecrypto/cc_priv.h> /* TODO: Get rid of this include in this header. */
19 typedef uint8_t cc_byte
;
20 typedef size_t cc_size
;
22 #if CCN_UNIT_SIZE == 8
23 typedef uint64_t cc_unit
; // 64 bit unit
24 //typedef uint128_t cc_dunit; // 128 bit double width unit
25 #define CCN_LOG2_BITS_PER_UNIT 6 // 2^6 = 64 bits
26 #define CC_UNIT_C(x) UINT64_C(x)
27 #elif CCN_UNIT_SIZE == 4
28 typedef uint32_t cc_unit
; // 32 bit unit
29 typedef uint64_t cc_dunit
; // 64 bit double width unit
30 #define CCN_LOG2_BITS_PER_UNIT 5 // 2^5 = 32 bits
31 #define CC_UNIT_C(x) UINT32_C(x)
32 #elif CCN_UNIT_SIZE == 2
33 typedef uint16_t cc_unit
; // 16 bit unit
34 typedef uint32_t cc_dunit
; // 32 bit double width unit
35 #define CCN_LOG2_BITS_PER_UNIT 4 // 2^4 = 16 bits
36 #define CC_UNIT_C(x) UINT16_C(x)
37 #elif CCN_UNIT_SIZE == 1
38 typedef uint8_t cc_unit
; // 8 bit unit
39 typedef uint16_t cc_dunit
; // 16 bit double width unit
40 #define CCN_LOG2_BITS_PER_UNIT 3 // 2^3 = 8 bits
41 #define CC_UNIT_C(x) UINT8_C(x)
43 #error invalid CCN_UNIT_SIZE
46 // All mp types have units in little endian unit order.
47 typedef cc_unit
*ccn_t
; // n unit long mp
48 typedef cc_unit
*ccnp1_t
; // n + 1 unit long mp
49 typedef cc_unit
*cc2n_t
; // 2 * n unit long mp
50 typedef cc_unit
*cc2np2_t
; // 2 * n + 2 unit long mp
51 typedef const cc_unit
*ccn_in_t
; // n unit long mp
52 typedef const cc_unit
*ccnp1_in_t
; // n + 1 unit long mp
53 typedef const cc_unit
*cc2n_in_t
; // 2 * n unit long mp
54 typedef const cc_unit
*cc2np2_in_t
; // 2 * n + 2 unit long mp
56 #define CCN_UNIT_BITS (sizeof(cc_unit) * 8)
57 #define CCN_UNIT_MASK ((cc_unit)~0)
60 /* Conversions between n sizeof and bits */
62 /* Returns the sizeof a ccn vector of length _n_ units. */
63 #define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_))
65 /* Returns the count (n) of a ccn vector that can represent _bits_. */
66 #define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) / CCN_UNIT_BITS)
68 /* Returns the sizeof a ccn vector that can represent _bits_. */
69 #define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_)))
71 /* Returns the count (n) of a ccn vector that can represent _size_ bytes. */
72 #define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE)
74 /* Return the max number of bits a ccn vector of _n_ units can hold. */
75 #define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS)
77 /* Return the max number of bits a ccn vector of _size_ bytes can hold. */
78 #define ccn_bitsof_size(_size_) ((_size_) * 8)
80 /* Return the size of a ccn of size bytes in bytes. */
81 #define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_))
83 /* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */
84 #define ccn_bit(_ccn_, _k_) ({__typeof__ (_k_) __k = (_k_); \
85 1 & ((_ccn_)[__k / CCN_UNIT_BITS] >> (__k & (CCN_UNIT_BITS - 1)));})
87 #define ccn_set_bit(_ccn_, _k_, _v_) ({__typeof__ (_k_) __k = (_k_); \
89 (_ccn_)[__k/CCN_UNIT_BITS] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \
91 (_ccn_)[__k/CCN_UNIT_BITS] &= ~(CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1))); \
94 /* Macros for making ccn constants. You must use list of CCN64_C() instances
95 separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or
96 CCN8_C() instance at the end of the list, when making macros to declare
97 larger sized constants. */
98 #define CCN8_C(a0) CC_UNIT_C(0x##a0)
100 #if CCN_UNIT_SIZE >= 2
101 #define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0)
102 #define ccn16_v(a0) (a0)
103 #elif CCN_UNIT_SIZE == 1
104 #define CCN16_C(a1,a0) CCN8_C(a0),CCN8_C(a1)
105 #define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
108 #if CCN_UNIT_SIZE >= 4
109 #define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0)
110 #define ccn32_v(a0) (a0)
112 #define CCN32_C(a3,a2,a1,a0) CCN16_C(a1,a0),CCN16_C(a3,a2)
113 #define ccn32_v(a0) ccn16_v(a0 & UINT16_C(0xffff)),ccn16_v(a0 >> 16)
116 #if CCN_UNIT_SIZE == 8
117 #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0)
118 #define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0)
119 #define ccn64_v(a0) (a0)
120 //#define ccn64_32(a1,a0) ((a1 << 32) | a0)
121 //#define ccn_uint64(a,i) (a[i])
123 #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4)
124 #define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4)
125 #define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32)
126 //#define ccn64_32(a1,a0) ccn32_v(a0),ccn32_v(a1)
127 //#define ccn_uint64(a,i) ((uint64_t)ccn_uint32(a, i << 1 + 1) << 32 | (uint64_t)ccn_uint32(a, i << 1))
130 /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
131 64 bit units respectively. */
132 #if CCN_UNIT_SIZE == 8
133 /* #define ccn_uint16(a,i) ((i & 3) == 3 ? ((uint16_t)(a[i >> 2] >> 48)) : \
134 (i & 3) == 2 ? ((uint16_t)(a[i >> 2] >> 32) & UINT16_C(0xffff)) : \
135 (i & 3) == 1 ? ((uint16_t)(a[i >> 2] >> 16) & UINT16_C(0xffff)) : \
136 ((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
138 //#define ccn_uint32(a,i) (i & 1 ? ((uint32_t)(a[i >> 1] >> 32)) : ((uint32_t)(a[i >> 1] & UINT32_C(0xffffffff))))
139 #elif CCN_UNIT_SIZE == 4
140 //#define ccn16_v(a0) (a0)
141 //#define ccn32_v(a0) (a0)
142 //#define ccn_uint16(a,i) (i & 1 ? ((uint16_t)(a[i >> 1] >> 16)) : ((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
143 //#define ccn_uint32(a,i) (a[i])
144 #elif CCN_UNIT_SIZE == 2
145 //#define ccn16_v(a0) (a0)
146 //#define ccn32_v(a0,a1) (a1,a0)
147 //#define ccn_uint16(a,i) (a[i])
148 //#define ccn_uint32(a,i) (((uint32_t)a[i << 1 + 1]) << 16 | (uint32_t)a[i << 1]))
149 #elif CCN_UNIT_SIZE == 1
150 //#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
151 //#define ccn_uint16(a,i) ((uint16_t)((a[i << 1 + 1] << 8) | a[i << 1]))
152 //#define ccn_uint32(a,i) ((uint32_t)ccn_uint16(a, i << 1 + 1) << 16 | (uint32_t)ccn_uint16(a, i << 1))
155 /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
156 64 bit units respectively. */
157 #if CCN_UNIT_SIZE == 8
159 #define ccn64_32(a1,a0) (((cc_unit)a1) << 32 | ((cc_unit)a0))
160 #define ccn32_32(a0) a0
161 #if __LITTLE_ENDIAN__
162 #define ccn32_32_parse(p,i) (((uint32_t *)p)[i])
164 #define ccn32_32_parse(p,i) (((uint32_t *)p)[i^1])
166 #define ccn32_32_null 0
168 #define ccn64_64(a0) a0
169 #define ccn64_64_parse(p,i) p[i]
170 #define ccn64_64_null 0
172 #elif CCN_UNIT_SIZE == 4
174 #define ccn32_32(a0) a0
175 #define ccn32_32_parse(p,i) p[i]
176 #define ccn32_32_null 0
177 #define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1)
179 #define ccn64_64(a1,a0) a0,a1
180 #define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1]
181 #define ccn64_64_null 0,0
183 #elif CCN_UNIT_SIZE == 2
185 #define ccn32_32(a1,a0) a0,a1
186 #define ccn32_32_parse(p,i) p[1+(i<<1)],p[i<<1]
187 #define ccn32_32_null 0,0
188 #define ccn64_32(a3,a2,a1,a0) ccn32_32(a1,a0),ccn32_32(a3,a2)
190 #define ccn64_64(a3,a2,a1,a0) a0,a1,a2,a3
191 #define ccn64_64_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
192 #define ccn64_64_null 0,0,0,0
194 #elif CCN_UNIT_SIZE == 1
196 #define ccn32_32(a3,a2,a1,a0) a0,a1,a2,a3
197 #define ccn32_32_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
198 #define ccn32_32_null 0,0,0,0
199 #define ccn64_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn32_32(a3,a2,a1,a0),ccn32_32(a7,a6,a5,a4)
201 #define ccn64_64(a7,a6,a5,a4,a3,a2,a1,a0) a0,a1,a2,a3,a4,a5,a6,a7
202 #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]
203 #define ccn64_64_null 0,0,0,0,0,0,0,0
208 /* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */
209 #define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2)
210 #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)
211 #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)
212 #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)
215 #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) \
216 CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\
217 CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\
218 CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0)
220 #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) \
221 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),\
224 #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) \
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),\
228 #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) \
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 CCN40_C(d4,d3,d2,d1,d0)
232 #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) \
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 CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0)
236 #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) \
237 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),\
240 #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) \
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 CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\
243 CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0)
245 #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) \
246 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),\
249 #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) \
250 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),\
251 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),\
254 #define CCN192_N ccn_nof(192)
255 #define CCN224_N ccn_nof(224)
256 #define CCN256_N ccn_nof(256)
257 #define CCN384_N ccn_nof(384)
258 #define CCN521_N ccn_nof(521)
260 #if defined(_ARM_ARCH_6) || defined(_ARM_ARCH_7)
261 #if CCN_USE_BUILTIN_CLZ
263 cc_unit
cc_clz(cc_unit data
)
265 return __builtin_clzl(data
);
269 cc_unit
cc_clz(cc_unit data
)
271 __asm__ ("clz %0, %1\n" : "=l" (data
) : "l" (data
));
274 #endif /* CCN_USE_BUILTIN_CLZ */
275 #endif /* !defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) */
279 /* Return the number of used units after stripping leading 0 units. */
280 CC_INLINE CC_PURE CC_NONNULL2
281 cc_size
ccn_n(cc_size n
, const cc_unit
*s
) {
283 while (n
-- && s
[n
] == 0) {}
286 while (n
&& s
[n
- 1] == 0) {
297 cc_unit a
[2] = { s
[n
- 1], s
[n
- 2] };
305 cc_unit a
[4] = { s
[n
- 1], s
[n
- 2], s
[n
- 3], s
[n
- 4] };
320 /* Return the number of used units after stripping leading 0 units. */
322 cc_size
ccn_n(cc_size n
, const cc_unit
*s
);
325 /* s >> k -> r return bits shifted out of least significant word in bits [0, n>
326 { N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
327 the _multi version doesn't return the shifted bits, but does support multiple
330 cc_unit
ccn_shift_right(cc_size n
, cc_unit
*r
, const cc_unit
*s
, size_t k
);
332 void ccn_shift_right_multi(cc_size n
, cc_unit
*r
,const cc_unit
*s
, size_t k
);
334 /* s << k -> r return bits shifted out of most significant word in bits [0, n>
335 { N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
336 the _multi version doesn't return the shifted bits, but does support multiple
339 cc_unit
ccn_shift_left(cc_size n
, cc_unit
*r
, const cc_unit
*s
, size_t k
);
341 void ccn_shift_left_multi(cc_size n
, cc_unit
*r
, const cc_unit
*s
, size_t k
);
343 /* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most
344 significant bit that is 1.
345 { N bit } N = n * sizeof(cc_unit) * 8 */
347 size_t ccn_bitlen(cc_size n
, const cc_unit
*s
);
349 /* Returns the number of bits which are zero before the first one bit
350 counting from least to most significant bit. */
352 size_t ccn_trailing_zeros(cc_size n
, const cc_unit
*s
);
354 /* s == 0 -> return true | s != 0 -> return false
355 { N bit } N = n * sizeof(cc_unit) * 8 */
356 #define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_))
358 /* s == 1 -> return true | s != 1 -> return false
359 { N bit } N = n * sizeof(cc_unit) * 8 */
360 #define ccn_is_one(_n_, _s_) (ccn_n(_n_, _s_) == 1 && _s_[0] == 1)
362 #define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n(_n_, _s_) <= 1) && (_s_[0] <= 1)))
365 CC_INLINE CC_PURE
CC_NONNULL((2, 3))
366 int ccn_cmp(cc_size n
, const cc_unit
*s
, const cc_unit
*t
) {
372 return si
> ti
? 1 : -1;
377 /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
378 { N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */
379 CC_PURE
CC_NONNULL((2, 3))
380 int ccn_cmp(cc_size n
, const cc_unit
*s
, const cc_unit
*t
);
383 /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
384 { N bit, M bit -> int } N = ns * sizeof(cc_unit) * 8 M = nt * sizeof(cc_unit) * 8 */
385 CC_INLINE
CC_NONNULL((2, 4))
386 int ccn_cmpn(cc_size ns
, const cc_unit
*s
,
387 cc_size nt
, const cc_unit
*t
) {
390 } else if (ns
< nt
) {
393 return ccn_cmp(ns
, s
, t
);
396 /* s - t -> r return 1 iff t > s
397 { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
398 CC_NONNULL((2, 3, 4))
399 cc_unit
ccn_sub(cc_size n
, cc_unit
*r
, const cc_unit
*s
, const cc_unit
*t
);
401 /* s - v -> r return 1 iff v > s return 0 otherwise.
402 { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
404 cc_unit
ccn_sub1(cc_size n
, cc_unit
*r
, const cc_unit
*s
, cc_unit v
);
406 /* s - t -> r return 1 iff t > s
407 { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
409 CC_NONNULL((2, 3, 5))
410 cc_unit
ccn_subn(cc_size n
, cc_unit
*r
, const cc_unit
*s
,
411 cc_size nt
, const cc_unit
*t
) {
413 return ccn_sub1(n
- nt
, r
+ nt
, s
+ nt
, ccn_sub(nt
, r
, s
, t
));
417 /* s + t -> r return carry if result doesn't fit in n bits.
418 { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
419 CC_NONNULL((2, 3, 4))
420 cc_unit
ccn_add(cc_size n
, cc_unit
*r
, const cc_unit
*s
, const cc_unit
*t
);
422 /* s + v -> r return carry if result doesn't fit in n bits.
423 { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
425 cc_unit
ccn_add1(cc_size n
, cc_unit
*r
, const cc_unit
*s
, cc_unit v
);
427 /* s + t -> r return carry if result doesn't fit in n bits
428 { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
430 CC_NONNULL((2, 3, 5))
431 cc_unit
ccn_addn(cc_size n
, cc_unit
*r
, const cc_unit
*s
,
432 cc_size nt
, const cc_unit
*t
) {
434 return ccn_add1(n
- nt
, r
+ nt
, s
+ nt
, ccn_add(nt
, r
, s
, t
));
438 void ccn_divmod(cc_size n
, cc_unit
*q
, cc_unit
*r
, const cc_unit
*s
, const cc_unit
*t
);
441 CC_NONNULL((2, 3, 4))
442 void ccn_lcm(cc_size n
, cc_unit
*r2n
, const cc_unit
*s
, const cc_unit
*t
);
445 /* s * t -> r_2n r_2n must not overlap with s nor t
446 { n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
447 { N bit, N bit -> 2N bit } N = ccn_bitsof(n) */
448 CC_NONNULL((2, 3, 4))
449 void ccn_mul(cc_size n
, cc_unit
*r_2n
, const cc_unit
*s
, const cc_unit
*t
);
451 /* s[0..n) * v -> r[0..n)+return value
452 { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
454 cc_unit
ccn_mul1(cc_size n
, cc_unit
*r
, const cc_unit
*s
, const cc_unit v
);
456 /* s[0..n) * v + r[0..n) -> r[0..n)+return value
457 { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
459 cc_unit
ccn_addmul1(cc_size n
, cc_unit
*r
, const cc_unit
*s
, const cc_unit v
);
463 {2 * n bit, n bit -> n bit } n = count * sizeof(cc_unit) * 8 */
464 CC_NONNULL((2, 3, 4))
465 void ccn_mod(cc_size n
, cc_unit
*r
, const cc_unit
*a_2n
, const cc_unit
*d
);
469 N bit, N bit -> N bit */
470 CC_NONNULL((2, 3, 4))
471 void ccn_gcd(cc_size n
, cc_unit
*r
, const cc_unit
*s
, const cc_unit
*t
);
474 N bit, N bit -> O bit */
475 CC_NONNULL((2, 4, 6))
476 void ccn_gcdn(cc_size rn
, cc_unit
*r
, cc_size sn
, const cc_unit
*s
, cc_size tn
, const cc_unit
*t
);
478 /* r = (data, len) treated as a big endian byte array, return -1 if data
479 doesn't fit in r, return 0 otherwise. */
481 int ccn_read_uint(cc_size n
, cc_unit
*r
, size_t data_size
, const uint8_t *data
);
483 /* r = (data, len) treated as a big endian byte array, return -1 if data
484 doesn't fit in r, return 0 otherwise.
485 ccn_read_uint strips leading zeroes and doesn't care about sign. */
486 #define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data)
488 /* Return actual size in bytes needed to serialize s. */
490 size_t ccn_write_uint_size(cc_size n
, const cc_unit
*s
);
492 /* Serialize s, to out.
493 First byte of byte stream is the m.s. byte of s,
494 regardless of the size of cc_unit.
496 No assumption is made about the alignment of out.
498 The out_size argument should be the value returned from ccn_write_uint_size,
499 and is also the exact number of bytes this function will write to out.
500 If out_size if less than the value returned by ccn_write_uint_size, only the
501 first out_size non-zero most significant octets of s will be written. */
503 void ccn_write_uint(cc_size n
, const cc_unit
*s
, size_t out_size
, void *out
);
506 CC_INLINE
CC_NONNULL((2, 4))
507 cc_size
ccn_write_uint_padded(cc_size n
, const cc_unit
* s
, size_t out_size
, uint8_t* to
)
509 size_t bytesInKey
= ccn_write_uint_size(n
, s
);
510 cc_size offset
= (out_size
> bytesInKey
) ? out_size
- bytesInKey
: 0;
513 ccn_write_uint(n
, s
, out_size
- offset
, to
+ offset
);
519 /* Return actual size in bytes needed to serialize s as int
520 (adding leading zero if high bit is set). */
522 size_t ccn_write_int_size(cc_size n
, const cc_unit
*s
);
524 /* Serialize s, to out.
525 First byte of byte stream is the m.s. byte of s,
526 regardless of the size of cc_unit.
528 No assumption is made about the alignment of out.
530 The out_size argument should be the value returned from ccn_write_int_size,
531 and is also the exact number of bytes this function will write to out.
532 If out_size if less than the value returned by ccn_write_int_size, only the
533 first out_size non-zero most significant octets of s will be written. */
535 void ccn_write_int(cc_size n
, const cc_unit
*s
, size_t out_size
, void *out
);
539 { n bit -> 2 * n bit } */
540 CC_INLINE
CC_NONNULL((2, 3))
541 void ccn_sqr(cc_size n
, cc_unit
*r
, const cc_unit
*s
) {
546 { n bit -> n bit } */
548 void ccn_set(cc_size n
, cc_unit
*r
, const cc_unit
*s
);
550 CC_INLINE CC_NONNULL2
551 void ccn_zero(cc_size n
, cc_unit
*r
) {
552 CC_BZERO(r
, ccn_sizeof_n(n
));
556 void ccn_zero_multi(cc_size n
, cc_unit
*r
, ...);
558 /* Burn (zero fill or otherwise overwrite) n cc_units of stack space. */
559 void ccn_burn_stack(cc_size n
);
561 CC_INLINE CC_NONNULL2
562 void ccn_seti(cc_size n
, cc_unit
*r
, cc_unit v
) {
565 ccn_zero(n
- 1, r
+ 1);
568 CC_INLINE
CC_NONNULL((2, 4))
569 void ccn_setn(cc_size n
, cc_unit
*r
, const cc_size s_size
, const cc_unit
*s
) {
570 /* FIXME: assert not available in kernel.
575 ccn_set(s_size
, r
, s
);
576 ccn_zero(n
- s_size
, r
+ s_size
);
579 #define CC_SWAP_HOST_BIG_64(x) \
580 ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
581 (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
582 (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
583 (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
584 (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
585 (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
586 (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
587 (((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
588 #define CC_SWAP_HOST_BIG_32(x) \
589 ((((x) & 0xff000000) >> 24) | \
590 (((x) & 0x00ff0000) >> 8) | \
591 (((x) & 0x0000ff00) << 8) | \
592 (((x) & 0x000000ff) << 24))
593 #define CC_SWAP_HOST_BIG_16(x) \
594 ((((x) & 0xff00) >> 8) | \
595 (((x) & 0x00ff) << 8))
597 /* This should probably move if we move ccn_swap out of line. */
598 #if CCN_UNIT_SIZE == 8
599 #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x)
600 #elif CCN_UNIT_SIZE == 4
601 #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x)
602 #elif CCN_UNIT_SIZE == 2
603 #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_16(x)
604 #elif CCN_UNIT_SIZE == 1
605 #define CC_UNIT_TO_BIG(x) (x)
607 #error unsupported CCN_UNIT_SIZE
610 /* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */
611 CC_INLINE CC_NONNULL2
612 void ccn_swap(cc_size n
, cc_unit
*r
) {
614 for (e
= r
+ n
- 1; r
< e
; ++r
, --e
) {
615 cc_unit t
= CC_UNIT_TO_BIG(*r
);
616 *r
= CC_UNIT_TO_BIG(*e
);
620 *r
= CC_UNIT_TO_BIG(*r
);
623 CC_INLINE
CC_NONNULL((2, 3, 4))
624 void ccn_xor(cc_size n
, cc_unit
*r
, const cc_unit
*s
, const cc_unit
*t
) {
632 void ccn_print(cc_size n
, const cc_unit
*s
);
634 void ccn_lprint(cc_size n
, const char *label
, const cc_unit
*s
);
636 /* Forward declaration so we don't depend on ccrng.h. */
640 CC_INLINE
CC_NONNULL((2, 3))
641 int ccn_random(cc_size n
, cc_unit
*r
, struct ccrng_state
*rng
) {
642 return (RNG
)->generate((RNG
), ccn_sizeof_n(n
), (unsigned char *)r
);
645 #define ccn_random(_n_,_r_,_ccrng_ctx_) \
646 ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_)
649 /* Make a ccn of size ccn_nof(nbits) units with up to nbits sized random value. */
651 int ccn_random_bits(cc_size nbits
, cc_unit
*r
, struct ccrng_state
*rng
);
653 #endif /* _CORECRYPTO_CCN_H_ */