/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 <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 | 25.0M | { |
47 | 25.0M | mp_size_t k, i; |
48 | 25.0M | mp_limb_t mask; |
49 | 25.0M | volatile const mp_limb_t *tp; |
50 | | |
51 | 25.0M | tp = tab; |
52 | | |
53 | | /* Place first entry into result area. */ |
54 | 469M | for (i = 0; i < n; i++) |
55 | 444M | rp[i] = tp[i]; |
56 | | |
57 | | /* Conditionally replace entry in result area by entry 1...(nents-1) using |
58 | | masking trickery. */ |
59 | 719M | for (k = 1; k < nents; k++) |
60 | 694M | { |
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 | 694M | mask = -(mp_limb_t) ((-(unsigned long) (which ^ k)) >> (BITS_PER_ULONG - 1)); |
65 | 694M | tp += n; |
66 | 10.2G | for (i = 0; i < n; i++) |
67 | 9.54G | rp[i] = (rp[i] & mask) | (tp[i] & ~mask); |
68 | 694M | } |
69 | 25.0M | } |
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 |