]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/cczp.h
5 * Created on 11/16/2010
7 * Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
11 #ifndef _CORECRYPTO_CCZP_H_
12 #define _CORECRYPTO_CCZP_H_
14 #include <corecrypto/ccn.h>
15 #include <corecrypto/ccrng.h>
18 Don't use cczp_hd struct directly, except in static tables such as eliptic curve parameter
21 Declare cczp objects using cczp_decl_n(). It allocates cc_unit arrays of the length returned by
22 either cczp_nof_n() or cczp_short_nof_n().
27 typedef struct cczp
*cczp_t
;
28 typedef const struct cczp
*cczp_const_t
;
30 typedef void (*ccmod_func_t
)(cc_ws_t ws
, cczp_const_t zp
, cc_unit
*r
, const cc_unit
*s
);
32 // keep cczp_hd and cczp structures consistent
33 // cczp_hd is typecasted to cczp to read EC curve params
34 // options field is to specify Montgomery arithmetic, bit field, etc
35 // make sure n is the first element see ccrsa_ctx_n macro
36 #define __CCZP_HEADER_ELEMENTS_DEFINITIONS(pre) \
38 cc_unit pre##options; \
39 ccmod_func_t pre##mod_prime;
41 #define __CCZP_ELEMENTS_DEFINITIONS(pre) \
42 __CCZP_HEADER_ELEMENTS_DEFINITIONS(pre) \
45 // cczp_hd must be defined separetly without variable length array ccn[], because it is used in
46 // sructures such as ccdh_gp_decl_n
48 __CCZP_HEADER_ELEMENTS_DEFINITIONS()
49 } CC_ALIGNED(CCN_UNIT_SIZE
);
52 __CCZP_ELEMENTS_DEFINITIONS()
53 } CC_ALIGNED(CCN_UNIT_SIZE
);
55 /* Return the size of an cczp where each ccn is _size_ bytes. */
56 #define cczp_size(_size_) (sizeof(struct cczp) + ccn_sizeof_n(1) + 2 * (_size_))
58 /* Return number of units that a struct cczp needs to be in units for a prime
59 size of N units. This is large enough for all operations. */
60 #define cczp_nof_n(_n_) (ccn_nof_size(sizeof(struct cczp)) + 1 + 2 * (_n_))
62 /* Return number of units that a struct cczp needs to be in units for a prime
63 size of _n_ units. The _short variant does not have room for CCZP_RECIP,
64 so it can not be used with cczp_mod, cczp_mul, cczp_sqr. It can be used
65 with cczp_add, cczp_sub, cczp_div2, cczp_mod_inv. */
66 #define cczp_short_nof_n(_n_) (ccn_nof_size(sizeof(struct cczp)) + (_n_))
68 #define cczp_decl_n(_n_, _name_) cc_ctx_decl(struct cczp, ccn_sizeof_n(cczp_nof_n(_n_)), _name_)
69 #define cczp_short_decl_n(_n_, _name_) \
70 cc_ctx_decl(struct cczp_short, ccn_sizeof_n(cczp_short_nof_n(_n_)), _name_)
72 #define cczp_clear_n(_n_, _name_) cc_clear(ccn_sizeof_n(cczp_nof_n(_n_)), _name_)
73 #define cczp_short_clear_n(_n_, _name_) cc_clear(ccn_sizeof_n(cczp_short_nof_n(_n_)), _name_)
75 #define CCZP_N(ZP) ((ZP)->n)
76 #define CCZP_MOD(ZP) ((ZP)->mod_prime)
77 #define CCZP_MOD_PRIME(ZP) CCZP_MOD(ZP)
78 #define CCZP_PRIME(ZP) ((ZP)->ccn)
79 #define CCZP_RECIP(ZP) ((ZP)->ccn + CCZP_N(ZP))
80 #define CCZP_OPS(ZP) ((ZP)->options)
81 CC_CONST
CC_NONNULL((1)) static inline cc_size
cczp_n(cczp_const_t zp
)
86 CC_CONST
CC_NONNULL((1)) static inline cc_unit
cczp_options(cczp_const_t zp
)
91 CC_CONST
CC_NONNULL((1)) static inline ccmod_func_t
cczp_mod_prime(cczp_const_t zp
)
96 CC_CONST
CC_NONNULL((1)) static inline const cc_unit
*cczp_prime(cczp_const_t zp
)
101 /* Return a pointer to the Reciprocal or Montgomery constant of zp, which is
102 allocated cczp_n(zp) + 1 units long. */
103 CC_CONST
CC_NONNULL((1))
105 static inline const cc_unit
*cczp_recip(cczp_const_t zp
)
107 return zp
->ccn
+ zp
->n
;
110 CC_CONST
CC_NONNULL((1)) CC_INLINE
size_t cczp_bitlen(cczp_const_t zp
)
112 return ccn_bitlen(cczp_n(zp
), cczp_prime(zp
));
115 /* Ensure both cczp_mod_prime(zp) and cczp_recip(zp) are valid. cczp_n and
116 cczp_prime must have been previously initialized. */
118 int cczp_init(cczp_t zp
);
120 /* Compute r = s2n mod cczp_prime(zp). Will write cczp_n(zp)
121 units to r and reads 2 * cczp_n(zp) units units from s2n. If r and s2n are not
122 identical they must not overlap. Before calling this function either
123 cczp_init(zp) must have been called or both CCZP_MOD_PRIME((cc_unit *)zp)
124 and CCZP_RECIP((cc_unit *)zp) must be initialized some other way. */
125 CC_NONNULL((1, 2, 3)) void cczp_mod(cc_ws_t ws
, cczp_const_t zp
, cc_unit
*r
, const cc_unit
*s2n
);
127 /* Compute r = sn mod cczp_prime(zp), Will write cczp_n(zp)
128 units to r and reads sn units units from s. If r and s are not
129 identical they must not overlap. Before calling this function either
130 cczp_init(zp) must have been called or both CCZP_MOD_PRIME((cc_unit *)zp)
131 and CCZP_RECIP((cc_unit *)zp) must be initialized some other way. */
132 CC_NONNULL((1, 2, 4)) int cczp_modn(cczp_const_t zp
, cc_unit
*r
, cc_size ns
, const cc_unit
*s
);
134 /* Compute r = x * y mod cczp_prime(zp). Will write cczp_n(zp) units to r
135 and reads cczp_n(zp) units units from both x and y. If r and x are not
136 identical they must not overlap, The same holds for r and y. Before
137 calling this function either cczp_init(zp) must have been called or both
138 CCZP_MOD_PRIME((cc_unit *)zp) and CCZP_RECIP((cc_unit *)zp) must be
139 initialized some other way. */
140 CC_NONNULL((1, 2, 3, 4))
141 void cczp_mul(cczp_const_t zp
, cc_unit
*t
, const cc_unit
*x
, const cc_unit
*y
);
143 /* Compute r = m ^ e mod cczp_prime(zp), using Montgomery ladder.
144 - writes cczp_n(zp) units to r
145 - reads cczp_n(zp) units units from m and e
146 - if r and m are not identical they must not overlap.
147 - r and e must not overlap nor be identical.
148 - before calling this function either cczp_init(zp) must have been called
149 or both CCZP_MOD_PRIME((cc_unit *)zp) and CCZP_RECIP((cc_unit *)zp) must
150 be initialized some other way.
152 CC_NONNULL((1, 2, 3, 4))
153 int cczp_power(cczp_const_t zp
, cc_unit
*r
, const cc_unit
*m
, const cc_unit
*e
);
155 /* Compute r = m ^ e mod cczp_prime(zp), using Square Square Multiply Always.
156 - writes cczp_n(zp) units to r
157 - reads cczp_n(zp) units units from m and e
158 - if r and m are not identical they must not overlap.
159 - r and e must not overlap nor be identical.
160 - before calling this function either cczp_init(zp) must have been called
161 or both CCZP_MOD_PRIME((cc_unit *)zp) and CCZP_RECIP((cc_unit *)zp) must
162 be initialized some other way.
164 Important: This function is intented to be constant time but is more likely
165 to leak information due to memory cache. Only used with randomized input
167 CC_NONNULL((1, 2, 3, 4))
168 int cczp_power_ssma(cczp_const_t zp
, cc_unit
*r
, const cc_unit
*m
, const cc_unit
*e
);
171 @brief cczp_inv(zp, r, x) computes r = x^-1 (mod p) , where p=cczp_prime(zp).
172 @discussion It is a general function and works for any p. It validates the inputs. r and x can
173 overlap. It writes n =cczp_n(zp) units to r, and read n units units from x and p. The output r is
174 overwriten only if the inverse is correctly computed. This function is not constant time in
175 absolute sense, but it does not have data dependent 'if' statements in the code.
176 @param zp The input zp. cczp_n(zp) and cczp_prime(zp) need to be valid. cczp_init(zp) need not to
177 be called before invoking cczp_inv().
178 @param x input big integer
179 @param r output big integer
180 @return 0 if inverse exists and correctly computed.
182 CC_NONNULL((1, 2, 3))
183 int cczp_inv(cczp_const_t zp
, cc_unit
*r
, const cc_unit
*x
);
186 @brief cczp_inv_odd(zp, r, x) computes r = x^-1 (mod p) , where p=cczp_prime(zp) is an odd number.
187 @discussion r and x can overlap.
188 @param zp The input zp. cczp_n(zp) and cczp_prime(zp) need to be valid. cczp_init(zp) need not to
189 be called before invoking.
190 @param x input big integer
191 @param r output big integer
192 @return 0 if successful
194 CC_NONNULL((1, 2, 3)) int cczp_inv_odd(cczp_const_t zp
, cc_unit
*r
, const cc_unit
*x
);
197 @brief cczp_inv_field(zp, r, x) computes r = x^-1 (mod p) , where p=cczp_prime(zp) is a prime
199 @discussion r and x must NOT overlap. The excution time of the function is independent to the value
200 of the input x. It works only if p is a field. That is, when p is a prime. It supports Montgomery
201 and non-Montgomery form of zp. It leaks the value of the prime and should only be used be used for
202 public (not secret) primes (ex. Elliptic Curves)
204 @param zp The input zp. cczp_n(zp) and cczp_prime(zp) need to be valid. cczp_init(zp) need not to
205 be called before invoking cczp_inv_field().
206 @param x input big unteger
207 @param r output big integer
208 @return 0 if inverse exists and correctly computed.
210 CC_NONNULL((1, 2, 3))
211 int cczp_inv_field(cczp_const_t zp
, cc_unit
*r
, const cc_unit
*x
);
213 #endif /* _CORECRYPTO_CCZP_H_ */