(root)/
gmp-6.3.0/
mpn/
generic/
sec_tabselect.c
       1  /* mpn_sec_tabselect.
       2  
       3  Copyright 2007-2009, 2011, 2013, 2021 Free Software Foundation, Inc.
       4  
       5  This file is part of the GNU MP Library.
       6  
       7  The GNU MP Library is free software; you can redistribute it and/or modify
       8  it under the terms of either:
       9  
      10    * the GNU Lesser General Public License as published by the Free
      11      Software Foundation; either version 3 of the License, or (at your
      12      option) any later version.
      13  
      14  or
      15  
      16    * the GNU General Public License as published by the Free Software
      17      Foundation; either version 2 of the License, or (at your option) any
      18      later version.
      19  
      20  or both in parallel, as here.
      21  
      22  The GNU MP Library is distributed in the hope that it will be useful, but
      23  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      24  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      25  for more details.
      26  
      27  You should have received copies of the GNU General Public License and the
      28  GNU Lesser General Public License along with the GNU MP Library.  If not,
      29  see https://www.gnu.org/licenses/.  */
      30  
      31  #include <stdio.h>
      32  #include "gmp-impl.h"
      33  
      34  #ifndef SEC_TABSELECT_METHOD
      35  #define SEC_TABSELECT_METHOD 1
      36  #endif
      37  
      38  /* Select entry `which' from table `tab', which has nents entries, each `n'
      39     limbs.  Store the selected entry at rp.  Reads entire table to avoid
      40     side-channel information leaks.  O(n*nents).  */
      41  
      42  #if SEC_TABSELECT_METHOD == 1
      43  void
      44  mpn_sec_tabselect (volatile mp_limb_t *rp, volatile const mp_limb_t *tab,
      45  		   mp_size_t n, mp_size_t nents, mp_size_t which)
      46  {
      47    mp_size_t k, i;
      48    mp_limb_t mask;
      49    volatile const mp_limb_t *tp;
      50  
      51    tp = tab;
      52  
      53    /* Place first entry into result area. */
      54    for (i = 0; i < n; i++)
      55      rp[i] = tp[i];
      56  
      57    /* Conditionally replace entry in result area by entry 1...(nents-1) using
      58       masking trickery. */
      59    for (k = 1; k < nents; k++)
      60      {
      61        /* Generate a mask using an expression which all compilers should compile
      62  	 into branch-free code.  The convoluted expression is designed to both
      63  	 allow mp_limb_t greater and mp_limb_t smaller than mp_size_t. */
      64        mask = -(mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1));
      65        tp += n;
      66        for (i = 0; i < n; i++)
      67  	rp[i] = (rp[i] & mask) | (tp[i] & ~mask);
      68      }
      69  }
      70  #endif
      71  
      72  #if SEC_TABSELECT_METHOD == 2
      73  void
      74  mpn_sec_tabselect (volatile mp_limb_t * restrict rp,
      75  		   volatile const mp_limb_t * restrict tab,
      76  		   mp_size_t n, mp_size_t nents, mp_size_t which)
      77  {
      78    mp_size_t k, i;
      79    mp_limb_t mask, r0, r1, r2, r3;
      80    volatile const mp_limb_t * restrict tp;
      81  
      82    if (n & 1)
      83      {
      84        tp = tab;
      85        r0 = 0;
      86        for (k = 0; k < nents; k++)
      87  	{
      88  	  mask = (mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)) - 1;
      89  	  r0 += tp[0] & mask;
      90  	  tp += n;
      91  	}
      92        rp[0] = r0;
      93        rp += 1;
      94        tab += 1;
      95      }
      96  
      97    if (n & 2)
      98      {
      99        tp = tab;
     100        r0 = r1 = 0;
     101        for (k = 0; k < nents; k++)
     102  	{
     103  	  mask = (mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)) - 1;
     104  	  r0 += tp[0] & mask;
     105  	  r1 += tp[1] & mask;
     106  	  tp += n;
     107  	}
     108        rp[0] = r0;
     109        rp[1] = r1;
     110        rp += 2;
     111        tab += 2;
     112      }
     113  
     114    for (i = 0; i <= n - 4; i += 4)
     115      {
     116        tp = tab + i;
     117        r0 = r1 = r2 = r3 = 0;
     118        for (k = 0; k < nents; k++)
     119  	{
     120  	  mask = (mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)) - 1;
     121  	  r0 += tp[0] & mask;
     122  	  r1 += tp[1] & mask;
     123  	  r2 += tp[2] & mask;
     124  	  r3 += tp[3] & mask;
     125  	  tp += n;
     126  	}
     127        rp[0] = r0;
     128        rp[1] = r1;
     129        rp[2] = r2;
     130        rp[3] = r3;
     131        rp += 4;
     132      }
     133  }
     134  #endif