Coverage Report

Created: 2024-11-25 06:30

/src/nettle/ecc-mod-arith.c
Line
Count
Source (jump to first uncovered line)
1
/* ecc-mod-arith.c
2
3
   Copyright (C) 2013, 2014 Niels Möller
4
5
   This file is part of GNU Nettle.
6
7
   GNU Nettle is free software: you can redistribute it and/or
8
   modify 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
17
       Software Foundation; either version 2 of the License, or (at your
18
       option) any later version.
19
20
   or both in parallel, as here.
21
22
   GNU Nettle is distributed in the hope that it will be useful,
23
   but WITHOUT ANY WARRANTY; without even the implied warranty of
24
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25
   General Public License for more details.
26
27
   You should have received copies of the GNU General Public License and
28
   the GNU Lesser General Public License along with this program.  If
29
   not, see http://www.gnu.org/licenses/.
30
*/
31
32
/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
33
34
#if HAVE_CONFIG_H
35
# include "config.h"
36
#endif
37
38
#include <assert.h>
39
40
#include "ecc-internal.h"
41
42
/* Routines for modp arithmetic. All values are ecc->size limbs, but
43
   not necessarily < p. */
44
45
int
46
ecc_mod_zero_p (const struct ecc_modulo *m, const mp_limb_t *xp_in)
47
3.39k
{
48
3.39k
  volatile mp_limb_t is_non_zero, is_not_p;
49
3.39k
  const volatile mp_limb_t *xp;
50
3.39k
  mp_size_t i;
51
52
16.9k
  for (xp = xp_in, i = 0, is_non_zero = is_not_p = 0; i < m->size; i++)
53
13.5k
    {
54
13.5k
      is_non_zero |= xp[i];
55
13.5k
      is_not_p |= (xp[i] ^ m->m[i]);
56
13.5k
    }
57
58
3.39k
  return is_zero_limb (is_non_zero) | is_zero_limb (is_not_p);
59
3.39k
}
60
61
int
62
ecc_mod_equal_p (const struct ecc_modulo *m, const mp_limb_t *a,
63
     const mp_limb_t *ref, mp_limb_t *scratch)
64
0
{
65
0
  mp_limb_t cy;
66
0
  cy = mpn_sub_n (scratch, a, ref, m->size);
67
  /* If cy > 0, i.e., a < ref, then they can't be equal mod m. */
68
0
  return (1 - cy) & ecc_mod_zero_p (m, scratch);
69
0
}
70
71
void
72
ecc_mod_add (const struct ecc_modulo *m, mp_limb_t *rp,
73
       const mp_limb_t *ap, const mp_limb_t *bp)
74
7.05M
{
75
7.05M
  mp_limb_t cy;
76
7.05M
  cy = mpn_add_n (rp, ap, bp, m->size);
77
7.05M
  cy = mpn_cnd_add_n (cy, rp, rp, m->B, m->size);
78
7.05M
  cy = mpn_cnd_add_n (cy, rp, rp, m->B, m->size);
79
7.05M
  assert_maybe (cy == 0);
80
7.05M
}
81
82
void
83
ecc_mod_sub (const struct ecc_modulo *m, mp_limb_t *rp,
84
       const mp_limb_t *ap, const mp_limb_t *bp)
85
11.2M
{
86
11.2M
  mp_limb_t cy;
87
11.2M
  cy = mpn_sub_n (rp, ap, bp, m->size);
88
  /* The adjustments for this function work differently depending on
89
     the value of the most significant bit of m.
90
91
     If m has a most significant bit of zero, then the first
92
     adjustment step conditionally adds 2m. If in addition, inputs are
93
     in the 0 <= a,b < 2m range, then the first adjustment guarantees
94
     that result is in that same range. The second adjustment step is
95
     needed only if b > 2m, it then ensures output is correct modulo
96
     m, but nothing more.
97
98
     If m has a most significant bit of one, Bm2m and B are the same,
99
     and this function works analogously to ecc_mod_add.
100
   */
101
11.2M
  cy = mpn_cnd_sub_n (cy, rp, rp, m->Bm2m, m->size);
102
11.2M
  cy = mpn_cnd_sub_n (cy, rp, rp, m->B, m->size);
103
11.2M
  assert_maybe (cy == 0);
104
11.2M
}
105
106
void
107
ecc_mod_mul_1 (const struct ecc_modulo *m, mp_limb_t *rp,
108
         const mp_limb_t *ap, mp_limb_t b)
109
2.26M
{
110
2.26M
  mp_limb_t hi;
111
112
2.26M
  assert (b <= 0xffffffff);
113
2.26M
  hi = mpn_mul_1 (rp, ap, m->size, b);
114
2.26M
  hi = mpn_addmul_1 (rp, m->B, m->size, hi);
115
2.26M
  assert_maybe (hi <= 1);
116
2.26M
  hi = mpn_cnd_add_n (hi, rp, rp, m->B, m->size);
117
  /* Sufficient if b < B^size / p */
118
2.26M
  assert_maybe (hi == 0);
119
2.26M
}
120
121
void
122
ecc_mod_addmul_1 (const struct ecc_modulo *m, mp_limb_t *rp,
123
      const mp_limb_t *ap, mp_limb_t b)
124
12.9k
{
125
12.9k
  mp_limb_t hi;
126
127
12.9k
  assert (b <= 0xffffffff);
128
12.9k
  hi = mpn_addmul_1 (rp, ap, m->size, b);
129
12.9k
  hi = mpn_addmul_1 (rp, m->B, m->size, hi);
130
12.9k
  assert_maybe (hi <= 1);
131
12.9k
  hi = mpn_cnd_add_n (hi, rp, rp, m->B, m->size);
132
  /* Sufficient roughly if b < B^size / p */
133
12.9k
  assert_maybe (hi == 0);
134
12.9k
}
135
  
136
void
137
ecc_mod_submul_1 (const struct ecc_modulo *m, mp_limb_t *rp,
138
      const mp_limb_t *ap, mp_limb_t b)
139
3.04M
{
140
3.04M
  mp_limb_t hi;
141
142
3.04M
  assert (b <= 0xffffffff);
143
3.04M
  hi = mpn_submul_1 (rp, ap, m->size, b);
144
3.04M
  hi = mpn_submul_1 (rp, m->B, m->size, hi);
145
3.04M
  assert_maybe (hi <= 1);
146
3.04M
  hi = mpn_cnd_sub_n (hi, rp, rp, m->B, m->size);
147
  /* Sufficient roughly if b < B^size / p */
148
3.04M
  assert_maybe (hi == 0);
149
3.04M
}
150
151
void
152
ecc_mod_mul (const struct ecc_modulo *m, mp_limb_t *rp,
153
       const mp_limb_t *ap, const mp_limb_t *bp, mp_limb_t *tp)
154
17.1M
{
155
17.1M
  mpn_mul_n (tp, ap, bp, m->size);
156
17.1M
  m->reduce (m, rp, tp);
157
17.1M
}
158
159
void
160
ecc_mod_sqr (const struct ecc_modulo *m, mp_limb_t *rp,
161
       const mp_limb_t *ap, mp_limb_t *tp)
162
16.1M
{
163
16.1M
  mpn_sqr (tp, ap, m->size);
164
16.1M
  m->reduce (m, rp, tp);
165
16.1M
}
166
167
void
168
ecc_mod_mul_canonical (const struct ecc_modulo *m, mp_limb_t *rp,
169
           const mp_limb_t *ap, const mp_limb_t *bp, mp_limb_t *tp)
170
44.9k
{
171
44.9k
  mp_limb_t cy;
172
44.9k
  mpn_mul_n (tp, ap, bp, m->size);
173
44.9k
  m->reduce (m, tp + m->size, tp);
174
175
44.9k
  cy = mpn_sub_n (rp, tp + m->size, m->m, m->size);
176
44.9k
  cnd_copy (cy, rp, tp + m->size, m->size);
177
44.9k
}
178
179
void
180
ecc_mod_sqr_canonical (const struct ecc_modulo *m, mp_limb_t *rp,
181
           const mp_limb_t *ap, mp_limb_t *tp)
182
17
{
183
17
  mp_limb_t cy;
184
17
  mpn_sqr (tp, ap, m->size);
185
17
  m->reduce (m, tp + m->size, tp);
186
187
17
  cy = mpn_sub_n (rp, tp + m->size, m->m, m->size);
188
17
  cnd_copy (cy, rp, tp + m->size, m->size);
189
17
}
190
191
void
192
ecc_mod_pow_2k (const struct ecc_modulo *m,
193
    mp_limb_t *rp, const mp_limb_t *xp,
194
    unsigned k, mp_limb_t *tp)
195
174k
{
196
174k
  ecc_mod_sqr (m, rp, xp, tp);
197
6.49M
  while (--k > 0)
198
6.32M
    ecc_mod_sqr (m, rp, rp, tp);
199
174k
}
200
201
void
202
ecc_mod_pow_2k_mul (const struct ecc_modulo *m,
203
        mp_limb_t *rp, const mp_limb_t *xp,
204
        unsigned k, const mp_limb_t *yp,
205
        mp_limb_t *tp)
206
146k
{
207
146k
  ecc_mod_pow_2k (m, rp, xp, k, tp);
208
146k
  ecc_mod_mul (m, rp, rp, yp, tp);
209
146k
}