1 1.1 mrg /* mpn_cnd_add_n -- Compute R = U + V if CND != 0 or R = U if CND == 0. 2 1.1 mrg Both cases should take the same time and perform the exact same memory 3 1.1 mrg accesses, since this function is intended to be used where side-channel 4 1.1 mrg attack resilience is relevant. 5 1.1 mrg 6 1.1 mrg Copyright 1992-1994, 1996, 2000, 2002, 2008, 2009, 2011, 2013 Free Software 7 1.1 mrg Foundation, Inc. 8 1.1 mrg 9 1.1 mrg This file is part of the GNU MP Library. 10 1.1 mrg 11 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify 12 1.1 mrg it under the terms of either: 13 1.1 mrg 14 1.1 mrg * the GNU Lesser General Public License as published by the Free 15 1.1 mrg Software Foundation; either version 3 of the License, or (at your 16 1.1 mrg option) any later version. 17 1.1 mrg 18 1.1 mrg or 19 1.1 mrg 20 1.1 mrg * the GNU General Public License as published by the Free Software 21 1.1 mrg Foundation; either version 2 of the License, or (at your option) any 22 1.1 mrg later version. 23 1.1 mrg 24 1.1 mrg or both in parallel, as here. 25 1.1 mrg 26 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but 27 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 28 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29 1.1 mrg for more details. 30 1.1 mrg 31 1.1 mrg You should have received copies of the GNU General Public License and the 32 1.1 mrg GNU Lesser General Public License along with the GNU MP Library. If not, 33 1.1 mrg see https://www.gnu.org/licenses/. */ 34 1.1 mrg 35 1.1 mrg #include "gmp-impl.h" 36 1.1 mrg 37 1.1 mrg mp_limb_t 38 1.1 mrg mpn_cnd_add_n (mp_limb_t cnd, mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n) 39 1.1 mrg { 40 1.1 mrg mp_limb_t ul, vl, sl, rl, cy, cy1, cy2, mask; 41 1.1 mrg 42 1.1 mrg ASSERT (n >= 1); 43 1.1 mrg ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n)); 44 1.1 mrg ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n)); 45 1.1 mrg 46 1.1 mrg mask = -(mp_limb_t) (cnd != 0); 47 1.1 mrg cy = 0; 48 1.1 mrg do 49 1.1 mrg { 50 1.1 mrg ul = *up++; 51 1.1 mrg vl = *vp++ & mask; 52 1.1 mrg #if GMP_NAIL_BITS == 0 53 1.1 mrg sl = ul + vl; 54 1.1 mrg cy1 = sl < ul; 55 1.1 mrg rl = sl + cy; 56 1.1 mrg cy2 = rl < sl; 57 1.1 mrg cy = cy1 | cy2; 58 1.1 mrg *rp++ = rl; 59 1.1 mrg #else 60 1.1 mrg rl = ul + vl; 61 1.1 mrg rl += cy; 62 1.1 mrg cy = rl >> GMP_NUMB_BITS; 63 1.1 mrg *rp++ = rl & GMP_NUMB_MASK; 64 1.1 mrg #endif 65 1.1 mrg } 66 1.1 mrg while (--n != 0); 67 1.1 mrg 68 1.1 mrg return cy; 69 1.1 mrg } 70