-/*
- * ccn.h
- * corecrypto
- *
- * Created on 11/16/2010
- *
- * Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
+/* Copyright (c) (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
*
+ * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
+ * is contained in the License.txt file distributed with corecrypto) and only to
+ * people who accept that license. IMPORTANT: Any license rights granted to you by
+ * Apple Inc. (if any) are limited to internal use within your organization only on
+ * devices and computers you own or control, for the sole purpose of verifying the
+ * security characteristics and correct functioning of the Apple Software. You may
+ * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCN_H_
#error invalid CCN_UNIT_SIZE
#endif
-// All mp types have units in little endian unit order.
-typedef cc_unit *ccn_t; // n unit long mp
-typedef cc_unit *ccnp1_t; // n + 1 unit long mp
-typedef cc_unit *cc2n_t; // 2 * n unit long mp
-typedef cc_unit *cc2np2_t; // 2 * n + 2 unit long mp
-typedef const cc_unit *ccn_in_t; // n unit long mp
-typedef const cc_unit *ccnp1_in_t; // n + 1 unit long mp
-typedef const cc_unit *cc2n_in_t; // 2 * n unit long mp
-typedef const cc_unit *cc2np2_in_t; // 2 * n + 2 unit long mp
-
#define CCN_UNIT_BITS (sizeof(cc_unit) * 8)
#define CCN_UNIT_MASK ((cc_unit)~0)
+#define CCN_UNIT_LOWER_HALF_MASK ((CCN_UNIT_MASK) >> (CCN_UNIT_BITS/2))
+#define CCN_UNIT_UPPER_HALF_MASK (~CCN_UNIT_LOWER_HALF_MASK)
+#define CCN_UNIT_HALF_BITS (CCN_UNIT_BITS / 2)
typedef struct {
cc_unit *start; // First cc_unit of the workspace
/* Returns the count (n) of a ccn vector that can represent _size_ bytes. */
#define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE)
+#define ccn_nof_sizeof(_expr_) ccn_nof_size(sizeof (_expr_))
+
/* Return the max number of bits a ccn vector of _n_ units can hold. */
#define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS)
#define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_))
/* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */
-#define ccn_bit(_ccn_, _k_) ({__typeof__ (_k_) __k = (_k_); \
+#define ccn_bit(_ccn_, _k_) ({size_t __k = (size_t)(_k_); \
1 & ((_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] >> (__k & (CCN_UNIT_BITS - 1)));})
/* Set the value of bit _k_ of _ccn_ to the value _v_ */
-#define ccn_set_bit(_ccn_, _k_, _v_) ({__typeof__ (_k_) __k = (_k_); \
+#define ccn_set_bit(_ccn_, _k_, _v_) ({size_t __k = (size_t)(_k_); \
if (_v_) \
(_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \
else \
/* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */
#define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2)
+#define ccn192_32(a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4)
#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)
#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)
#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)
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),\
CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0)
-#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) \
- 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),\
- CCN8_C(e0)
-
#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) \
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),\
CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\
CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0)
-#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) \
- 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),\
- CCN8_C(g0)
-
#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) \
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),\
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),\
#define CCN521_N ccn_nof(521)
/* Return the number of used units after stripping leading 0 units. */
-CC_PURE CC_NONNULL2
-cc_size ccn_n(cc_size n, const cc_unit *s);
+CC_PURE CC_NONNULL((2))
+cc_size ccn_n(cc_size n, const cc_unit *s) __asm__("_ccn_n");
-/* s >> k -> r return bits shifted out of least significant word in bits [0, n>
+/* s >> k -> r return bits shifted out of least significant word in the higest order bits of
+ the retuned value. For example if CCN_UNIT_SIZE == 1, then (0b1101 1110)>>4 returns (0b1110 0000)
+ and sets r==(0b0000 1101).
{ N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
the _multi version doesn't return the shifted bits, but does support multiple
word shifts. */
CC_NONNULL((2, 3))
-cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k);
-CC_NONNULL((2, 3))
-void ccn_shift_right_multi(cc_size n, cc_unit *r,const cc_unit *s, size_t k);
-
-/* s << k -> r return bits shifted out of most significant word in bits [0, n>
- { N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
- the _multi version doesn't return the shifted bits, but does support multiple
- word shifts */
-CC_NONNULL((2, 3))
-cc_unit ccn_shift_left(cc_size n, cc_unit *r, const cc_unit *s, size_t k);
-CC_NONNULL((2, 3))
-void ccn_shift_left_multi(cc_size n, cc_unit *r, const cc_unit *s, size_t k);
+cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k) __asm__("_ccn_shift_right");
/* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most
- significant bit that is 1.
- { N bit } N = n * sizeof(cc_unit) * 8 */
-CC_NONNULL2
+ * significant bit that is 1.
+ * { N bit } N = n * sizeof(cc_unit) * 8
+ *
+ * Runs in constant time, independent of the value of `s`.
+ */
+CC_NONNULL((2))
size_t ccn_bitlen(cc_size n, const cc_unit *s);
-/* Returns the number of bits which are zero before the first one bit
- counting from least to most significant bit. */
-CC_NONNULL2
-size_t ccn_trailing_zeros(cc_size n, const cc_unit *s);
-
/* s == 0 -> return true | s != 0 -> return false
{ N bit } N = n * sizeof(cc_unit) * 8 */
#define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_))
/* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
{ N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */
CC_PURE CC_NONNULL((2, 3))
-int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t);
+int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t) __asm__("_ccn_cmp");
-/* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
- { N bit, M bit -> int } N = ns * sizeof(cc_unit) * 8 M = nt * sizeof(cc_unit) * 8 */
-CC_INLINE CC_NONNULL((2, 4))
-int ccn_cmpn(cc_size ns, const cc_unit *s,
- cc_size nt, const cc_unit *t) {
- if (ns > nt) {
- return 1;
- } else if (ns < nt) {
- return -1;
- }
- return ccn_cmp(ns, s, t);
-}
+/*! @function ccn_cmpn
+ @abstract Compares the values of two big ints of different lengths.
+
+ @discussion The execution time does not depend on the values of either s or t.
+ The function does not hide ns, nt, or whether ns > nt.
+
+ @param ns Length of s
+ @param s First integer
+ @param nt Length of t
+ @param t Second integer
+
+ @return 1 if s > t, -1 if s < t, 0 otherwise.
+ */
+CC_NONNULL_ALL
+int ccn_cmpn(cc_size ns, const cc_unit *s, cc_size nt, const cc_unit *t);
/* s - t -> r return 1 iff t > s
{ N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3, 4))
-cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
-
-/* |s - t| -> r return 1 iff t > s, 0 otherwise */
-cc_unit ccn_abs(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
+cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) __asm__("_ccn_sub");
/* s - v -> r return 1 iff v > s return 0 otherwise.
{ N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
/* s + t -> r return carry if result doesn't fit in n bits.
{ N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3, 4))
-cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
+cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) __asm__("_ccn_add");
/* s + v -> r return carry if result doesn't fit in n bits.
{ N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
}
-CC_NONNULL((2, 3, 4))
-void ccn_lcm(cc_size n, cc_unit *r2n, const cc_unit *s, const cc_unit *t);
-
-
/* s * t -> r_2n r_2n must not overlap with s nor t
{ n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
{ N bit, N bit -> 2N bit } N = ccn_bitsof(n) */
CC_NONNULL((2, 3, 4))
-void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t);
-
-/* s * t -> r_2n r_2n must not overlap with s nor t
- { n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
- { N bit, N bit -> 2N bit } N = ccn_bitsof(n)
- Provide a workspace for potential speedup */
-CC_NONNULL((2, 3, 4, 5))
-void ccn_mul_ws(cc_size count, cc_unit *r, const cc_unit *s, const cc_unit *t, cc_ws_t ws);
+void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t) __asm__("_ccn_mul");
/* s[0..n) * v -> r[0..n)+return value
{ N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3))
cc_unit ccn_addmul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
-#if 0
-/* a % d -> n
- {2 * n bit, n bit -> n bit } n = count * sizeof(cc_unit) * 8 */
-CC_NONNULL((2, 3, 4))
-void ccn_mod(cc_size n, cc_unit *r, const cc_unit *a_2n, const cc_unit *d);
-#endif
-
-/* r = gcd(s, t).
- N bit, N bit -> N bit */
-CC_NONNULL((2, 3, 4))
-void ccn_gcd(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t);
-/* r = gcd(s, t).
- N bit, N bit -> O bit */
-CC_NONNULL((2, 4, 6))
-void ccn_gcdn(cc_size rn, cc_unit *r, cc_size sn, const cc_unit *s, cc_size tn, const cc_unit *t);
+/*!
+ @function ccn_read_uint
+ @abstract Copy big endian integer and represent it in cc_units
+
+ @param n Input allocated size of the cc_unit output array r
+ @param r Ouput cc_unit array for unsigned integer
+ @param data_nbytes Input byte size of data
+ @param data Input unsigned integer represented in big endian
+
+ @result r is initialized with the big unsigned number
+
+ @return 0 if no error, !=0 if the big number cannot be represented in the allocated cc_unit array.
+
+ @discussion The execution pattern of this function depends on both n and data_nbytes but not on data values except the handling
+ of the error case.
+ */
-/* r = (data, len) treated as a big endian byte array, return -1 if data
- doesn't fit in r, return 0 otherwise. */
CC_NONNULL((2, 4))
-int ccn_read_uint(cc_size n, cc_unit *r, size_t data_size, const uint8_t *data);
+int ccn_read_uint(cc_size n, cc_unit *r, size_t data_nbytes, const uint8_t *data);
/* r = (data, len) treated as a big endian byte array, return -1 if data
- doesn't fit in r, return 0 otherwise.
+ doesn't fit in r, return 0 otherwise.
ccn_read_uint strips leading zeroes and doesn't care about sign. */
#define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data)
-/* Return actual size in bytes needed to serialize s. */
-CC_PURE CC_NONNULL2
-size_t ccn_write_uint_size(cc_size n, const cc_unit *s);
+/*!
+ @function ccn_write_uint_size
+ @abstract Compute the minimum size required to store an big integer
+
+ @param n Input size of the cc_unit array representing the input
+ @param s Input cc_unit array
+
+ @result Return value is the exact byte size of the big integer
+
+ @discussion
+ The execution flow is independent on the value of the big integer.
+ However, the use of the returned value may leak the position of the most significant byte
+ */
+CC_PURE CC_NONNULL((2)) size_t ccn_write_uint_size(cc_size n, const cc_unit *s);
-/* Serialize s, to out.
- First byte of byte stream is the m.s. byte of s,
- regardless of the size of cc_unit.
+/*!
+ @function ccn_write_uint
+ @abstract Serialize the big integer into a big endian byte buffer
+
+ @param n Input size of the cc_unit array representing the input
+ @param s Input cc_unit array
+ @param out_size Size of the output buffer
+ @param out Output byte array of size at least out_size
+
+ @discussion This function writes exactly
+ MIN(out_size,ccn_write_uint_size(n,s)) bytes truncating to keep the
+ most significant bytes when out_size<ccn_write_uint_size(n,s). The
+ execution flow of function is based on the position of the most
+ significant byte as well as input sizes.
- No assumption is made about the alignment of out.
+ */
- The out_size argument should be the value returned from ccn_write_uint_size,
- and is also the exact number of bytes this function will write to out.
- If out_size if less than the value returned by ccn_write_uint_size, only the
- first out_size non-zero most significant octets of s will be written. */
CC_NONNULL((2, 4))
void ccn_write_uint(cc_size n, const cc_unit *s, size_t out_size, void *out);
+/*!
+ @function ccn_write_uint_padded_ct
+ @abstract Serialize the big integer into a big endian byte buffer
+
+ @param n Input size of the cc_unit array representing the input
+ @param s Input cc_unit array
+ @param out_size Size of the output buffer
+ @param out Output byte array of size at least out_size
+
+ @return number of leading zero bytes in case of success, a negative error value in case of failure
+
+ @result This function writes exactly out_size byte, padding with zeroes when necessary.
+ This function DOES NOT support truncation and returns an error if out_size < ccn_write_uint_size
+
+ @discussion The execution flow of function is independent on the value of the big integer
+ However, the processing of the return value by the caller may expose the position of
+ the most significant byte
+ */
+CC_NONNULL((2, 4))
+int ccn_write_uint_padded_ct(cc_size n, const cc_unit *s, size_t out_size, uint8_t *out);
-CC_INLINE CC_NONNULL((2, 4))
-cc_size ccn_write_uint_padded(cc_size n, const cc_unit* s, size_t out_size, uint8_t* to)
-{
- size_t bytesInKey = ccn_write_uint_size(n, s);
- cc_size offset = (out_size > bytesInKey) ? out_size - bytesInKey : 0;
-
- cc_zero(offset, to);
- ccn_write_uint(n, s, out_size - offset, to + offset);
+/*!
+ @function ccn_write_uint_padded
+ @abstract Serialize the big integer into a big endian byte buffer
+ Not recommended, for most cases ccn_write_uint_padded_ct is more appropriate
+ Sensitive big integers are exposed since the processing expose the position of the MS byte
+
+ @param n Input size of the cc_unit array representing the input
+ @param s Input cc_unit array
+ @param out_size Size of the output buffer
+ @param out Output byte array of size at least out_size
+
+ @return number of leading zero bytes
+
+ @result This function writes exactly out_size byte, padding with zeroes when necessary.
+ This function DOES support truncation when out_size<ccn_write_uint_size()
+
+ @discussion The execution flow of this function DEPENDS on the position of the most significant byte in
+ case truncation is required.
+ */
+CC_INLINE CC_NONNULL((2, 4)) size_t ccn_write_uint_padded(cc_size n, const cc_unit *s, size_t out_size, uint8_t *out)
+{
+ size_t offset = 0;
+ // Try first the non-truncation case
+ int offset_int = ccn_write_uint_padded_ct(n, s, out_size, out);
+ if (offset_int >= 0) {
+ // It worked
+ offset = (size_t)offset_int;
+ } else {
+ // Truncation case, execution depends on the position of the MSByte
+ ccn_write_uint(n, s, out_size, out);
+ }
return offset;
}
-/* Return actual size in bytes needed to serialize s as int
+/* Return actual size in bytes needed to serialize s as int
(adding leading zero if high bit is set). */
-CC_PURE CC_NONNULL2
+CC_PURE CC_NONNULL((2))
size_t ccn_write_int_size(cc_size n, const cc_unit *s);
/* Serialize s, to out.
CC_NONNULL((2, 4))
void ccn_write_int(cc_size n, const cc_unit *s, size_t out_size, void *out);
-#if CCN_DEDICATED_SQR
-
-/* s^2 -> r
- { n bit -> 2 * n bit } */
-CC_NONNULL((2, 3))
-void ccn_sqr(cc_size n, cc_unit *r, const cc_unit *s);
-
-/* s^2 -> r
- { n bit -> 2 * n bit } */
-CC_NONNULL((2, 3, 4))
-void ccn_sqr_ws(cc_size n, cc_unit *r, const cc_unit *s, cc_ws_t ws);
-
-#else
-
-/* s^2 -> r
- { n bit -> 2 * n bit } */
-CC_INLINE CC_NONNULL((2, 3))
-void ccn_sqr(cc_size n, cc_unit *r, const cc_unit *s) {
- ccn_mul(n, r, s, s);
-}
-
-/* s^2 -> r
- { n bit -> 2 * n bit } */
-CC_INLINE CC_NONNULL((2, 3, 4))
-void ccn_sqr_ws(cc_size n, cc_unit *r, const cc_unit *s, cc_ws_t ws) {
- ccn_mul_ws(n, r, s, s, ws);
-}
-
-#endif
-
/* s -> r
{ n bit -> n bit } */
CC_NONNULL((2, 3))
void ccn_set(cc_size n, cc_unit *r, const cc_unit *s);
-CC_INLINE CC_NONNULL2
+CC_INLINE CC_NONNULL((2))
void ccn_zero(cc_size n, cc_unit *r) {
- cc_zero(ccn_sizeof_n(n),r);
+ cc_clear(ccn_sizeof_n(n),r);
}
-CC_INLINE CC_NONNULL2
+CC_INLINE CC_NONNULL((2))
void ccn_clear(cc_size n, cc_unit *r) {
cc_clear(ccn_sizeof_n(n),r);
}
-CC_NONNULL2
+CC_NONNULL((2))
void ccn_zero_multi(cc_size n, cc_unit *r, ...);
-CC_INLINE CC_NONNULL2
+CC_INLINE CC_NONNULL((2))
void ccn_seti(cc_size n, cc_unit *r, cc_unit v) {
- /* assert(n > 0); */
+ assert(n > 0);
r[0] = v;
ccn_zero(n - 1, r + 1);
}
CC_INLINE CC_NONNULL((2, 4))
void ccn_setn(cc_size n, cc_unit *r, const cc_size s_size, const cc_unit *s) {
- /* FIXME: assert not available in kernel.
assert(n > 0);
assert(s_size > 0);
assert(s_size <= n);
- */
ccn_set(s_size, r, s);
ccn_zero(n - s_size, r + s_size);
}
#endif
/* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */
-CC_INLINE CC_NONNULL2
+CC_INLINE CC_NONNULL((2))
void ccn_swap(cc_size n, cc_unit *r) {
cc_unit *e;
for (e = r + n - 1; r < e; ++r, --e) {
}
/* Debugging */
-CC_NONNULL2
+CC_NONNULL((2))
void ccn_print(cc_size n, const cc_unit *s);
-CC_NONNULL3
+CC_NONNULL((3))
void ccn_lprint(cc_size n, const char *label, const cc_unit *s);
/* Forward declaration so we don't depend on ccrng.h. */
CC_NONNULL((2, 3))
int ccn_random_bits(cc_size nbits, cc_unit *r, struct ccrng_state *rng);
-/*!
- @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)
-
- @param nd length of array d
- @param recip returned reciprocal of size nd+1
- @param d input number d
-*/
-CC_NONNULL((2, 3))
-void ccn_make_recip(cc_size nd, cc_unit *recip, const cc_unit *d);
-
CC_NONNULL((6, 8))
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);
#define ccn_div(nq, q, na, a, nd, d) ccn_div_euclid(nq, q, 0, NULL, na, a, nd, d)
#define ccn_mod(nr, r, na, a, nd, d) ccn_div_euclid(0 , NULL, nr, r, na, a, nd, d)
-/*!
- @brief ccn_div_use_recip(nq, q, nr, r, na, a, nd, d) comutes q=a/d and r=a%d
- @discussion q and rcan be NULL. Reads na from a and nd from d. Writes nq in q and nr in r. nq and nr must be large enough to accomodate results, otherwise error is retuned. Execution time depends on the size of a. Computation is perfomed on of fixedsize and the leadig zeros of a of q are are also used in the computation.
- @param nq length of array q that hold the quotients. The maximum length of quotient is the actual length of dividend a
- @param q returned quotient. If nq is larger than needed, it is filled with leading zeros. If it is smaller, error is returned. q can be set to NULL, if not needed.
- @param nr length of array r that hold the remainder. The maximum length of remainder is the actual length of divisor d
- @param r returned remainder. If nr is larger than needed, it is filled with leading zeros. Ifi is smaller error is returned. r can be set to NULL if not required.
- @param na length of dividend. Dividend may have leading zeros.
- @param a input Dividend
- @param nd length of input divisor. Divisor may have leading zeros.
- @param d input Divisor
- @param recip_d The reciprocal of d, of length nd+1.
-
- @return returns 0 if successful, negative of error.
- */
-CC_NONNULL((6, 8, 9))
-int ccn_div_use_recip(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, const cc_unit *recip_d);
-
#endif /* _CORECRYPTO_CCN_H_ */