0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef G10_MPI_INTERNAL_H
0018 #define G10_MPI_INTERNAL_H
0019
0020 #include <linux/module.h>
0021 #include <linux/kernel.h>
0022 #include <linux/slab.h>
0023 #include <linux/string.h>
0024 #include <linux/mpi.h>
0025 #include <linux/errno.h>
0026
0027 #define log_debug printk
0028 #define log_bug printk
0029
0030 #define assert(x) \
0031 do { \
0032 if (!x) \
0033 log_bug("failed assertion\n"); \
0034 } while (0);
0035
0036
0037
0038
0039
0040
0041
0042 #ifndef KARATSUBA_THRESHOLD
0043 #define KARATSUBA_THRESHOLD 16
0044 #endif
0045
0046
0047 #if KARATSUBA_THRESHOLD < 2
0048 #undef KARATSUBA_THRESHOLD
0049 #define KARATSUBA_THRESHOLD 2
0050 #endif
0051
0052 typedef mpi_limb_t *mpi_ptr_t;
0053 typedef int mpi_size_t;
0054
0055 #define RESIZE_IF_NEEDED(a, b) \
0056 do { \
0057 if ((a)->alloced < (b)) \
0058 mpi_resize((a), (b)); \
0059 } while (0)
0060
0061
0062 #define MPN_COPY(d, s, n) \
0063 do { \
0064 mpi_size_t _i; \
0065 for (_i = 0; _i < (n); _i++) \
0066 (d)[_i] = (s)[_i]; \
0067 } while (0)
0068
0069 #define MPN_COPY_INCR(d, s, n) \
0070 do { \
0071 mpi_size_t _i; \
0072 for (_i = 0; _i < (n); _i++) \
0073 (d)[_i] = (s)[_i]; \
0074 } while (0)
0075
0076
0077 #define MPN_COPY_DECR(d, s, n) \
0078 do { \
0079 mpi_size_t _i; \
0080 for (_i = (n)-1; _i >= 0; _i--) \
0081 (d)[_i] = (s)[_i]; \
0082 } while (0)
0083
0084
0085 #define MPN_ZERO(d, n) \
0086 do { \
0087 int _i; \
0088 for (_i = 0; _i < (n); _i++) \
0089 (d)[_i] = 0; \
0090 } while (0)
0091
0092 #define MPN_NORMALIZE(d, n) \
0093 do { \
0094 while ((n) > 0) { \
0095 if ((d)[(n)-1]) \
0096 break; \
0097 (n)--; \
0098 } \
0099 } while (0)
0100
0101 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
0102 do { \
0103 if ((size) < KARATSUBA_THRESHOLD) \
0104 mul_n_basecase(prodp, up, vp, size); \
0105 else \
0106 mul_n(prodp, up, vp, size, tspace); \
0107 } while (0);
0108
0109
0110
0111
0112
0113
0114
0115 #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
0116 do { \
0117 mpi_limb_t _ql __maybe_unused; \
0118 mpi_limb_t _q, _r; \
0119 mpi_limb_t _xh, _xl; \
0120 umul_ppmm(_q, _ql, (nh), (di)); \
0121 _q += (nh); \
0122 umul_ppmm(_xh, _xl, _q, (d)); \
0123 sub_ddmmss(_xh, _r, (nh), (nl), _xh, _xl); \
0124 if (_xh) { \
0125 sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \
0126 _q++; \
0127 if (_xh) { \
0128 sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \
0129 _q++; \
0130 } \
0131 } \
0132 if (_r >= (d)) { \
0133 _r -= (d); \
0134 _q++; \
0135 } \
0136 (r) = _r; \
0137 (q) = _q; \
0138 } while (0)
0139
0140
0141
0142 mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs);
0143 void mpi_free_limb_space(mpi_ptr_t a);
0144 void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs);
0145
0146 static inline mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0147 mpi_size_t s1_size, mpi_limb_t s2_limb);
0148 mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0149 mpi_ptr_t s2_ptr, mpi_size_t size);
0150 static inline mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
0151 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
0152
0153 static inline mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0154 mpi_size_t s1_size, mpi_limb_t s2_limb);
0155 mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0156 mpi_ptr_t s2_ptr, mpi_size_t size);
0157 static inline mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
0158 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
0159
0160
0161 int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size);
0162
0163
0164
0165 struct karatsuba_ctx {
0166 struct karatsuba_ctx *next;
0167 mpi_ptr_t tspace;
0168 mpi_size_t tspace_size;
0169 mpi_ptr_t tp;
0170 mpi_size_t tp_size;
0171 };
0172
0173 void mpihelp_release_karatsuba_ctx(struct karatsuba_ctx *ctx);
0174
0175 mpi_limb_t mpihelp_addmul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0176 mpi_size_t s1_size, mpi_limb_t s2_limb);
0177 mpi_limb_t mpihelp_submul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0178 mpi_size_t s1_size, mpi_limb_t s2_limb);
0179 int mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
0180 mpi_ptr_t vp, mpi_size_t vsize, mpi_limb_t *_result);
0181 void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size);
0182 void mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
0183 mpi_ptr_t tspace);
0184 void mpihelp_mul_n(mpi_ptr_t prodp,
0185 mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size);
0186
0187 int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp,
0188 mpi_ptr_t up, mpi_size_t usize,
0189 mpi_ptr_t vp, mpi_size_t vsize,
0190 struct karatsuba_ctx *ctx);
0191
0192
0193 mpi_limb_t mpihelp_mul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0194 mpi_size_t s1_size, mpi_limb_t s2_limb);
0195
0196
0197 mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
0198 mpi_limb_t divisor_limb);
0199 mpi_limb_t mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
0200 mpi_ptr_t np, mpi_size_t nsize,
0201 mpi_ptr_t dp, mpi_size_t dsize);
0202 mpi_limb_t mpihelp_divmod_1(mpi_ptr_t quot_ptr,
0203 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
0204 mpi_limb_t divisor_limb);
0205
0206
0207 mpi_limb_t mpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
0208 unsigned cnt);
0209 mpi_limb_t mpihelp_rshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
0210 unsigned cnt);
0211
0212
0213 #define W_TYPE_SIZE BITS_PER_MPI_LIMB
0214 typedef mpi_limb_t UWtype;
0215 typedef unsigned int UHWtype;
0216 #if defined(__GNUC__)
0217 typedef unsigned int UQItype __attribute__ ((mode(QI)));
0218 typedef int SItype __attribute__ ((mode(SI)));
0219 typedef unsigned int USItype __attribute__ ((mode(SI)));
0220 typedef int DItype __attribute__ ((mode(DI)));
0221 typedef unsigned int UDItype __attribute__ ((mode(DI)));
0222 #else
0223 typedef unsigned char UQItype;
0224 typedef long SItype;
0225 typedef unsigned long USItype;
0226 #endif
0227
0228 #ifdef __GNUC__
0229 #include "mpi-inline.h"
0230 #endif
0231
0232 #endif