Skip to content

Commit

Permalink
EdDSA: Explicit guard against infinite looping
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdettman committed Mar 14, 2024
1 parent 64439fc commit 1e96ddd
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 14 deletions.
8 changes: 6 additions & 2 deletions crypto/src/math/ec/rfc8032/Ed25519.cs
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,9 @@ private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byt
uint[] v1 = new uint[4];
#endif

Scalar25519.ReduceBasisVar(nA, v0, v1);
if (!Scalar25519.ReduceBasisVar(nA, v0, v1))
throw new InvalidOperationException();

Scalar25519.Multiply128Var(nS, v1, nS);

Init(out PointAccum pZ);
Expand Down Expand Up @@ -852,7 +854,9 @@ private static bool ImplVerify(byte[] sig, int sigOff, PublicPoint publicPoint,
uint[] v1 = new uint[4];
#endif

Scalar25519.ReduceBasisVar(nA, v0, v1);
if (!Scalar25519.ReduceBasisVar(nA, v0, v1))
throw new InvalidOperationException();

Scalar25519.Multiply128Var(nS, v1, nS);

Init(out PointAccum pZ);
Expand Down
8 changes: 6 additions & 2 deletions crypto/src/math/ec/rfc8032/Ed448.cs
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,9 @@ private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byt
uint[] v1 = new uint[8];
#endif

Scalar448.ReduceBasisVar(nA, v0, v1);
if (!Scalar448.ReduceBasisVar(nA, v0, v1))
throw new InvalidOperationException();

Scalar448.Multiply225Var(nS, v1, nS);

Init(out PointProjective pZ);
Expand Down Expand Up @@ -790,7 +792,9 @@ private static bool ImplVerify(byte[] sig, int sigOff, PublicPoint publicPoint,
uint[] v1 = new uint[8];
#endif

Scalar448.ReduceBasisVar(nA, v0, v1);
if (!Scalar448.ReduceBasisVar(nA, v0, v1))
throw new InvalidOperationException();

Scalar448.Multiply225Var(nS, v1, nS);

Init(out PointProjective pZ);
Expand Down
16 changes: 14 additions & 2 deletions crypto/src/math/ec/rfc8032/Scalar25519.cs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ internal static void Reduce512(ReadOnlySpan<byte> n, Span<byte> r)
#endif

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
internal static void ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<uint> z1)
internal static bool ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<uint> z1)
{
/*
* Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L.
Expand All @@ -612,11 +612,16 @@ internal static void ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<ui
Span<uint> v0 = stackalloc uint[4]; v0.CopyFrom(k);
Span<uint> v1 = stackalloc uint[4]; v1[0] = 1U;

// Conservative upper bound on the number of loop iterations needed
int iterations = TargetLength * 4;
int last = 15;
int len_Nv = ScalarUtilities.GetBitLengthPositive(last, Nv);

while (len_Nv > TargetLength)
{
if (--iterations < 0)
return false;

int len_p = ScalarUtilities.GetBitLength(last, p);
int s = len_p - len_Nv;
s &= ~(s >> 31);
Expand Down Expand Up @@ -646,9 +651,10 @@ internal static void ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<ui
// v1 * k == v0 mod L
v0.CopyTo(z0);
v1.CopyTo(z1);
return true;
}
#else
internal static void ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
internal static bool ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
{
/*
* Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L.
Expand All @@ -665,11 +671,16 @@ internal static void ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
uint[] v0 = new uint[4]; Array.Copy(k, v0, 4);
uint[] v1 = new uint[4]; v1[0] = 1U;

// Conservative upper bound on the number of loop iterations needed
int iterations = TargetLength * 4;
int last = 15;
int len_Nv = ScalarUtilities.GetBitLengthPositive(last, Nv);

while (len_Nv > TargetLength)
{
if (--iterations < 0)
return false;

int len_p = ScalarUtilities.GetBitLength(last, p);
int s = len_p - len_Nv;
s &= ~(s >> 31);
Expand Down Expand Up @@ -699,6 +710,7 @@ internal static void ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
// v1 * k == v0 mod L
Array.Copy(v0, z0, 4);
Array.Copy(v1, z1, 4);
return true;
}
#endif

Expand Down
16 changes: 14 additions & 2 deletions crypto/src/math/ec/rfc8032/Scalar448.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ internal static void Reduce912(ReadOnlySpan<byte> n, Span<byte> r)
#endif

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
internal static void ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<uint> z1)
internal static bool ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<uint> z1)
{
/*
* Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L.
Expand All @@ -1131,11 +1131,16 @@ internal static void ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<ui
Span<uint> v0 = stackalloc uint[8]; v0.CopyFrom(k);
Span<uint> v1 = stackalloc uint[8]; v1[0] = 1U;

// Conservative upper bound on the number of loop iterations needed
int iterations = TargetLength * 4;
int last = 27;
int len_Nv = ScalarUtilities.GetBitLengthPositive(last, Nv);

while (len_Nv > TargetLength)
{
if (--iterations < 0)
return false;

int len_p = ScalarUtilities.GetBitLength(last, p);
int s = len_p - len_Nv;
s &= ~(s >> 31);
Expand Down Expand Up @@ -1168,9 +1173,10 @@ internal static void ReduceBasisVar(ReadOnlySpan<uint> k, Span<uint> z0, Span<ui
// v1 * k == v0 mod L
v0.CopyTo(z0);
v1.CopyTo(z1);
return true;
}
#else
internal static void ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
internal static bool ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
{
/*
* Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L.
Expand All @@ -1187,11 +1193,16 @@ internal static void ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
uint[] v0 = new uint[8]; Array.Copy(k, v0, 8);
uint[] v1 = new uint[8]; v1[0] = 1U;

// Conservative upper bound on the number of loop iterations needed
int iterations = TargetLength * 4;
int last = 27;
int len_Nv = ScalarUtilities.GetBitLengthPositive(last, Nv);

while (len_Nv > TargetLength)
{
if (--iterations < 0)
return false;

int len_p = ScalarUtilities.GetBitLength(last, p);
int s = len_p - len_Nv;
s &= ~(s >> 31);
Expand Down Expand Up @@ -1224,6 +1235,7 @@ internal static void ReduceBasisVar(uint[] k, uint[] z0, uint[] z1)
// v1 * k == v0 mod L
Array.Copy(v0, z0, 8);
Array.Copy(v1, z1, 8);
return true;
}
#endif

Expand Down
12 changes: 6 additions & 6 deletions crypto/src/math/ec/rfc8032/ScalarUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ internal static void AddShifted_NP(int last, int s, uint[] Nu, uint[] Nv, uint[]
}
else
{
// Keep the original value of p in t
// Copy the low limbs of the original p
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
t[..(last + 1)].CopyFrom(p);
t[..last].CopyFrom(p);
#else
Array.Copy(p, 0, t, 0, last + 1);
Array.Copy(p, 0, t, 0, last);
#endif

int sWords = s >> 5, sBits = s & 31;
Expand Down Expand Up @@ -288,11 +288,11 @@ internal static void SubShifted_NP(int last, int s, uint[] Nu, uint[] Nv, uint[]
}
else
{
// Keep the original value of p in t
// Copy the low limbs of the original p
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
t[..(last + 1)].CopyFrom(p);
t[..last].CopyFrom(p);
#else
Array.Copy(p, 0, t, 0, last + 1);
Array.Copy(p, 0, t, 0, last);
#endif

int sWords = s >> 5, sBits = s & 31;
Expand Down

0 comments on commit 1e96ddd

Please sign in to comment.