Home | History | Annotate | Line # | Download | only in generic
sec_powm.c revision 1.1
      1  1.1  mrg /* mpn_sec_powm -- Compute R = U^E mod M.  Secure variant, side-channel silent
      2  1.1  mrg    under the assumption that the multiply instruction is side channel silent.
      3  1.1  mrg 
      4  1.1  mrg    Contributed to the GNU project by Torbjrn Granlund.
      5  1.1  mrg 
      6  1.1  mrg Copyright 2007-2009, 2011-2014 Free Software Foundation, Inc.
      7  1.1  mrg 
      8  1.1  mrg This file is part of the GNU MP Library.
      9  1.1  mrg 
     10  1.1  mrg The GNU MP Library is free software; you can redistribute it and/or modify
     11  1.1  mrg it under the terms of either:
     12  1.1  mrg 
     13  1.1  mrg   * the GNU Lesser General Public License as published by the Free
     14  1.1  mrg     Software Foundation; either version 3 of the License, or (at your
     15  1.1  mrg     option) any later version.
     16  1.1  mrg 
     17  1.1  mrg or
     18  1.1  mrg 
     19  1.1  mrg   * the GNU General Public License as published by the Free Software
     20  1.1  mrg     Foundation; either version 2 of the License, or (at your option) any
     21  1.1  mrg     later version.
     22  1.1  mrg 
     23  1.1  mrg or both in parallel, as here.
     24  1.1  mrg 
     25  1.1  mrg The GNU MP Library is distributed in the hope that it will be useful, but
     26  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     27  1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     28  1.1  mrg for more details.
     29  1.1  mrg 
     30  1.1  mrg You should have received copies of the GNU General Public License and the
     31  1.1  mrg GNU Lesser General Public License along with the GNU MP Library.  If not,
     32  1.1  mrg see https://www.gnu.org/licenses/.  */
     33  1.1  mrg 
     34  1.1  mrg 
     35  1.1  mrg /*
     36  1.1  mrg   BASIC ALGORITHM, Compute U^E mod M, where M < B^n is odd.
     37  1.1  mrg 
     38  1.1  mrg   1. T <- (B^n * U) mod M                Convert to REDC form
     39  1.1  mrg 
     40  1.1  mrg   2. Compute table U^0, U^1, U^2... of E-dependent size
     41  1.1  mrg 
     42  1.1  mrg   3. While there are more bits in E
     43  1.1  mrg        W <- power left-to-right base-k
     44  1.1  mrg 
     45  1.1  mrg 
     46  1.1  mrg   TODO:
     47  1.1  mrg 
     48  1.1  mrg    * Make getbits a macro, thereby allowing it to update the index operand.
     49  1.1  mrg      That will simplify the code using getbits.  (Perhaps make getbits' sibling
     50  1.1  mrg      getbit then have similar form, for symmetry.)
     51  1.1  mrg 
     52  1.1  mrg    * Choose window size without looping.  (Superoptimize or think(tm).)
     53  1.1  mrg 
     54  1.1  mrg    * REDC_1_TO_REDC_2_THRESHOLD might actually represent the cutoff between
     55  1.1  mrg      redc_1 and redc_n.  On such systems, we will switch to redc_2 causing
     56  1.1  mrg      slowdown.
     57  1.1  mrg */
     58  1.1  mrg 
     59  1.1  mrg #include "gmp.h"
     60  1.1  mrg #include "gmp-impl.h"
     61  1.1  mrg #include "longlong.h"
     62  1.1  mrg 
     63  1.1  mrg #undef MPN_REDC_1_SEC
     64  1.1  mrg #define MPN_REDC_1_SEC(rp, up, mp, n, invm)				\
     65  1.1  mrg   do {									\
     66  1.1  mrg     mp_limb_t cy;							\
     67  1.1  mrg     cy = mpn_redc_1 (rp, up, mp, n, invm);				\
     68  1.1  mrg     mpn_cnd_sub_n (cy, rp, rp, mp, n);					\
     69  1.1  mrg   } while (0)
     70  1.1  mrg 
     71  1.1  mrg #undef MPN_REDC_2_SEC
     72  1.1  mrg #define MPN_REDC_2_SEC(rp, up, mp, n, mip)				\
     73  1.1  mrg   do {									\
     74  1.1  mrg     mp_limb_t cy;							\
     75  1.1  mrg     cy = mpn_redc_2 (rp, up, mp, n, mip);				\
     76  1.1  mrg     mpn_cnd_sub_n (cy, rp, rp, mp, n);					\
     77  1.1  mrg   } while (0)
     78  1.1  mrg 
     79  1.1  mrg #if HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2
     80  1.1  mrg #define WANT_REDC_2 1
     81  1.1  mrg #endif
     82  1.1  mrg 
     83  1.1  mrg /* Define our own mpn squaring function.  We do this since we cannot use a
     84  1.1  mrg    native mpn_sqr_basecase over TUNE_SQR_TOOM2_MAX, or a non-native one over
     85  1.1  mrg    SQR_TOOM2_THRESHOLD.  This is so because of fixed size stack allocations
     86  1.1  mrg    made inside mpn_sqr_basecase.  */
     87  1.1  mrg 
     88  1.1  mrg #if HAVE_NATIVE_mpn_sqr_diagonal
     89  1.1  mrg #define MPN_SQR_DIAGONAL(rp, up, n)					\
     90  1.1  mrg   mpn_sqr_diagonal (rp, up, n)
     91  1.1  mrg #else
     92  1.1  mrg #define MPN_SQR_DIAGONAL(rp, up, n)					\
     93  1.1  mrg   do {									\
     94  1.1  mrg     mp_size_t _i;							\
     95  1.1  mrg     for (_i = 0; _i < (n); _i++)					\
     96  1.1  mrg       {									\
     97  1.1  mrg 	mp_limb_t ul, lpl;						\
     98  1.1  mrg 	ul = (up)[_i];							\
     99  1.1  mrg 	umul_ppmm ((rp)[2 * _i + 1], lpl, ul, ul << GMP_NAIL_BITS);	\
    100  1.1  mrg 	(rp)[2 * _i] = lpl >> GMP_NAIL_BITS;				\
    101  1.1  mrg       }									\
    102  1.1  mrg   } while (0)
    103  1.1  mrg #endif
    104  1.1  mrg 
    105  1.1  mrg 
    106  1.1  mrg #if ! HAVE_NATIVE_mpn_sqr_basecase
    107  1.1  mrg /* The limit of the generic code is SQR_TOOM2_THRESHOLD.  */
    108  1.1  mrg #define SQR_BASECASE_LIM  SQR_TOOM2_THRESHOLD
    109  1.1  mrg #endif
    110  1.1  mrg 
    111  1.1  mrg #if HAVE_NATIVE_mpn_sqr_basecase
    112  1.1  mrg #ifdef TUNE_SQR_TOOM2_MAX
    113  1.1  mrg /* We slightly abuse TUNE_SQR_TOOM2_MAX here.  If it is set for an assembly
    114  1.1  mrg    mpn_sqr_basecase, it comes from SQR_TOOM2_THRESHOLD_MAX in the assembly
    115  1.1  mrg    file.  An assembly mpn_sqr_basecase that does not define it should allow
    116  1.1  mrg    any size.  */
    117  1.1  mrg #define SQR_BASECASE_LIM  SQR_TOOM2_THRESHOLD
    118  1.1  mrg #endif
    119  1.1  mrg #endif
    120  1.1  mrg 
    121  1.1  mrg #ifdef WANT_FAT_BINARY
    122  1.1  mrg /* For fat builds, we use SQR_TOOM2_THRESHOLD which will expand to a read from
    123  1.1  mrg    __gmpn_cpuvec.  Perhaps any possible sqr_basecase.asm allow any size, and we
    124  1.1  mrg    limit the use unnecessarily.  We cannot tell, so play it safe.  FIXME.  */
    125  1.1  mrg #define SQR_BASECASE_LIM  SQR_TOOM2_THRESHOLD
    126  1.1  mrg #endif
    127  1.1  mrg 
    128  1.1  mrg #ifndef SQR_BASECASE_LIM
    129  1.1  mrg /* If SQR_BASECASE_LIM is now not defined, use mpn_sqr_basecase for any operand
    130  1.1  mrg    size.  */
    131  1.1  mrg #define mpn_local_sqr(rp,up,n,tp) mpn_sqr_basecase(rp,up,n)
    132  1.1  mrg #else
    133  1.1  mrg /* Else use mpn_sqr_basecase for its allowed sizes, else mpn_mul_basecase.  */
    134  1.1  mrg #define mpn_local_sqr(rp,up,n,tp) \
    135  1.1  mrg   do {									\
    136  1.1  mrg     if (BELOW_THRESHOLD (n, SQR_BASECASE_LIM))				\
    137  1.1  mrg       mpn_sqr_basecase (rp, up, n);					\
    138  1.1  mrg     else								\
    139  1.1  mrg       mpn_mul_basecase(rp, up, n, up, n);				\
    140  1.1  mrg   } while (0)
    141  1.1  mrg #endif
    142  1.1  mrg 
    143  1.1  mrg #define getbit(p,bi) \
    144  1.1  mrg   ((p[(bi - 1) / GMP_NUMB_BITS] >> (bi - 1) % GMP_NUMB_BITS) & 1)
    145  1.1  mrg 
    146  1.1  mrg /* FIXME: Maybe some things would get simpler if all callers ensure
    147  1.1  mrg    that bi >= nbits. As far as I understand, with the current code bi
    148  1.1  mrg    < nbits can happen only for the final iteration. */
    149  1.1  mrg static inline mp_limb_t
    150  1.1  mrg getbits (const mp_limb_t *p, mp_bitcnt_t bi, int nbits)
    151  1.1  mrg {
    152  1.1  mrg   int nbits_in_r;
    153  1.1  mrg   mp_limb_t r;
    154  1.1  mrg   mp_size_t i;
    155  1.1  mrg 
    156  1.1  mrg   if (bi < nbits)
    157  1.1  mrg     {
    158  1.1  mrg       return p[0] & (((mp_limb_t) 1 << bi) - 1);
    159  1.1  mrg     }
    160  1.1  mrg   else
    161  1.1  mrg     {
    162  1.1  mrg       bi -= nbits;			/* bit index of low bit to extract */
    163  1.1  mrg       i = bi / GMP_NUMB_BITS;		/* word index of low bit to extract */
    164  1.1  mrg       bi %= GMP_NUMB_BITS;		/* bit index in low word */
    165  1.1  mrg       r = p[i] >> bi;			/* extract (low) bits */
    166  1.1  mrg       nbits_in_r = GMP_NUMB_BITS - bi;	/* number of bits now in r */
    167  1.1  mrg       if (nbits_in_r < nbits)		/* did we get enough bits? */
    168  1.1  mrg 	r += p[i + 1] << nbits_in_r;	/* prepend bits from higher word */
    169  1.1  mrg       return r & (((mp_limb_t ) 1 << nbits) - 1);
    170  1.1  mrg     }
    171  1.1  mrg }
    172  1.1  mrg 
    173  1.1  mrg #ifndef POWM_SEC_TABLE
    174  1.1  mrg #if GMP_NUMB_BITS < 50
    175  1.1  mrg #define POWM_SEC_TABLE  2,33,96,780,2741
    176  1.1  mrg #else
    177  1.1  mrg #define POWM_SEC_TABLE  2,130,524,2578
    178  1.1  mrg #endif
    179  1.1  mrg #endif
    180  1.1  mrg 
    181  1.1  mrg #if TUNE_PROGRAM_BUILD
    182  1.1  mrg extern int win_size (mp_bitcnt_t);
    183  1.1  mrg #else
    184  1.1  mrg static inline int
    185  1.1  mrg win_size (mp_bitcnt_t enb)
    186  1.1  mrg {
    187  1.1  mrg   int k;
    188  1.1  mrg   /* Find k, such that x[k-1] < enb <= x[k].
    189  1.1  mrg 
    190  1.1  mrg      We require that x[k] >= k, then it follows that enb > x[k-1] >=
    191  1.1  mrg      k-1, which implies k <= enb.
    192  1.1  mrg   */
    193  1.1  mrg   static const mp_bitcnt_t x[] = {0,POWM_SEC_TABLE,~(mp_bitcnt_t)0};
    194  1.1  mrg   for (k = 1; enb > x[k]; k++)
    195  1.1  mrg     ;
    196  1.1  mrg   ASSERT (k <= enb);
    197  1.1  mrg   return k;
    198  1.1  mrg }
    199  1.1  mrg #endif
    200  1.1  mrg 
    201  1.1  mrg /* Convert U to REDC form, U_r = B^n * U mod M.
    202  1.1  mrg    Uses scratch space at tp of size 2un + n + 1.  */
    203  1.1  mrg static void
    204  1.1  mrg redcify (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr mp, mp_size_t n, mp_ptr tp)
    205  1.1  mrg {
    206  1.1  mrg   MPN_ZERO (tp, n);
    207  1.1  mrg   MPN_COPY (tp + n, up, un);
    208  1.1  mrg 
    209  1.1  mrg   mpn_sec_div_r (tp, un + n, mp, n, tp + un + n);
    210  1.1  mrg   MPN_COPY (rp, tp, n);
    211  1.1  mrg }
    212  1.1  mrg 
    213  1.1  mrg /* {rp, n} <-- {bp, bn} ^ {ep, en} mod {mp, n},
    214  1.1  mrg    where en = ceil (enb / GMP_NUMB_BITS)
    215  1.1  mrg    Requires that {mp, n} is odd (and hence also mp[0] odd).
    216  1.1  mrg    Uses scratch space at tp as defined by mpn_sec_powm_itch.  */
    217  1.1  mrg void
    218  1.1  mrg mpn_sec_powm (mp_ptr rp, mp_srcptr bp, mp_size_t bn,
    219  1.1  mrg 	      mp_srcptr ep, mp_bitcnt_t enb,
    220  1.1  mrg 	      mp_srcptr mp, mp_size_t n, mp_ptr tp)
    221  1.1  mrg {
    222  1.1  mrg   mp_limb_t ip[2], *mip;
    223  1.1  mrg   int windowsize, this_windowsize;
    224  1.1  mrg   mp_limb_t expbits;
    225  1.1  mrg   mp_ptr pp, this_pp;
    226  1.1  mrg   long i;
    227  1.1  mrg   int cnd;
    228  1.1  mrg 
    229  1.1  mrg   ASSERT (enb > 0);
    230  1.1  mrg   ASSERT (n > 0);
    231  1.1  mrg   /* The code works for bn = 0, but the defined scratch space is 2 limbs
    232  1.1  mrg      greater than we supply, when converting 1 to redc form .  */
    233  1.1  mrg   ASSERT (bn > 0);
    234  1.1  mrg   ASSERT ((mp[0] & 1) != 0);
    235  1.1  mrg 
    236  1.1  mrg   windowsize = win_size (enb);
    237  1.1  mrg 
    238  1.1  mrg #if WANT_REDC_2
    239  1.1  mrg   if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
    240  1.1  mrg     {
    241  1.1  mrg       mip = ip;
    242  1.1  mrg       binvert_limb (mip[0], mp[0]);
    243  1.1  mrg       mip[0] = -mip[0];
    244  1.1  mrg     }
    245  1.1  mrg   else
    246  1.1  mrg     {
    247  1.1  mrg       mip = ip;
    248  1.1  mrg       mpn_binvert (mip, mp, 2, tp);
    249  1.1  mrg       mip[0] = -mip[0]; mip[1] = ~mip[1];
    250  1.1  mrg     }
    251  1.1  mrg #else
    252  1.1  mrg   mip = ip;
    253  1.1  mrg   binvert_limb (mip[0], mp[0]);
    254  1.1  mrg   mip[0] = -mip[0];
    255  1.1  mrg #endif
    256  1.1  mrg 
    257  1.1  mrg   pp = tp;
    258  1.1  mrg   tp += (n << windowsize);	/* put tp after power table */
    259  1.1  mrg 
    260  1.1  mrg   /* Compute pp[0] table entry */
    261  1.1  mrg   /* scratch: |   n   | 1 |   n+2    |  */
    262  1.1  mrg   /*          | pp[0] | 1 | redcify  |  */
    263  1.1  mrg   this_pp = pp;
    264  1.1  mrg   this_pp[n] = 1;
    265  1.1  mrg   redcify (this_pp, this_pp + n, 1, mp, n, this_pp + n + 1);
    266  1.1  mrg   this_pp += n;
    267  1.1  mrg 
    268  1.1  mrg   /* Compute pp[1] table entry.  To avoid excessive scratch usage in the
    269  1.1  mrg      degenerate situation where B >> M, we let redcify use scratch space which
    270  1.1  mrg      will later be used by the pp table (element 2 and up).  */
    271  1.1  mrg   /* scratch: |   n   |   n   |  bn + n + 1  |  */
    272  1.1  mrg   /*          | pp[0] | pp[1] |   redcify    |  */
    273  1.1  mrg   redcify (this_pp, bp, bn, mp, n, this_pp + n);
    274  1.1  mrg 
    275  1.1  mrg   /* Precompute powers of b and put them in the temporary area at pp.  */
    276  1.1  mrg   /* scratch: |   n   |   n   | ...  |                    |   2n      |  */
    277  1.1  mrg   /*          | pp[0] | pp[1] | ...  | pp[2^windowsize-1] |  product  |  */
    278  1.1  mrg   for (i = (1 << windowsize) - 2; i > 0; i--)
    279  1.1  mrg     {
    280  1.1  mrg       mpn_mul_basecase (tp, this_pp, n, pp + n, n);
    281  1.1  mrg       this_pp += n;
    282  1.1  mrg #if WANT_REDC_2
    283  1.1  mrg       if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
    284  1.1  mrg 	MPN_REDC_1_SEC (this_pp, tp, mp, n, mip[0]);
    285  1.1  mrg       else
    286  1.1  mrg 	MPN_REDC_2_SEC (this_pp, tp, mp, n, mip);
    287  1.1  mrg #else
    288  1.1  mrg       MPN_REDC_1_SEC (this_pp, tp, mp, n, mip[0]);
    289  1.1  mrg #endif
    290  1.1  mrg     }
    291  1.1  mrg 
    292  1.1  mrg   expbits = getbits (ep, enb, windowsize);
    293  1.1  mrg   ASSERT_ALWAYS (enb >= windowsize);
    294  1.1  mrg   enb -= windowsize;
    295  1.1  mrg 
    296  1.1  mrg   mpn_sec_tabselect (rp, pp, n, 1 << windowsize, expbits);
    297  1.1  mrg 
    298  1.1  mrg   /* Main exponentiation loop.  */
    299  1.1  mrg   /* scratch: |   n   |   n   | ...  |                    |     3n-4n     |  */
    300  1.1  mrg   /*          | pp[0] | pp[1] | ...  | pp[2^windowsize-1] |  loop scratch |  */
    301  1.1  mrg 
    302  1.1  mrg #define INNERLOOP							\
    303  1.1  mrg   while (enb != 0)							\
    304  1.1  mrg     {									\
    305  1.1  mrg       expbits = getbits (ep, enb, windowsize);				\
    306  1.1  mrg       this_windowsize = windowsize;					\
    307  1.1  mrg       if (enb < windowsize)						\
    308  1.1  mrg 	{								\
    309  1.1  mrg 	  this_windowsize -= windowsize - enb;				\
    310  1.1  mrg 	  enb = 0;							\
    311  1.1  mrg 	}								\
    312  1.1  mrg       else								\
    313  1.1  mrg 	enb -= windowsize;						\
    314  1.1  mrg 									\
    315  1.1  mrg       do								\
    316  1.1  mrg 	{								\
    317  1.1  mrg 	  mpn_local_sqr (tp, rp, n, tp + 2 * n);			\
    318  1.1  mrg 	  MPN_REDUCE (rp, tp, mp, n, mip);				\
    319  1.1  mrg 	  this_windowsize--;						\
    320  1.1  mrg 	}								\
    321  1.1  mrg       while (this_windowsize != 0);					\
    322  1.1  mrg 									\
    323  1.1  mrg       mpn_sec_tabselect (tp + 2*n, pp, n, 1 << windowsize, expbits);	\
    324  1.1  mrg       mpn_mul_basecase (tp, rp, n, tp + 2*n, n);			\
    325  1.1  mrg 									\
    326  1.1  mrg       MPN_REDUCE (rp, tp, mp, n, mip);					\
    327  1.1  mrg     }
    328  1.1  mrg 
    329  1.1  mrg #if WANT_REDC_2
    330  1.1  mrg   if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
    331  1.1  mrg     {
    332  1.1  mrg #undef MPN_MUL_N
    333  1.1  mrg #undef MPN_SQR
    334  1.1  mrg #undef MPN_REDUCE
    335  1.1  mrg #define MPN_MUL_N(r,a,b,n)		mpn_mul_basecase (r,a,n,b,n)
    336  1.1  mrg #define MPN_SQR(r,a,n)			mpn_sqr_basecase (r,a,n)
    337  1.1  mrg #define MPN_REDUCE(rp,tp,mp,n,mip)	MPN_REDC_1_SEC (rp, tp, mp, n, mip[0])
    338  1.1  mrg       INNERLOOP;
    339  1.1  mrg     }
    340  1.1  mrg   else
    341  1.1  mrg     {
    342  1.1  mrg #undef MPN_MUL_N
    343  1.1  mrg #undef MPN_SQR
    344  1.1  mrg #undef MPN_REDUCE
    345  1.1  mrg #define MPN_MUL_N(r,a,b,n)		mpn_mul_basecase (r,a,n,b,n)
    346  1.1  mrg #define MPN_SQR(r,a,n)			mpn_sqr_basecase (r,a,n)
    347  1.1  mrg #define MPN_REDUCE(rp,tp,mp,n,mip)	MPN_REDC_2_SEC (rp, tp, mp, n, mip)
    348  1.1  mrg       INNERLOOP;
    349  1.1  mrg     }
    350  1.1  mrg #else
    351  1.1  mrg #undef MPN_MUL_N
    352  1.1  mrg #undef MPN_SQR
    353  1.1  mrg #undef MPN_REDUCE
    354  1.1  mrg #define MPN_MUL_N(r,a,b,n)		mpn_mul_basecase (r,a,n,b,n)
    355  1.1  mrg #define MPN_SQR(r,a,n)			mpn_sqr_basecase (r,a,n)
    356  1.1  mrg #define MPN_REDUCE(rp,tp,mp,n,mip)	MPN_REDC_1_SEC (rp, tp, mp, n, mip[0])
    357  1.1  mrg   INNERLOOP;
    358  1.1  mrg #endif
    359  1.1  mrg 
    360  1.1  mrg   MPN_COPY (tp, rp, n);
    361  1.1  mrg   MPN_ZERO (tp + n, n);
    362  1.1  mrg 
    363  1.1  mrg #if WANT_REDC_2
    364  1.1  mrg   if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
    365  1.1  mrg     MPN_REDC_1_SEC (rp, tp, mp, n, mip[0]);
    366  1.1  mrg   else
    367  1.1  mrg     MPN_REDC_2_SEC (rp, tp, mp, n, mip);
    368  1.1  mrg #else
    369  1.1  mrg   MPN_REDC_1_SEC (rp, tp, mp, n, mip[0]);
    370  1.1  mrg #endif
    371  1.1  mrg   cnd = mpn_sub_n (tp, rp, mp, n);	/* we need just retval */
    372  1.1  mrg   mpn_cnd_sub_n (!cnd, rp, rp, mp, n);
    373  1.1  mrg }
    374  1.1  mrg 
    375  1.1  mrg mp_size_t
    376  1.1  mrg mpn_sec_powm_itch (mp_size_t bn, mp_bitcnt_t enb, mp_size_t n)
    377  1.1  mrg {
    378  1.1  mrg   int windowsize;
    379  1.1  mrg   mp_size_t redcify_itch, itch;
    380  1.1  mrg 
    381  1.1  mrg   /* The top scratch usage will either be when reducing B in the 2nd redcify
    382  1.1  mrg      call, or more typically n*2^windowsize + 3n or 4n, in the main loop.  (It
    383  1.1  mrg      is 3n or 4n depending on if we use mpn_local_sqr or a native
    384  1.1  mrg      mpn_sqr_basecase.  We assume 4n always for now.) */
    385  1.1  mrg 
    386  1.1  mrg   windowsize = win_size (enb);
    387  1.1  mrg 
    388  1.1  mrg   /* The 2n term is due to pp[0] and pp[1] at the time of the 2nd redcify call,
    389  1.1  mrg      the (bn + n) term is due to redcify's own usage, and the rest is due to
    390  1.1  mrg      mpn_sec_div_r's usage when called from redcify.  */
    391  1.1  mrg   redcify_itch = (2 * n) + (bn + n) + ((bn + n) + 2 * n + 2);
    392  1.1  mrg 
    393  1.1  mrg   /* The n * 2^windowsize term is due to the power table, the 4n term is due to
    394  1.1  mrg      scratch needs of squaring/multiplication in the exponentiation loop.  */
    395  1.1  mrg   itch = (n << windowsize) + (4 * n);
    396  1.1  mrg 
    397  1.1  mrg   return MAX (itch, redcify_itch);
    398  1.1  mrg }
    399