diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-02 11:31:49 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-02 11:31:49 +0700 |
commit | 9ea95a408236d1878ec679887b3bbcb3ff3316c4 (patch) | |
tree | f711b109a9ba3710772ab501d270b8d94d6d09ee /crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs | |
parent | Avoid a few negations in Sqrt() (diff) | |
download | BouncyCastle.NET-ed25519-9ea95a408236d1878ec679887b3bbcb3ff3316c4.tar.xz |
Allow for (very rare) cases where the Sqrt() algorithm needs to retry
Diffstat (limited to '')
-rw-r--r-- | crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs index 1f9425dd0..3152f1bee 100644 --- a/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs @@ -124,41 +124,48 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec */ public override ECFieldElement Sqrt() { - //ECFieldElement root = new FpFieldElement(Q, ToBigInteger()).Sqrt(); - //return root == null ? null : new SecP224R1FieldElement(root.ToBigInteger()); - uint[] c = this.x; if (Nat224.IsZero(c) || Nat224.IsOne(c)) return this; - uint[] d1 = Mod.Random(SecP224R1Field.P); - uint[] e1 = Nat224.Create(); - e1[0] = 1; + uint[] nc = Nat224.Create(); + SecP224R1Field.Negate(c, nc); - uint[] f = Nat224.Create(); - RP(c, d1, e1, f); - RS(d1, e1, f); + uint[] r = Mod.Random(SecP224R1Field.P); - uint[] d0 = Nat224.Create(); - uint[] e0 = Nat224.Create(); - - for (int i = 0; i < 95; ++i) + for (;;) { - Nat224.Copy(d1, d0); - Nat224.Copy(e1, e0); + uint[] d1 = Nat224.Create(); + Nat224.Copy(r, d1); + uint[] e1 = Nat224.Create(); + e1[0] = 1; + uint[] f1 = Nat224.Create(); + RP(nc, d1, e1, f1); - RS(d1, e1, f); + uint[] d0 = Nat224.Create(); + uint[] e0 = Nat224.Create(); - if (Nat224.IsZero(d1)) - break; - } + for (int k = 1; k < 96; ++k) + { + Nat224.Copy(d1, d0); + Nat224.Copy(e1, e0); + + RS(d1, e1, f1); - Mod.Invert(SecP224R1Field.P, e0, f); - SecP224R1Field.Multiply(f, d0, f); + if (Nat224.IsZero(d1)) + { + Mod.Invert(SecP224R1Field.P, e0, f1); + SecP224R1Field.Multiply(f1, d0, f1); - SecP224R1Field.Square(f, d1); + SecP224R1Field.Square(f1, d1); + + return Nat224.Eq(c, d1) ? new SecP224R1FieldElement(f1) : null; + } + } - return Nat224.Eq(c, d1) ? new SecP224R1FieldElement(f) : null; + // Avoid any possible infinite loop due to a bad random number generator + SecP224R1Field.AddOne(r, r); + } } public override bool Equals(object obj) @@ -185,27 +192,24 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7); } - private static void RM(uint[] nc, uint[] d0, uint[] e0, uint[] d1, uint[] e1, uint[] f) + private static void RM(uint[] nc, uint[] d0, uint[] e0, uint[] d1, uint[] e1, uint[] f1) { uint[] t = Nat224.Create(); SecP224R1Field.Multiply(e1, e0, t); SecP224R1Field.Multiply(t, nc, t); - SecP224R1Field.Multiply(d1, d0, f); - SecP224R1Field.Add(f, t, f); + SecP224R1Field.Multiply(d1, d0, f1); + SecP224R1Field.Add(f1, t, f1); SecP224R1Field.Multiply(d1, e0, t); - Nat224.Copy(f, d1); + Nat224.Copy(f1, d1); SecP224R1Field.Multiply(e1, d0, e1); SecP224R1Field.Add(e1, t, e1); - SecP224R1Field.Square(e1, f); - SecP224R1Field.Multiply(f, nc, f); + SecP224R1Field.Square(e1, f1); + SecP224R1Field.Multiply(f1, nc, f1); } - private static void RP(uint[] c, uint[] d1, uint[] e1, uint[] f) + private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1) { - uint[] nc = Nat224.Create(); - SecP224R1Field.Negate(c, nc); - - Nat224.Copy(nc, f); + Nat224.Copy(nc, f1); uint[] d0 = Nat224.Create(); uint[] e0 = Nat224.Create(); @@ -218,10 +222,10 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec int j = 1 << i; while (--j >= 0) { - RS(d1, e1, f); + RS(d1, e1, f1); } - RM(nc, d0, e0, d1, e1, f); + RM(nc, d0, e0, d1, e1, f1); } } |