| 1 | /* |
| 2 | * cczp.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_CCZP_H_ |
| 12 | #define _CORECRYPTO_CCZP_H_ |
| 13 | |
| 14 | #include <corecrypto/ccn.h> |
| 15 | #include <corecrypto/ccrng.h> |
| 16 | |
| 17 | /* |
| 18 | Don't use cczp_hd struct directly, except in static tables such as eliptic curve parameter |
| 19 | definitions. |
| 20 | |
| 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(). |
| 23 | */ |
| 24 | |
| 25 | struct cczp; |
| 26 | |
| 27 | typedef struct cczp *cczp_t; |
| 28 | typedef const struct cczp *cczp_const_t; |
| 29 | |
| 30 | typedef void (*ccmod_func_t)(cc_ws_t ws, cczp_const_t zp, cc_unit *r, const cc_unit *s); |
| 31 | |
| 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 (pre) \ |
| 37 | cc_size pre##n; \ |
| 38 | cc_unit pre##options; \ |
| 39 | ccmod_func_t pre##mod_prime; |
| 40 | |
| 41 | #define __CCZP_ELEMENTS_DEFINITIONS(pre) \ |
| 42 | __CCZP_HEADER_ELEMENTS_DEFINITIONS(pre) \ |
| 43 | cc_unit pre##ccn[]; |
| 44 | |
| 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 |
| 47 | struct cczp_hd { |
| 48 | __CCZP_HEADER_ELEMENTS_DEFINITIONS() |
| 49 | } CC_ALIGNED(CCN_UNIT_SIZE); |
| 50 | |
| 51 | struct cczp { |
| 52 | __CCZP_ELEMENTS_DEFINITIONS() |
| 53 | } CC_ALIGNED(CCN_UNIT_SIZE); |
| 54 | |
| 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_)) |
| 57 | |
| 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_)) |
| 61 | |
| 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_)) |
| 67 | |
| 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_) |
| 71 | |
| 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_) |
| 74 | |
| 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) |
| 82 | { |
| 83 | return zp->n; |
| 84 | } |
| 85 | |
| 86 | CC_CONST CC_NONNULL((1)) static inline cc_unit cczp_options(cczp_const_t zp) |
| 87 | { |
| 88 | return zp->options; |
| 89 | } |
| 90 | |
| 91 | CC_CONST CC_NONNULL((1)) static inline ccmod_func_t cczp_mod_prime(cczp_const_t zp) |
| 92 | { |
| 93 | return zp->mod_prime; |
| 94 | } |
| 95 | |
| 96 | CC_CONST CC_NONNULL((1)) static inline const cc_unit *cczp_prime(cczp_const_t zp) |
| 97 | { |
| 98 | return zp->ccn; |
| 99 | } |
| 100 | |
| 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)) |
| 104 | |
| 105 | static inline const cc_unit *cczp_recip(cczp_const_t zp) |
| 106 | { |
| 107 | return zp->ccn + zp->n; |
| 108 | } |
| 109 | |
| 110 | CC_CONST CC_NONNULL((1)) CC_INLINE size_t cczp_bitlen(cczp_const_t zp) |
| 111 | { |
| 112 | return ccn_bitlen(cczp_n(zp), cczp_prime(zp)); |
| 113 | } |
| 114 | |
| 115 | /* Ensure both cczp_mod_prime(zp) and cczp_recip(zp) are valid. cczp_n and |
| 116 | cczp_prime must have been previously initialized. */ |
| 117 | CC_NONNULL((1)) |
| 118 | int cczp_init(cczp_t zp); |
| 119 | |
| 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); |
| 126 | |
| 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); |
| 133 | |
| 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); |
| 142 | |
| 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. |
| 151 | */ |
| 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); |
| 154 | |
| 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. |
| 163 | |
| 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 |
| 166 | */ |
| 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); |
| 169 | |
| 170 | /*! |
| 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. |
| 181 | */ |
| 182 | CC_NONNULL((1, 2, 3)) |
| 183 | int cczp_inv(cczp_const_t zp, cc_unit *r, const cc_unit *x); |
| 184 | |
| 185 | /*! |
| 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 |
| 193 | */ |
| 194 | CC_NONNULL((1, 2, 3)) int cczp_inv_odd(cczp_const_t zp, cc_unit *r, const cc_unit *x); |
| 195 | |
| 196 | /*! |
| 197 | @brief cczp_inv_field(zp, r, x) computes r = x^-1 (mod p) , where p=cczp_prime(zp) is a prime |
| 198 | number number. |
| 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) |
| 203 | |
| 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. |
| 209 | */ |
| 210 | CC_NONNULL((1, 2, 3)) |
| 211 | int cczp_inv_field(cczp_const_t zp, cc_unit *r, const cc_unit *x); |
| 212 | |
| 213 | #endif /* _CORECRYPTO_CCZP_H_ */ |
| 214 | |