Skip to content

Commit

Permalink
EdDsa: add basepoint multiples to support scalar splitting
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdettman committed Nov 19, 2022
1 parent d6ad54d commit bfbc6a6
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 33 deletions.
63 changes: 50 additions & 13 deletions crypto/src/math/ec/rfc8032/Ed25519.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ public enum Algorithm
private static readonly int[] B_y = { 0x02666658, 0x01999999, 0x00666666, 0x03333333, 0x00CCCCCC, 0x02666666,
0x01999999, 0x00666666, 0x03333333, 0x00CCCCCC, };

// 2^128 * B
private static readonly int[] B128_x = { 0x00B7E824, 0x0011EB98, 0x003E5FC8, 0x024E1739, 0x0131CD0B, 0x014E29A0,
0x034E6138, 0x0132C952, 0x03F9E22F, 0x00984F5F };
private static readonly int[] B128_y = { 0x03F5A66B, 0x02AF4452, 0x0049E5BB, 0x00F28D26, 0x0121A17C, 0x02C29C3A,
0x0047AD89, 0x0087D95F, 0x0332936E, 0x00BE5933 };

// Note that d == -121665/121666
private static readonly int[] C_d = { 0x035978A3, 0x02D37284, 0x018AB75E, 0x026A0A0E, 0x0000E014, 0x0379E898,
0x01D01E5D, 0x01E738CC, 0x03715B7F, 0x00A406D9 };
Expand All @@ -93,6 +99,7 @@ public enum Algorithm

private static readonly object PrecompLock = new object();
private static PointPrecomp[] PrecompBaseWnaf = null;
private static PointPrecomp[] PrecompBase128Wnaf = null;
private static int[] PrecompBaseComb = null;

private struct PointAccum
Expand Down Expand Up @@ -1072,20 +1079,21 @@ private static void PointLookupZ(uint[] x, int n, int[] table, ref PointPrecompZ
}
#endif

private static void PointPrecompute(ref PointAffine p, PointExtended[] points, int count, ref PointTemp t)
private static void PointPrecompute(ref PointAffine p, PointExtended[] points, int pointsOff, int pointsLen,
ref PointTemp t)
{
Debug.Assert(count > 0);
Debug.Assert(pointsLen > 0);

Init(out points[0]);
PointCopy(ref p, ref points[0]);
Init(out points[pointsOff]);
PointCopy(ref p, ref points[pointsOff]);

Init(out PointExtended d);
PointAdd(ref points[0], ref points[0], ref d, ref t);
PointAdd(ref points[pointsOff], ref points[pointsOff], ref d, ref t);

for (int i = 1; i < count; ++i)
for (int i = 1; i < pointsLen; ++i)
{
Init(out points[i]);
PointAdd(ref points[i - 1], ref d, ref points[i], ref t);
Init(out points[pointsOff + i]);
PointAdd(ref points[pointsOff + i - 1], ref d, ref points[pointsOff + i], ref t);
}
}

Expand Down Expand Up @@ -1159,12 +1167,12 @@ public static void Precompute()
{
lock (PrecompLock)
{
if (PrecompBaseWnaf != null && PrecompBaseComb != null)
if (PrecompBaseComb != null)
return;

int wnafPoints = 1 << (WnafWidthBase - 2);
int combPoints = PrecompBlocks * PrecompPoints;
int totalPoints = wnafPoints + combPoints;
int totalPoints = wnafPoints * 2 + combPoints;

PointExtended[] points = new PointExtended[totalPoints];
Init(out PointTemp t);
Expand All @@ -1173,7 +1181,13 @@ public static void Precompute()
F.Copy(B_x, 0, b.x, 0);
F.Copy(B_y, 0, b.y, 0);

PointPrecompute(ref b, points, wnafPoints, ref t);
PointPrecompute(ref b, points, 0, wnafPoints, ref t);

Init(out PointAffine b128);
F.Copy(B128_x, 0, b128.x, 0);
F.Copy(B128_y, 0, b128.y, 0);

PointPrecompute(ref b128, points, wnafPoints, wnafPoints, ref t);

Init(out PointAccum p);
F.Copy(B_x, 0, p.x, 0);
Expand All @@ -1182,7 +1196,7 @@ public static void Precompute()
F.Copy(B_x, 0, p.u, 0);
F.Copy(B_y, 0, p.v, 0);

int pointsIndex = wnafPoints;
int pointsIndex = wnafPoints * 2;
PointExtended[] toothPowers = new PointExtended[PrecompTeeth];
for (int tooth = 0; tooth < PrecompTeeth; ++tooth)
{
Expand Down Expand Up @@ -1260,10 +1274,33 @@ public static void Precompute()
F.Normalize(r.xyd);
}

PrecompBase128Wnaf = new PointPrecomp[wnafPoints];
for (int i = 0; i < wnafPoints; ++i)
{
ref PointExtended q = ref points[wnafPoints + i];
ref PointPrecomp r = ref PrecompBase128Wnaf[i];
Init(out r);

// Calculate x/2 and y/2 (because the z value holds half the inverse; see above).
F.Mul(q.x, q.z, q.x);
F.Mul(q.y, q.z, q.y);

// y/2 +/- x/2
F.Apm(q.y, q.x, r.ypx_h, r.ymx_h);

// x/2 * y/2 * (4.d) == x.y.d
F.Mul(q.x, q.y, r.xyd);
F.Mul(r.xyd, C_d4, r.xyd);

F.Normalize(r.ymx_h);
F.Normalize(r.ypx_h);
F.Normalize(r.xyd);
}

PrecompBaseComb = F.CreateTable(combPoints * 3);
Init(out PointPrecomp s);
int off = 0;
for (int i = wnafPoints; i < totalPoints; ++i)
for (int i = wnafPoints * 2; i < totalPoints; ++i)
{
ref PointExtended q = ref points[i];

Expand Down
71 changes: 51 additions & 20 deletions crypto/src/math/ec/rfc8032/Ed448.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,21 @@ public enum Algorithm
private const int L4_6 = 0x08EEC492; // L4_6:27/24
private const int L4_7 = 0x20CD7705; // L4_7:29/24

private static readonly uint[] B_x = { 0x070CC05EU, 0x026A82BCU, 0x00938E26U, 0x080E18B0U, 0x0511433BU, 0x0F72AB66U, 0x0412AE1AU,
0x0A3D3A46U, 0x0A6DE324U, 0x00F1767EU, 0x04657047U, 0x036DA9E1U, 0x05A622BFU, 0x0ED221D1U, 0x066BED0DU, 0x04F1970CU };
private static readonly uint[] B_y = { 0x0230FA14U, 0x008795BFU, 0x07C8AD98U, 0x0132C4EDU, 0x09C4FDBDU, 0x01CE67C3U, 0x073AD3FFU,
0x005A0C2DU, 0x07789C1EU, 0x0A398408U, 0x0A73736CU, 0x0C7624BEU, 0x003756C9U, 0x02488762U, 0x016EB6BCU, 0x0693F467U };
private static readonly uint[] B_x = { 0x070CC05EU, 0x026A82BCU, 0x00938E26U, 0x080E18B0U, 0x0511433BU,
0x0F72AB66U, 0x0412AE1AU, 0x0A3D3A46U, 0x0A6DE324U, 0x00F1767EU, 0x04657047U, 0x036DA9E1U, 0x05A622BFU,
0x0ED221D1U, 0x066BED0DU, 0x04F1970CU };
private static readonly uint[] B_y = { 0x0230FA14U, 0x008795BFU, 0x07C8AD98U, 0x0132C4EDU, 0x09C4FDBDU,
0x01CE67C3U, 0x073AD3FFU, 0x005A0C2DU, 0x07789C1EU, 0x0A398408U, 0x0A73736CU, 0x0C7624BEU, 0x003756C9U,
0x02488762U, 0x016EB6BCU, 0x0693F467U };

// 2^224 * B
private static readonly uint[] B224_x = { 0x091780C7U, 0x0A7EA989U, 0x0D2476B6U, 0x004E4ECCU, 0x0C494B68U,
0x00AF9F58U, 0x0DEE64FDU, 0x0E0F269FU, 0x0021BD26U, 0x085A61F6U, 0x0B5D284BU, 0x0C265C35U, 0x03775AFDU,
0x058755EAU, 0x02ECF2C6U, 0x0617F174U };
private static readonly uint[] B224_y = { 0x05EC556AU, 0x050109E2U, 0x0FD57E39U, 0x0235366BU, 0x044B6B2EU,
0x07B3C976U, 0x0B2B7B9CU, 0x0F7F9E82U, 0x00EC6409U, 0x0B6196ABU, 0x00A20D9EU, 0x088F1D16U, 0x0586F761U,
0x0e3BE3B4U, 0x0E26395DU, 0x09983C26U };

private const int C_d = -39081;

private const int WnafWidth = 5;
Expand All @@ -92,6 +103,7 @@ public enum Algorithm

private static readonly object PrecompLock = new object();
private static PointAffine[] PrecompBaseWnaf = null;
private static PointAffine[] PrecompBase224Wnaf = null;
private static uint[] PrecompBaseComb = null;

private struct PointAffine
Expand Down Expand Up @@ -1067,21 +1079,22 @@ private static uint[] PointPrecompute(ref PointProjective p, int count)
return table;
}

private static void PointPrecomputeVar(ref PointProjective p, PointProjective[] points, int count)
private static void PointPrecomputeVar(ref PointProjective p, PointProjective[] points, int pointsOff,
int pointsLen)
{
Debug.Assert(count > 0);
Debug.Assert(pointsLen > 0);

Init(out PointProjective d);
PointCopy(ref p, ref d);
PointDouble(ref d);

Init(out points[0]);
PointCopy(ref p, ref points[0]);
for (int i = 1; i < count; ++i)
Init(out points[pointsOff]);
PointCopy(ref p, ref points[pointsOff]);
for (int i = 1; i < pointsLen; ++i)
{
Init(out points[i]);
PointCopy(ref points[i - 1], ref points[i]);
PointAdd(ref d, ref points[i]);
Init(out points[pointsOff + i]);
PointCopy(ref points[pointsOff + i - 1], ref points[pointsOff + i]);
PointAdd(ref d, ref points[pointsOff + i]);
}
}

Expand All @@ -1096,15 +1109,15 @@ public static void Precompute()
{
lock (PrecompLock)
{
if (PrecompBaseWnaf != null && PrecompBaseComb != null)
if (PrecompBaseComb != null)
return;

Debug.Assert(PrecompRange > 448);
Debug.Assert(PrecompRange < 480);

int wnafPoints = 1 << (WnafWidthBase - 2);
int combPoints = PrecompBlocks * PrecompPoints;
int totalPoints = wnafPoints + combPoints;
int totalPoints = wnafPoints * 2 + combPoints;

PointProjective[] points = new PointProjective[totalPoints];

Expand All @@ -1113,9 +1126,16 @@ public static void Precompute()
F.Copy(B_y, 0, p.y, 0);
F.One(p.z);

PointPrecomputeVar(ref p, points, wnafPoints);
PointPrecomputeVar(ref p, points, 0, wnafPoints);

Init(out PointProjective p224);
F.Copy(B224_x, 0, p224.x, 0);
F.Copy(B224_y, 0, p224.y, 0);
F.One(p224.z);

int pointsIndex = wnafPoints;
PointPrecomputeVar(ref p224, points, wnafPoints, wnafPoints);

int pointsIndex = wnafPoints * 2;
PointProjective[] toothPowers = new PointProjective[PrecompTeeth];
for (int tooth = 0; tooth < PrecompTeeth; ++tooth)
{
Expand Down Expand Up @@ -1177,9 +1197,20 @@ public static void Precompute()
F.Mul(q.y, q.z, r.y); F.Normalize(r.y);
}

PrecompBase224Wnaf = new PointAffine[wnafPoints];
for (int i = 0; i < wnafPoints; ++i)
{
ref PointProjective q = ref points[wnafPoints + i];
ref PointAffine r = ref PrecompBase224Wnaf[i];
Init(out r);

F.Mul(q.x, q.z, r.x); F.Normalize(r.x);
F.Mul(q.y, q.z, r.y); F.Normalize(r.y);
}

PrecompBaseComb = F.CreateTable(combPoints * 2);
int off = 0;
for (int i = wnafPoints; i < totalPoints; ++i)
for (int i = wnafPoints * 2; i < totalPoints; ++i)
{
ref PointProjective q = ref points[i];

Expand Down Expand Up @@ -2045,7 +2076,7 @@ private static void ScalarMultOrderVar(ref PointProjective p, ref PointProjectiv

int count = 1 << (WnafWidth - 2);
PointProjective[] tp = new PointProjective[count];
PointPrecomputeVar(ref p, tp, count);
PointPrecomputeVar(ref p, tp, 0, count);

PointSetNeutral(ref r);

Expand Down Expand Up @@ -2079,7 +2110,7 @@ private static void ScalarMultStrausVar(uint[] nb, uint[] np, ref PointProjectiv

int count = 1 << (WnafWidth - 2);
PointProjective[] tp = new PointProjective[count];
PointPrecomputeVar(ref p, tp, count);
PointPrecomputeVar(ref p, tp, 0, count);

PointSetNeutral(ref r);

Expand Down Expand Up @@ -2122,7 +2153,7 @@ private static void ScalarMultStrausVar(ReadOnlySpan<uint> nb, ReadOnlySpan<uint

int count = 1 << (WnafWidth - 2);
PointProjective[] tp = new PointProjective[count];
PointPrecomputeVar(ref p, tp, count);
PointPrecomputeVar(ref p, tp, 0, count);

PointSetNeutral(ref r);

Expand Down

0 comments on commit bfbc6a6

Please sign in to comment.