Skip to content

Commit

Permalink
Fix for EdDSA verification infinite loop
Browse files Browse the repository at this point in the history
Resolves: #1599

Signed-off-by: Alexander Scheel <alexander.scheel@keyfactor.com>
  • Loading branch information
cipherboy committed Mar 13, 2024
1 parent 6dc716d commit 9c16579
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 54 deletions.
Expand Up @@ -306,6 +306,7 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)
int[] Nu = new int[16]; System.arraycopy(LSq, 0, Nu, 0, 16);
int[] Nv = new int[16]; Nat256.square(k, Nv); ++Nv[0];
int[] p = new int[16]; Nat256.mul(L, k, p);
int[] t = new int[16]; // temp array
int[] u0 = new int[4]; System.arraycopy(L, 0, u0, 0, 4);
int[] u1 = new int[4];
int[] v0 = new int[4]; System.arraycopy(k, 0, v0, 0, 4);
Expand All @@ -322,12 +323,12 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)

if (p[last] < 0)
{
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p);
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p, t);
ScalarUtil.addShifted_UV(3, s, u0, u1, v0, v1);
}
else
{
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p);
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p, t);
ScalarUtil.subShifted_UV(3, s, u0, u1, v0, v1);
}

Expand Down
Expand Up @@ -571,6 +571,7 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)
int[] Nu = new int[28]; System.arraycopy(LSq, 0, Nu, 0, 28);
int[] Nv = new int[28]; Nat448.square(k, Nv); ++Nv[0];
int[] p = new int[28]; Nat448.mul(L, k, p);
int[] t = new int[28]; // temp array
int[] u0 = new int[8]; System.arraycopy(L, 0, u0, 0, 8);
int[] u1 = new int[8];
int[] v0 = new int[8]; System.arraycopy(k, 0, v0, 0, 8);
Expand All @@ -587,12 +588,12 @@ static void reduceBasisVar(int[] k, int[] z0, int[] z1)

if (p[last] < 0)
{
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p);
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p, t);
ScalarUtil.addShifted_UV(7, s, u0, u1, v0, v1);
}
else
{
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p);
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p, t);
ScalarUtil.subShifted_UV(7, s, u0, u1, v0, v1);
}

Expand Down
208 changes: 158 additions & 50 deletions core/src/main/java/org/bouncycastle/math/ec/rfc8032/ScalarUtil.java
Expand Up @@ -6,57 +6,111 @@ abstract class ScalarUtil
{
private static final long M = 0xFFFFFFFFL;

static void addShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] _p)
static void addShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] p, int[] t)
{
int sWords = s >>> 5, sBits = s & 31;

long cc__p = 0L;
long cc_p = 0L;
long cc_Nu = 0L;

if (sBits == 0)
if (s == 0)
{
for (int i = sWords; i <= last; ++i)
for (int i = 0; i <= last; ++i)
{
int p_i = p[i];

cc_Nu += Nu[i] & M;
cc_Nu += _p[i - sWords] & M;
cc_Nu += p_i & M;

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

cc_Nu += _p[i - sWords] & M;
Nu[i] = (int)cc_Nu; cc_Nu >>>= 32;
cc_Nu += p_i & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
else
else if (s < 32)
{
int prev_p = 0;
int prev_q = 0;
int prev_v = 0;

for (int i = sWords; i <= last; ++i)
for (int i = 0; i <= last; ++i)
{
int next_p = _p[i - sWords];
int p_s = (next_p << sBits) | (prev_p >>> -sBits);
prev_p = next_p;
int p_i = p[i];
int p_s = (p_i << s) | (prev_p >>> -s);
prev_p = p_i;

cc_Nu += Nu[i] & M;
cc_Nu += p_s & M;

int next_v = Nv[i - sWords];
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
int next_v = Nv[i];
int v_s = (next_v << s) | (prev_v >>> -s);
prev_v = next_v;

cc__p += _p[i] & M;
cc__p += v_s & M;
_p[i] = (int)cc__p; cc__p >>>= 32;
cc_p += p_i & M;
cc_p += v_s & M;
p_i = (int)cc_p; cc_p >>= 32;
p[i] = p_i;

int next_q = _p[i - sWords];
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
prev_q = next_q;
int q_s = (p_i << s) | (prev_q >>> -s);
prev_q =p_i;

cc_Nu += q_s & M;
Nu[i] = (int)cc_Nu; cc_Nu >>>= 32;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
else
{
// Keep the original value of p in t.
System.arraycopy(p, 0, t, 0, p.length);

int sWords = s >>> 5; int sBits = s & 31;
if (sBits == 0)
{
for (int i = sWords; i <= last; ++i)
{
cc_Nu += Nu[i] & M;
cc_Nu += t[i - sWords] & M;

cc_p += p[i] & M;
cc_p += Nv[i - sWords] & M;
p[i] = (int)cc_p; cc_p >>= 32;

cc_Nu += p[i - sWords] & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
else
{
int prev_t = 0;
int prev_q = 0;
int prev_v = 0;

for (int i = sWords; i <= last; ++i)
{
int next_t = t[i - sWords];
int t_s = (next_t << sBits) | (prev_t >>> -sBits);
prev_t = next_t;

cc_Nu += Nu[i] & M;
cc_Nu += t_s & M;

int next_v = Nv[i - sWords];
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
prev_v = next_v;

cc_p += p[i] & M;
cc_p += v_s & M;
p[i] = (int)cc_p; cc_p >>= 32;

int next_q = p[i - sWords];
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
prev_q = next_q;

cc_Nu += q_s & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
}
}
Expand Down Expand Up @@ -141,59 +195,113 @@ static boolean lessThan(int last, int[] x, int[] y)
return false;
}

static void subShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] _p)
static void subShifted_NP(int last, int s, int[] Nu, int[] Nv, int[] p, int[] t)
{
int sWords = s >>> 5, sBits = s & 31;

long cc__p = 0L;
long cc_p = 0L;
long cc_Nu = 0L;

if (sBits == 0)
if (s == 0)
{
for (int i = sWords; i <= last; ++i)
for (int i = 0; i <= last; ++i)
{
int p_i = p[i];

cc_Nu += Nu[i] & M;
cc_Nu -= _p[i - sWords] & M;
cc_Nu -= p_i & M;

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

cc_Nu -= _p[i - sWords] & M;
cc_Nu -= p_i & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
else
else if (s < 32)
{
int prev_p = 0;
int prev_q = 0;
int prev_v = 0;

for (int i = sWords; i <= last; ++i)
for (int i = 0; i <= last; ++i)
{
int next_p = _p[i - sWords];
int p_s = (next_p << sBits) | (prev_p >>> -sBits);
prev_p = next_p;
int p_i = p[i];
int p_s = (p_i << s) | (prev_p >>> -s);
prev_p = p_i;

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

int next_v = Nv[i - sWords];
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
int next_v = Nv[i];
int v_s = (next_v << s) | (prev_v >>> -s);
prev_v = next_v;

cc__p += _p[i] & M;
cc__p -= v_s & M;
_p[i] = (int)cc__p; cc__p >>= 32;
cc_p += p_i & M;
cc_p -= v_s & M;
p_i = (int)cc_p; cc_p >>= 32;
p[i] = p_i;

int next_q = _p[i - sWords];
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
prev_q = next_q;
int q_s = (p_i << s) | (prev_q >>> -s);
prev_q = p_i;

cc_Nu -= q_s & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
else
{
// Keep the original value of p in t.
System.arraycopy(p, 0, t, 0, p.length);

int sWords = s >>> 5; int sBits = s & 31;
if (sBits == 0)
{
for (int i = sWords; i <= last; ++i)
{
cc_Nu += Nu[i] & M;
cc_Nu -= t[i - sWords] & M;

cc_p += p[i] & M;
cc_p -= Nv[i - sWords] & M;
p[i] = (int)cc_p; cc_p >>= 32;

cc_Nu -= p[i - sWords] & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
else
{
int prev_t = 0;
int prev_q = 0;
int prev_v = 0;

for (int i = sWords; i <= last; ++i)
{
int next_t = t[i - sWords];
int t_s = (next_t << sBits) | (prev_t >>> -sBits);
prev_t = next_t;

cc_Nu += Nu[i] & M;
cc_Nu -= t_s & M;

int next_v = Nv[i - sWords];
int v_s = (next_v << sBits) | (prev_v >>> -sBits);
prev_v = next_v;

cc_p += p[i] & M;
cc_p -= v_s & M;
p[i] = (int)cc_p; cc_p >>= 32;

int next_q = p[i - sWords];
int q_s = (next_q << sBits) | (prev_q >>> -sBits);
prev_q = next_q;

cc_Nu -= q_s & M;
Nu[i] = (int)cc_Nu; cc_Nu >>= 32;
}
}
}
}

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

0 comments on commit 9c16579

Please sign in to comment.