diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Field.cs b/crypto/src/math/ec/custom/sec/SecP224R1Field.cs
index 4f5c3bbda..06d451c2b 100644
--- a/crypto/src/math/ec/custom/sec/SecP224R1Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224R1Field.cs
@@ -1,18 +1,22 @@
using System;
using System.Diagnostics;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Math.Raw;
+using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP224R1Field
{
// 2^224 - 2^96 + 1
- internal static readonly uint[] P = new uint[] { 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- internal static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
- 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000,
- 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 };
+ internal static readonly uint[] P = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF };
+ private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+ };
+ private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 };
private const uint P6 = 0xFFFFFFFF;
private const uint PExt13 = 0xFFFFFFFF;
@@ -69,6 +73,69 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
}
}
+ public static void Inv(uint[] x, uint[] z)
+ {
+ /*
+ * Raise this element to the exponent 2^224 - 2^96 - 1
+ *
+ * Breaking up the exponent's binary representation into "repunits", we get:
+ * { 127 1s } { 1 0s } { 96 1s }
+ *
+ * Therefore we need an addition chain containing 96, 127 (the lengths of the repunits)
+ * We use: 1, 2, 3, 6, 12, 24, 48, [96], 120, 126, [127]
+ */
+
+ if (0 != IsZero(x))
+ throw new ArgumentException("cannot be 0", "x");
+
+ uint[] x1 = x;
+ uint[] x2 = Nat224.Create();
+ Square(x1, x2);
+ Multiply(x2, x1, x2);
+ uint[] x3 = x2;
+ Square(x2, x3);
+ Multiply(x3, x1, x3);
+ uint[] x6 = Nat224.Create();
+ SquareN(x3, 3, x6);
+ Multiply(x6, x3, x6);
+ uint[] x12 = x3;
+ SquareN(x6, 6, x12);
+ Multiply(x12, x6, x12);
+ uint[] x24 = Nat224.Create();
+ SquareN(x12, 12, x24);
+ Multiply(x24, x12, x24);
+ uint[] x48 = x12;
+ SquareN(x24, 24, x48);
+ Multiply(x48, x24, x48);
+ uint[] x96 = Nat224.Create();
+ SquareN(x48, 48, x96);
+ Multiply(x96, x48, x96);
+ uint[] x120 = x48;
+ SquareN(x96, 24, x120);
+ Multiply(x120, x24, x120);
+ uint[] x126 = x24;
+ SquareN(x120, 6, x126);
+ Multiply(x126, x6, x126);
+ uint[] x127 = x6;
+ Square(x126, x127);
+ Multiply(x127, x1, x127);
+
+ uint[] t = x127;
+ SquareN(t, 97, t);
+ Multiply(t, x96, z);
+ }
+
+ public static int IsZero(uint[] x)
+ {
+ uint d = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ d |= x[i];
+ }
+ d = (d >> 1) | (d & 1);
+ return ((int)d - 1) >> 31;
+ }
+
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] tt = Nat224.CreateExt();
@@ -90,9 +157,9 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
public static void Negate(uint[] x, uint[] z)
{
- if (Nat224.IsZero(x))
+ if (0 != IsZero(x))
{
- Nat224.Zero(z);
+ Nat224.Sub(P, P, z);
}
else
{
@@ -100,6 +167,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
}
}
+ public static void Random(SecureRandom r, uint[] z)
+ {
+ byte[] bb = new byte[7 * 4];
+ do
+ {
+ r.NextBytes(bb);
+ Pack.LE_To_UInt32(bb, 0, z, 0, 7);
+ }
+ while (0 == Nat.LessThan(7, z, P));
+ }
+
+ public static void RandomMult(SecureRandom r, uint[] z)
+ {
+ do
+ {
+ Random(r, z);
+ }
+ while (0 != IsZero(z));
+ }
+
public static void Reduce(uint[] xx, uint[] z)
{
long xx10 = xx[10], xx11 = xx[11], xx12 = xx[12], xx13 = xx[13];
|