/src/gmp/mpn/sec_tabselect.c
Line | Count | Source |
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 "gmp-impl.h" |
32 | | |
33 | | #ifndef SEC_TABSELECT_METHOD |
34 | | #define SEC_TABSELECT_METHOD 1 |
35 | | #endif |
36 | | |
37 | | /* Select entry `which' from table `tab', which has nents entries, each `n' |
38 | | limbs. Store the selected entry at rp. Reads entire table to avoid |
39 | | side-channel information leaks. O(n*nents). */ |
40 | | |
41 | | #if SEC_TABSELECT_METHOD == 1 |
42 | | void |
43 | | mpn_sec_tabselect (volatile mp_limb_t *rp, volatile const mp_limb_t *tab, |
44 | | mp_size_t n, mp_size_t nents, mp_size_t which) |
45 | 5.07M | { |
46 | 5.07M | mp_size_t k, i; |
47 | 5.07M | mp_limb_t mask; |
48 | 5.07M | volatile const mp_limb_t *tp; |
49 | | |
50 | 5.07M | tp = tab; |
51 | | |
52 | | /* Place first entry into result area. */ |
53 | 79.0M | for (i = 0; i < n; i++) |
54 | 74.0M | rp[i] = tp[i]; |
55 | | |
56 | | /* Conditionally replace entry in result area by entry 1...(nents-1) using |
57 | | masking trickery. */ |
58 | 150M | for (k = 1; k < nents; k++) |
59 | 145M | { |
60 | | /* Generate a mask using an expression which all compilers should compile |
61 | | into branch-free code. The convoluted expression is designed to both |
62 | | allow mp_limb_t greater and mp_limb_t smaller than mp_size_t. */ |
63 | 145M | mask = -(mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)); |
64 | 145M | tp += n; |
65 | 1.97G | for (i = 0; i < n; i++) |
66 | 1.82G | rp[i] = (rp[i] & mask) | (tp[i] & ~mask); |
67 | 145M | } |
68 | 5.07M | } |
69 | | #endif |
70 | | |
71 | | #if SEC_TABSELECT_METHOD == 2 |
72 | | void |
73 | | mpn_sec_tabselect (volatile mp_limb_t * restrict rp, |
74 | | volatile const mp_limb_t * restrict tab, |
75 | | mp_size_t n, mp_size_t nents, mp_size_t which) |
76 | | { |
77 | | mp_size_t k, i; |
78 | | mp_limb_t mask, r0, r1, r2, r3; |
79 | | volatile const mp_limb_t * restrict tp; |
80 | | |
81 | | if (n & 1) |
82 | | { |
83 | | tp = tab; |
84 | | r0 = 0; |
85 | | for (k = 0; k < nents; k++) |
86 | | { |
87 | | mask = (mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)) - 1; |
88 | | r0 += tp[0] & mask; |
89 | | tp += n; |
90 | | } |
91 | | rp[0] = r0; |
92 | | rp += 1; |
93 | | tab += 1; |
94 | | } |
95 | | |
96 | | if (n & 2) |
97 | | { |
98 | | tp = tab; |
99 | | r0 = r1 = 0; |
100 | | for (k = 0; k < nents; k++) |
101 | | { |
102 | | mask = (mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)) - 1; |
103 | | r0 += tp[0] & mask; |
104 | | r1 += tp[1] & mask; |
105 | | tp += n; |
106 | | } |
107 | | rp[0] = r0; |
108 | | rp[1] = r1; |
109 | | rp += 2; |
110 | | tab += 2; |
111 | | } |
112 | | |
113 | | for (i = 0; i <= n - 4; i += 4) |
114 | | { |
115 | | tp = tab + i; |
116 | | r0 = r1 = r2 = r3 = 0; |
117 | | for (k = 0; k < nents; k++) |
118 | | { |
119 | | mask = (mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)) - 1; |
120 | | r0 += tp[0] & mask; |
121 | | r1 += tp[1] & mask; |
122 | | r2 += tp[2] & mask; |
123 | | r3 += tp[3] & mask; |
124 | | tp += n; |
125 | | } |
126 | | rp[0] = r0; |
127 | | rp[1] = r1; |
128 | | rp[2] = r2; |
129 | | rp[3] = r3; |
130 | | rp += 4; |
131 | | } |
132 | | } |
133 | | #endif |