diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-11-26 23:25:56 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-11-26 23:25:56 +0700 |
commit | 589bbac9b3c56e2eba76744179f00443bac3f118 (patch) | |
tree | 12ed57b36f1130f31b42aaf029d2f7045d55f303 | |
parent | EdDSA: Hold decoded pubilc point in public keys (diff) | |
download | BouncyCastle.NET-ed25519-589bbac9b3c56e2eba76744179f00443bac3f118.tar.xz |
Refactoring in Math.EC.Rfc8032
-rw-r--r-- | crypto/src/math/ec/rfc8032/Ed25519.cs | 24 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/Ed448.cs | 191 |
2 files changed, 124 insertions, 91 deletions
diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs index 2479d94d4..baacc75fa 100644 --- a/crypto/src/math/ec/rfc8032/Ed25519.cs +++ b/crypto/src/math/ec/rfc8032/Ed25519.cs @@ -1566,16 +1566,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int cOff = (PrecompSpacing - 1) * PrecompTeeth; for (;;) { - for (int b = 0; b < PrecompBlocks; ++b) + for (int block = 0; block < PrecompBlocks; ++block) { - uint w = n[b] >> cOff; + uint w = n[block] >> cOff; int sign = (int)(w >> (PrecompTeeth - 1)) & 1; int abs = ((int)w ^ -sign) & PrecompMask; Debug.Assert(sign == 0 || sign == 1); Debug.Assert(0 <= abs && abs < PrecompPoints); - PointLookup(b, abs, ref p); + PointLookup(block, abs, ref p); F.CNegate(resultSign ^ sign, r.x); F.CNegate(resultSign ^ sign, r.u); @@ -1771,7 +1771,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff); } - public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, + int sigOff) { byte[] ctx = null; byte phflag = 0x00; @@ -1786,7 +1787,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff); } - public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, + byte[] sig, int sigOff) { byte phflag = 0x00; @@ -1800,7 +1802,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff); } - public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, + byte[] sig, int sigOff) { byte phflag = 0x01; @@ -1818,7 +1821,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, m, 0, m.Length, sig, sigOff); } - public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IDigest ph, byte[] sig, int sigOff) + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IDigest ph, byte[] sig, + int sigOff) { byte[] m = new byte[PrehashSize]; if (PrehashSize != ph.DoFinal(m, 0)) @@ -2001,14 +2005,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 return ImplVerify(sig, sigOff, publicPoint, ctx, phflag, m, mOff, mLen); } - public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen) + public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, + int mLen) { byte phflag = 0x00; return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen); } - public static bool Verify(byte[] sig, int sigOff, PublicPoint publicPoint, byte[] ctx, byte[] m, int mOff, int mLen) + public static bool Verify(byte[] sig, int sigOff, PublicPoint publicPoint, byte[] ctx, byte[] m, int mOff, + int mLen) { byte phflag = 0x00; diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs index 8ffbccfa4..d3a9caf4d 100644 --- a/crypto/src/math/ec/rfc8032/Ed448.cs +++ b/crypto/src/math/ec/rfc8032/Ed448.cs @@ -102,6 +102,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 internal uint[] x, y, z; } + // Temp space to avoid allocations in point formulae. + private struct PointTemp + { + internal uint[] r0, r1, r2, r3, r4, r5, r6, r7; + } + private static byte[] CalculateS(byte[] r, byte[] k, byte[] s) { uint[] t = new uint[ScalarUints * 2]; Scalar448.Decode(r, t); @@ -578,8 +584,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(d, h, s, pk, 0, ctx, phflag, m, mOff, mLen, sig, sigOff); } - private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, - byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, byte[] m, + int mOff, int mLen, byte[] sig, int sigOff) { if (!CheckContextVar(ctx)) throw new ArgumentException("ctx"); @@ -596,8 +602,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); } - private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, - byte[] m, int mOff, int mLen) + private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, byte[] m, + int mOff, int mLen) { if (!CheckContextVar(ctx)) throw new ArgumentException("ctx"); @@ -803,6 +809,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 r.z = F.Create(); } + private static void Init(out PointTemp r) + { + r.r0 = F.Create(); + r.r1 = F.Create(); + r.r2 = F.Create(); + r.r3 = F.Create(); + r.r4 = F.Create(); + r.r5 = F.Create(); + r.r6 = F.Create(); + r.r7 = F.Create(); + } + private static void InvertZs(PointProjective[] points) { int count = points.Length; @@ -859,15 +877,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 return IsNeutralElementVar(p.x, p.y, p.z); } - private static void PointAdd(ref PointAffine p, ref PointProjective r) + private static void PointAdd(ref PointAffine p, ref PointProjective r, ref PointTemp t) { - uint[] b = F.Create(); - uint[] c = F.Create(); - uint[] d = F.Create(); - uint[] e = F.Create(); - uint[] f = F.Create(); - uint[] g = F.Create(); - uint[] h = F.Create(); + uint[] b = t.r1; + uint[] c = t.r2; + uint[] d = t.r3; + uint[] e = t.r4; + uint[] f = t.r5; + uint[] g = t.r6; + uint[] h = t.r7; F.Sqr(r.z, b); F.Mul(p.x, r.x, c); @@ -892,16 +910,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Mul(f, g, r.z); } - private static void PointAdd(ref PointProjective p, ref PointProjective r) + private static void PointAdd(ref PointProjective p, ref PointProjective r, ref PointTemp t) { - uint[] a = F.Create(); - uint[] b = F.Create(); - uint[] c = F.Create(); - uint[] d = F.Create(); - uint[] e = F.Create(); - uint[] f = F.Create(); - uint[] g = F.Create(); - uint[] h = F.Create(); + uint[] a = t.r0; + uint[] b = t.r1; + uint[] c = t.r2; + uint[] d = t.r3; + uint[] e = t.r4; + uint[] f = t.r5; + uint[] g = t.r6; + uint[] h = t.r7; F.Mul(p.z, r.z, a); F.Sqr(a, b); @@ -927,15 +945,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Mul(f, g, r.z); } - private static void PointAddVar(bool negate, ref PointAffine p, ref PointProjective r) + private static void PointAddVar(bool negate, ref PointAffine p, ref PointProjective r, ref PointTemp t) { - uint[] b = F.Create(); - uint[] c = F.Create(); - uint[] d = F.Create(); - uint[] e = F.Create(); - uint[] f = F.Create(); - uint[] g = F.Create(); - uint[] h = F.Create(); + uint[] b = t.r1; + uint[] c = t.r2; + uint[] d = t.r3; + uint[] e = t.r4; + uint[] f = t.r5; + uint[] g = t.r6; + uint[] h = t.r7; uint[] nb, ne, nf, ng; if (negate) @@ -971,16 +989,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Mul(f, g, r.z); } - private static void PointAddVar(bool negate, ref PointProjective p, ref PointProjective r) + private static void PointAddVar(bool negate, ref PointProjective p, ref PointProjective r, ref PointTemp t) { - uint[] a = F.Create(); - uint[] b = F.Create(); - uint[] c = F.Create(); - uint[] d = F.Create(); - uint[] e = F.Create(); - uint[] f = F.Create(); - uint[] g = F.Create(); - uint[] h = F.Create(); + uint[] a = t.r0; + uint[] b = t.r1; + uint[] c = t.r2; + uint[] d = t.r3; + uint[] e = t.r4; + uint[] f = t.r5; + uint[] g = t.r6; + uint[] h = t.r7; uint[] nb, ne, nf, ng; if (negate) @@ -1031,14 +1049,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Copy(p.z, 0, r.z, 0); } - private static void PointDouble(ref PointProjective r) + private static void PointDouble(ref PointProjective r, ref PointTemp t) { - uint[] b = F.Create(); - uint[] c = F.Create(); - uint[] d = F.Create(); - uint[] e = F.Create(); - uint[] h = F.Create(); - uint[] j = F.Create(); + uint[] b = t.r1; + uint[] c = t.r2; + uint[] d = t.r3; + uint[] e = t.r4; + uint[] h = t.r7; + uint[] j = t.r0; F.Add(r.x, r.y, b); F.Sqr(b, b); @@ -1129,7 +1147,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Copy(table, off, r.z, 0); } - private static uint[] PointPrecompute(ref PointProjective p, int count) + private static uint[] PointPrecompute(ref PointProjective p, int count, ref PointTemp t) { Debug.Assert(count > 0); @@ -1138,7 +1156,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Init(out PointProjective d); PointCopy(ref q, ref d); - PointDouble(ref d); + PointDouble(ref d, ref t); uint[] table = F.CreateTable(count * 3); int off = 0; @@ -1153,19 +1171,20 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (++i == count) break; - PointAdd(ref d, ref q); + PointAdd(ref d, ref q, ref t); } return table; } - private static void PointPrecompute(ref PointAffine p, PointProjective[] points, int pointsOff, int pointsLen) + private static void PointPrecompute(ref PointAffine p, PointProjective[] points, int pointsOff, int pointsLen, + ref PointTemp t) { Debug.Assert(pointsLen > 0); Init(out PointProjective d); PointCopy(ref p, ref d); - PointDouble(ref d); + PointDouble(ref d, ref t); Init(out points[pointsOff]); PointCopy(ref p, ref points[pointsOff]); @@ -1174,7 +1193,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Init(out points[pointsOff + i]); PointCopy(ref points[pointsOff + i - 1], ref points[pointsOff + i]); - PointAdd(ref d, ref points[pointsOff + i]); + PointAdd(ref d, ref points[pointsOff + i], ref t); } } @@ -1200,18 +1219,19 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int totalPoints = wnafPoints * 2 + combPoints; PointProjective[] points = new PointProjective[totalPoints]; + Init(out PointTemp t); Init(out PointAffine B); F.Copy(B_x, 0, B.x, 0); F.Copy(B_y, 0, B.y, 0); - PointPrecompute(ref B, points, 0, wnafPoints); + PointPrecompute(ref B, points, 0, wnafPoints, ref t); Init(out PointAffine B225); F.Copy(B225_x, 0, B225.x, 0); F.Copy(B225_y, 0, B225.y, 0); - PointPrecompute(ref B225, points, wnafPoints, wnafPoints); + PointPrecompute(ref B225, points, wnafPoints, wnafPoints, ref t); Init(out PointProjective p); PointCopy(ref B, ref p); @@ -1236,17 +1256,17 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } else { - PointAdd(ref p, ref sum); + PointAdd(ref p, ref sum, ref t); } - PointDouble(ref p); + PointDouble(ref p, ref t); PointCopy(ref p, ref toothPowers[tooth]); if (block + tooth != PrecompBlocks + PrecompTeeth - 2) { for (int spacing = 1; spacing < PrecompSpacing; ++spacing) { - PointDouble(ref p); + PointDouble(ref p, ref t); } } } @@ -1260,7 +1280,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Init(out points[pointsIndex]); PointCopy(ref points[pointsIndex - size], ref points[pointsIndex]); - PointAdd(ref toothPowers[tooth], ref points[pointsIndex]); + PointAdd(ref toothPowers[tooth], ref points[pointsIndex], ref t); } } } @@ -1344,25 +1364,26 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 // NOTE: Bit 448 is handled explicitly by an initial addition Debug.Assert(n[ScalarUints] == 1U); - uint[] table = PointPrecompute(ref p, 8); Init(out PointProjective q); + Init(out PointTemp t); + uint[] table = PointPrecompute(ref p, 8, ref t); // Replace first 4 doublings (2^4 * P) with 1 addition (P + 15 * P) PointLookup15(table, ref r); - PointAdd(ref p, ref r); + PointAdd(ref p, ref r, ref t); int w = 111; for (;;) { PointLookup(n, w, table, ref q); - PointAdd(ref q, ref r); + PointAdd(ref q, ref r, ref t); if (--w < 0) break; for (int i = 0; i < 4; ++i) { - PointDouble(ref r); + PointDouble(ref r, ref t); } } } @@ -1392,6 +1413,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Scalar448.ToSignedDigits(PrecompRange, n, n); Init(out PointAffine p); + Init(out PointTemp t); PointSetNeutral(ref r); @@ -1400,14 +1422,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { int tPos = cOff; - for (int b = 0; b < PrecompBlocks; ++b) + for (int block = 0; block < PrecompBlocks; ++block) { uint w = 0; - for (int t = 0; t < PrecompTeeth; ++t) + for (int tooth = 0; tooth < PrecompTeeth; ++tooth) { uint tBit = n[tPos >> 5] >> (tPos & 0x1F); - w &= ~(1U << t); - w ^= (tBit << t); + w &= ~(1U << tooth); + w ^= (tBit << tooth); tPos += PrecompSpacing; } @@ -1417,17 +1439,17 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Debug.Assert(sign == 0 || sign == 1); Debug.Assert(0 <= abs && abs < PrecompPoints); - PointLookup(b, abs, ref p); + PointLookup(block, abs, ref p); F.CNegate(sign, p.x); - PointAdd(ref p, ref r); + PointAdd(ref p, ref r, ref t); } if (--cOff < 0) break; - PointDouble(ref r); + PointDouble(ref r, ref t); } } @@ -1501,7 +1523,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int count = 1 << (WnafWidth225 - 2); PointProjective[] tp = new PointProjective[count]; - PointPrecompute(ref p, tp, 0, count); + Init(out PointTemp t); + PointPrecompute(ref p, tp, 0, count, ref t); PointSetNeutral(ref r); @@ -1511,13 +1534,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (wp != 0) { int index = (wp >> 1) ^ (wp >> 31); - PointAddVar(wp < 0, ref tp[index], ref r); + PointAddVar(wp < 0, ref tp[index], ref r, ref t); } if (--bit < 0) break; - PointDouble(ref r); + PointDouble(ref r, ref t); } } @@ -1555,8 +1578,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int count = 1 << (WnafWidth225 - 2); PointProjective[] tp = new PointProjective[count]; PointProjective[] tq = new PointProjective[count]; - PointPrecompute(ref p, tp, 0, count); - PointPrecompute(ref q, tq, 0, count); + Init(out PointTemp t); + PointPrecompute(ref p, tp, 0, count, ref t); + PointPrecompute(ref q, tq, 0, count, ref t); PointSetNeutral(ref r); @@ -1567,35 +1591,35 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (wb != 0) { int index = (wb >> 1) ^ (wb >> 31); - PointAddVar(wb < 0, ref PrecompBaseWnaf[index], ref r); + PointAddVar(wb < 0, ref PrecompBaseWnaf[index], ref r, ref t); } int wb225 = ws_b[225 + bit]; if (wb225 != 0) { int index = (wb225 >> 1) ^ (wb225 >> 31); - PointAddVar(wb225 < 0, ref PrecompBase225Wnaf[index], ref r); + PointAddVar(wb225 < 0, ref PrecompBase225Wnaf[index], ref r, ref t); } int wp = ws_p[bit]; if (wp != 0) { int index = (wp >> 1) ^ (wp >> 31); - PointAddVar(wp < 0, ref tp[index], ref r); + PointAddVar(wp < 0, ref tp[index], ref r, ref t); } int wq = ws_q[bit]; if (wq != 0) { int index = (wq >> 1) ^ (wq >> 31); - PointAddVar(wq < 0, ref tq[index], ref r); + PointAddVar(wq < 0, ref tq[index], ref r, ref t); } - PointDouble(ref r); + PointDouble(ref r, ref t); } // NOTE: Together with the final PointDouble of the loop, this clears the cofactor of 4 - PointDouble(ref r); + PointDouble(ref r, ref t); } public static void Sign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) @@ -1605,7 +1629,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff); } - public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, + byte[] sig, int sigOff) { byte phflag = 0x00; @@ -1619,7 +1644,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff); } - public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, + byte[] sig, int sigOff) { byte phflag = 0x01; @@ -1637,7 +1663,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ImplSign(sk, skOff, ctx, phflag, m, 0, m.Length, sig, sigOff); } - public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IXof ph, byte[] sig, int sigOff) + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IXof ph, byte[] sig, + int sigOff) { byte[] m = new byte[PrehashSize]; if (PrehashSize != ph.OutputFinal(m, 0, PrehashSize)) |