^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* mpi-internal.h - Internal to the Multi Precision Integers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1998, 2000 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is part of GnuPG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Note: This code is heavily based on the GNU MP Library.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Actually it's the same code with only minor changes in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * way the data is stored; this is to support the abstraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * of an optional secure memory allocation which may be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * to avoid revealing of sensitive data due to paging etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * The GNU MP Library itself is published under the LGPL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * however I decided to publish this code under the plain GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #ifndef G10_MPI_INTERNAL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define G10_MPI_INTERNAL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define log_debug printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define log_bug printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define assert(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (!x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) log_bug("failed assertion\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* If KARATSUBA_THRESHOLD is not already defined, define it to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * value which is good on most machines. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* tested 4, 16, 32 and 64, where 16 gave the best performance when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * checking a 768 and a 1024 bit ElGamal signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * (wk 22.12.97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #ifndef KARATSUBA_THRESHOLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define KARATSUBA_THRESHOLD 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #if KARATSUBA_THRESHOLD < 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #undef KARATSUBA_THRESHOLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define KARATSUBA_THRESHOLD 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) typedef int mpi_size_t; /* (must be a signed type) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define RESIZE_IF_NEEDED(a, b) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if ((a)->alloced < (b)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mpi_resize((a), (b)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Copy N limbs from S to D. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MPN_COPY(d, s, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mpi_size_t _i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) for (_i = 0; _i < (n); _i++) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) (d)[_i] = (s)[_i]; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MPN_COPY_INCR(d, s, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) mpi_size_t _i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) for (_i = 0; _i < (n); _i++) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) (d)[_i] = (s)[_i]; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MPN_COPY_DECR(d, s, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) mpi_size_t _i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) for (_i = (n)-1; _i >= 0; _i--) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) (d)[_i] = (s)[_i]; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Zero N limbs at D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define MPN_ZERO(d, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int _i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) for (_i = 0; _i < (n); _i++) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) (d)[_i] = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define MPN_NORMALIZE(d, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) while ((n) > 0) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if ((d)[(n)-1]) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (n)--; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if ((size) < KARATSUBA_THRESHOLD) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) mul_n_basecase(prodp, up, vp, size); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mul_n(prodp, up, vp, size, tspace); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * If this would yield overflow, DI should be the largest possible number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * (i.e., only ones). For correct operation, the most significant bit of D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * has to be set. Put the quotient in Q and the remainder in R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mpi_limb_t _ql __maybe_unused; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mpi_limb_t _q, _r; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mpi_limb_t _xh, _xl; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) umul_ppmm(_q, _ql, (nh), (di)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) umul_ppmm(_xh, _xl, _q, (d)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) sub_ddmmss(_xh, _r, (nh), (nl), _xh, _xl); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (_xh) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) _q++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (_xh) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) sub_ddmmss(_xh, _r, _xh, _r, 0, (d)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) _q++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (_r >= (d)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) _r -= (d); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) _q++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) (r) = _r; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) (q) = _q; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*-- mpiutil.c --*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void mpi_free_limb_space(mpi_ptr_t a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static inline mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) mpi_size_t s1_size, mpi_limb_t s2_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mpi_limb_t mpihelp_add_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mpi_ptr_t s2_ptr, mpi_size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static inline mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mpi_ptr_t s2_ptr, mpi_size_t s2_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static inline mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mpi_size_t s1_size, mpi_limb_t s2_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mpi_limb_t mpihelp_sub_n(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mpi_ptr_t s2_ptr, mpi_size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mpi_ptr_t s2_ptr, mpi_size_t s2_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*-- mpih-cmp.c --*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int mpihelp_cmp(mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*-- mpih-mul.c --*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct karatsuba_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct karatsuba_ctx *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) mpi_ptr_t tspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mpi_size_t tspace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) mpi_ptr_t tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) mpi_size_t tp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) void mpihelp_release_karatsuba_ctx(struct karatsuba_ctx *ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mpi_limb_t mpihelp_addmul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mpi_size_t s1_size, mpi_limb_t s2_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mpi_limb_t mpihelp_submul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mpi_size_t s1_size, mpi_limb_t s2_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int mpihelp_mul(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mpi_ptr_t vp, mpi_size_t vsize, mpi_limb_t *_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) void mpih_sqr_n_basecase(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void mpih_sqr_n(mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mpi_ptr_t tspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) void mpihelp_mul_n(mpi_ptr_t prodp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int mpihelp_mul_karatsuba_case(mpi_ptr_t prodp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) mpi_ptr_t up, mpi_size_t usize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mpi_ptr_t vp, mpi_size_t vsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct karatsuba_ctx *ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*-- generic_mpih-mul1.c --*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mpi_limb_t mpihelp_mul_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mpi_size_t s1_size, mpi_limb_t s2_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*-- mpih-div.c --*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) mpi_limb_t divisor_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) mpi_limb_t mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) mpi_ptr_t np, mpi_size_t nsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mpi_ptr_t dp, mpi_size_t dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mpi_limb_t mpihelp_divmod_1(mpi_ptr_t quot_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mpi_limb_t divisor_limb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*-- generic_mpih-[lr]shift.c --*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) mpi_limb_t mpihelp_lshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mpi_limb_t mpihelp_rshift(mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Define stuff for longlong.h. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define W_TYPE_SIZE BITS_PER_MPI_LIMB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) typedef mpi_limb_t UWtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) typedef unsigned int UHWtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #if defined(__GNUC__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) typedef unsigned int UQItype __attribute__ ((mode(QI)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) typedef int SItype __attribute__ ((mode(SI)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) typedef unsigned int USItype __attribute__ ((mode(SI)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) typedef int DItype __attribute__ ((mode(DI)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) typedef unsigned int UDItype __attribute__ ((mode(DI)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) typedef unsigned char UQItype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) typedef long SItype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) typedef unsigned long USItype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #ifdef __GNUC__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #include "mpi-inline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #endif /*G10_MPI_INTERNAL_H */