Skip to content

Commit 9c16579

Browse files
committed
Fix for EdDSA verification infinite loop
Resolves: #1599 Signed-off-by: Alexander Scheel <[email protected]>
1 parent 6dc716d commit 9c16579

File tree

3 files changed

+164
-54
lines changed

3 files changed

+164
-54
lines changed

core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar25519.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)
306306
int[] Nu = new int[16]; System.arraycopy(LSq, 0, Nu, 0, 16);
307307
int[] Nv = new int[16]; Nat256.square(k, Nv); ++Nv[0];
308308
int[] p = new int[16]; Nat256.mul(L, k, p);
309+
int[] t = new int[16]; // temp array
309310
int[] u0 = new int[4]; System.arraycopy(L, 0, u0, 0, 4);
310311
int[] u1 = new int[4];
311312
int[] v0 = new int[4]; System.arraycopy(k, 0, v0, 0, 4);
@@ -322,12 +323,12 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)
322323

323324
if (p[last] < 0)
324325
{
325-
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p);
326+
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p, t);
326327
ScalarUtil.addShifted_UV(3, s, u0, u1, v0, v1);
327328
}
328329
else
329330
{
330-
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p);
331+
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p, t);
331332
ScalarUtil.subShifted_UV(3, s, u0, u1, v0, v1);
332333
}
333334

core/src/main/java/org/bouncycastle/math/ec/rfc8032/Scalar448.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)
571571
int[] Nu = new int[28]; System.arraycopy(LSq, 0, Nu, 0, 28);
572572
int[] Nv = new int[28]; Nat448.square(k, Nv); ++Nv[0];
573573
int[] p = new int[28]; Nat448.mul(L, k, p);
574+
int[] t = new int[28]; // temp array
574575
int[] u0 = new int[8]; System.arraycopy(L, 0, u0, 0, 8);
575576
int[] u1 = new int[8];
576577
int[] v0 = new int[8]; System.arraycopy(k, 0, v0, 0, 8);
@@ -587,12 +588,12 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)
587588

588589
if (p[last] < 0)
589590
{
590-
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p);
591+
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p, t);
591592
ScalarUtil.addShifted_UV(7, s, u0, u1, v0, v1);
592593
}
593594
else
594595
{
595-
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p);
596+
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p, t);
596597
ScalarUtil.subShifted_UV(7, s, u0, u1, v0, v1);
597598
}
598599

core/src/main/java/org/bouncycastle/math/ec/rfc8032/ScalarUtil.java

Lines changed: 158 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,111 @@ abstract class ScalarUtil
66
{
77
private static final long M = 0xFFFFFFFFL;
88

9-
static void addShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] _p)
9+
static void addShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] p, int[] t)
1010
{
11-
int sWords = s >>> 5, sBits = s & 31;
12-
13-
long cc__p = 0L;
11+
long cc_p = 0L;
1412
long cc_Nu = 0L;
1513

16-
if (sBits == 0)
14+
if (s == 0)
1715
{
18-
for (int i = sWords; i <= last; ++i)
16+
for (int i = 0; i <= last; ++i)
1917
{
18+
int p_i = p[i];
19+
2020
cc_Nu += Nu[i] & M;
21-
cc_Nu += _p[i - sWords] & M;
21+
cc_Nu += p_i & M;
2222

23-
cc__p += _p[i] & M;
24-
cc__p += Nv[i - sWords] & M;
25-
_p[i] = (int)cc__p; cc__p >>>= 32;
23+
cc_p += p_i & M;
24+
cc_p += Nv[i] & M;
25+
p_i = (int)cc_p; cc_p >>= 32;
26+
p[i] = p_i;
2627

27-
cc_Nu += _p[i - sWords] & M;
28-
Nu[i] = (int)cc_Nu; cc_Nu >>>= 32;
28+
cc_Nu += p_i & M;
29+
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
2930
}
3031
}
31-
else
32+
else if (s < 32)
3233
{
3334
int prev_p = 0;
3435
int prev_q = 0;
3536
int prev_v = 0;
3637

37-
for (int i = sWords; i <= last; ++i)
38+
for (int i = 0; i <= last; ++i)
3839
{
39-
int next_p = _p[i - sWords];
40-
int p_s = (next_p << sBits) | (prev_p >>> -sBits);
41-
prev_p = next_p;
40+
int p_i = p[i];
41+
int p_s = (p_i << s) | (prev_p >>> -s);
42+
prev_p = p_i;
4243

4344
cc_Nu += Nu[i] & M;
4445
cc_Nu += p_s & M;
4546

46-
int next_v = Nv[i - sWords];
47-
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
47+
int next_v = Nv[i];
48+
int v_s = (next_v << s) | (prev_v >>> -s);
4849
prev_v = next_v;
4950

50-
cc__p += _p[i] & M;
51-
cc__p += v_s & M;
52-
_p[i] = (int)cc__p; cc__p >>>= 32;
51+
cc_p += p_i & M;
52+
cc_p += v_s & M;
53+
p_i = (int)cc_p; cc_p >>= 32;
54+
p[i] = p_i;
5355

54-
int next_q = _p[i - sWords];
55-
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
56-
prev_q = next_q;
56+
int q_s = (p_i << s) | (prev_q >>> -s);
57+
prev_q =p_i;
5758

5859
cc_Nu += q_s & M;
59-
Nu[i] = (int)cc_Nu; cc_Nu >>>= 32;
60+
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
61+
}
62+
}
63+
else
64+
{
65+
// Keep the original value of p in t.
66+
System.arraycopy(p, 0, t, 0, p.length);
67+
68+
int sWords = s >>> 5; int sBits = s & 31;
69+
if (sBits == 0)
70+
{
71+
for (int i = sWords; i <= last; ++i)
72+
{
73+
cc_Nu += Nu[i] & M;
74+
cc_Nu += t[i - sWords] & M;
75+
76+
cc_p += p[i] & M;
77+
cc_p += Nv[i - sWords] & M;
78+
p[i] = (int)cc_p; cc_p >>= 32;
79+
80+
cc_Nu += p[i - sWords] & M;
81+
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
82+
}
83+
}
84+
else
85+
{
86+
int prev_t = 0;
87+
int prev_q = 0;
88+
int prev_v = 0;
89+
90+
for (int i = sWords; i <= last; ++i)
91+
{
92+
int next_t = t[i - sWords];
93+
int t_s = (next_t << sBits) | (prev_t >>> -sBits);
94+
prev_t = next_t;
95+
96+
cc_Nu += Nu[i] & M;
97+
cc_Nu += t_s & M;
98+
99+
int next_v = Nv[i - sWords];
100+
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
101+
prev_v = next_v;
102+
103+
cc_p += p[i] & M;
104+
cc_p += v_s & M;
105+
p[i] = (int)cc_p; cc_p >>= 32;
106+
107+
int next_q = p[i - sWords];
108+
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
109+
prev_q = next_q;
110+
111+
cc_Nu += q_s & M;
112+
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
113+
}
60114
}
61115
}
62116
}
@@ -141,59 +195,113 @@ static boolean lessThan(int last, int[] x, int[] y)
141195
return false;
142196
}
143197

144-
static void subShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] _p)
198+
static void subShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] p, int[] t)
145199
{
146-
int sWords = s >>> 5, sBits = s & 31;
147-
148-
long cc__p = 0L;
200+
long cc_p = 0L;
149201
long cc_Nu = 0L;
150202

151-
if (sBits == 0)
203+
if (s == 0)
152204
{
153-
for (int i = sWords; i <= last; ++i)
205+
for (int i = 0; i <= last; ++i)
154206
{
207+
int p_i = p[i];
208+
155209
cc_Nu += Nu[i] & M;
156-
cc_Nu -= _p[i - sWords] & M;
210+
cc_Nu -= p_i & M;
157211

158-
cc__p += _p[i] & M;
159-
cc__p -= Nv[i - sWords] & M;
160-
_p[i] = (int)cc__p; cc__p >>= 32;
212+
cc_p += p_i & M;
213+
cc_p -= Nv[i] & M;
214+
p_i = (int)cc_p; cc_p >>= 32;
215+
p[i] = p_i;
161216

162-
cc_Nu -= _p[i - sWords] & M;
217+
cc_Nu -= p_i & M;
163218
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
164219
}
165220
}
166-
else
221+
else if (s < 32)
167222
{
168223
int prev_p = 0;
169224
int prev_q = 0;
170225
int prev_v = 0;
171226

172-
for (int i = sWords; i <= last; ++i)
227+
for (int i = 0; i <= last; ++i)
173228
{
174-
int next_p = _p[i - sWords];
175-
int p_s = (next_p << sBits) | (prev_p >>> -sBits);
176-
prev_p = next_p;
229+
int p_i = p[i];
230+
int p_s = (p_i << s) | (prev_p >>> -s);
231+
prev_p = p_i;
177232

178233
cc_Nu += Nu[i] & M;
179234
cc_Nu -= p_s & M;
180235

181-
int next_v = Nv[i - sWords];
182-
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
236+
int next_v = Nv[i];
237+
int v_s = (next_v << s) | (prev_v >>> -s);
183238
prev_v = next_v;
184239

185-
cc__p += _p[i] & M;
186-
cc__p -= v_s & M;
187-
_p[i] = (int)cc__p; cc__p >>= 32;
240+
cc_p += p_i & M;
241+
cc_p -= v_s & M;
242+
p_i = (int)cc_p; cc_p >>= 32;
243+
p[i] = p_i;
188244

189-
int next_q = _p[i - sWords];
190-
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
191-
prev_q = next_q;
245+
int q_s = (p_i << s) | (prev_q >>> -s);
246+
prev_q = p_i;
192247

193248
cc_Nu -= q_s & M;
194249
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
195250
}
196251
}
252+
else
253+
{
254+
// Keep the original value of p in t.
255+
System.arraycopy(p, 0, t, 0, p.length);
256+
257+
int sWords = s >>> 5; int sBits = s & 31;
258+
if (sBits == 0)
259+
{
260+
for (int i = sWords; i <= last; ++i)
261+
{
262+
cc_Nu += Nu[i] & M;
263+
cc_Nu -= t[i - sWords] & M;
264+
265+
cc_p += p[i] & M;
266+
cc_p -= Nv[i - sWords] & M;
267+
p[i] = (int)cc_p; cc_p >>= 32;
268+
269+
cc_Nu -= p[i - sWords] & M;
270+
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
271+
}
272+
}
273+
else
274+
{
275+
int prev_t = 0;
276+
int prev_q = 0;
277+
int prev_v = 0;
278+
279+
for (int i = sWords; i <= last; ++i)
280+
{
281+
int next_t = t[i - sWords];
282+
int t_s = (next_t << sBits) | (prev_t >>> -sBits);
283+
prev_t = next_t;
284+
285+
cc_Nu += Nu[i] & M;
286+
cc_Nu -= t_s & M;
287+
288+
int next_v = Nv[i - sWords];
289+
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
290+
prev_v = next_v;
291+
292+
cc_p += p[i] & M;
293+
cc_p -= v_s & M;
294+
p[i] = (int)cc_p; cc_p >>= 32;
295+
296+
int next_q = p[i - sWords];
297+
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
298+
prev_q = next_q;
299+
300+
cc_Nu -= q_s & M;
301+
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
302+
}
303+
}
304+
}
197305
}
198306

199307
static void subShifted_UV(int last, int s, int[] u0, int[] u1, int[] v0, int[] v1)

0 commit comments

Comments
 (0)