diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-24 15:07:59 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-24 15:07:59 +0700 |
commit | 4c690460459e4aef32982893bb6394c6d9ecd5f0 (patch) | |
tree | 42b5f4eb5f85a022af9240c4f2ed620da45febd4 /crypto/src/math/ec | |
parent | Fix return type in SubFromExt (diff) | |
download | BouncyCastle.NET-ed25519-4c690460459e4aef32982893bb6394c6d9ecd5f0.tar.xz |
Track carries for a, b to avoid unnecessary add/sub of prime modulus
Diffstat (limited to 'crypto/src/math/ec')
-rw-r--r-- | crypto/src/math/ec/Mod.cs | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/crypto/src/math/ec/Mod.cs b/crypto/src/math/ec/Mod.cs index 465aa5e41..bfb2faea4 100644 --- a/crypto/src/math/ec/Mod.cs +++ b/crypto/src/math/ec/Mod.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Org.BouncyCastle.Utilities; @@ -9,6 +10,8 @@ namespace Org.BouncyCastle.Math.EC public static void Invert(uint[] p, uint[] x, uint[] z) { int len = p.Length; + if (Nat.IsZero(len, x)) + throw new ArgumentException("cannot be 0", "x"); if (Nat.IsOne(len, x)) { Array.Copy(x, 0, z, 0, len); @@ -18,19 +21,21 @@ namespace Org.BouncyCastle.Math.EC uint[] u = Nat.Copy(len, x); uint[] a = Nat.Create(len); a[0] = 1; + int ac = 0; if ((u[0] & 1) == 0) { - InversionStep(p, u, len, a); + InversionStep(p, u, len, a, ref ac); } if (Nat.IsOne(len, u)) { - Array.Copy(a, 0, z, 0, len); + InversionResult(p, ac, a, z); return; } uint[] v = Nat.Copy(len, p); uint[] b = Nat.Create(len); + int bc = 0; int uvLen = len; @@ -43,29 +48,25 @@ namespace Org.BouncyCastle.Math.EC if (Nat.Gte(len, u, v)) { - Subtract(p, a, b, a); Nat.Sub(len, u, v, u); - if ((u[0] & 1) == 0) - { - InversionStep(p, u, uvLen, a); - } + Debug.Assert((u[0] & 1) == 0); + ac += Nat.Sub(len, a, b, a) - bc; + InversionStep(p, u, uvLen, a, ref ac); if (Nat.IsOne(len, u)) { - Array.Copy(a, 0, z, 0, len); + InversionResult(p, ac, a, z); return; } } else { - Subtract(p, b, a, b); Nat.Sub(len, v, u, v); - if ((v[0] & 1) == 0) - { - InversionStep(p, v, uvLen, b); - } + Debug.Assert((v[0] & 1) == 0); + bc += Nat.Sub(len, b, a, b) - ac; + InversionStep(p, v, uvLen, b, ref bc); if (Nat.IsOne(len, v)) { - Array.Copy(b, 0, z, 0, len); + InversionResult(p, bc, b, z); return; } } @@ -82,7 +83,19 @@ namespace Org.BouncyCastle.Math.EC } } - private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x) + private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z) + { + if (ac < 0) + { + Nat.Add(p.Length, a, p, z); + } + else + { + Array.Copy(a, 0, z, 0, p.Length); + } + } + + private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc) { int len = p.Length; int count = 0; @@ -103,8 +116,20 @@ namespace Org.BouncyCastle.Math.EC for (int i = 0; i < count; ++i) { - uint c = (x[0] & 1) == 0 ? 0 : Nat.Add(len, x, p, x); - Nat.ShiftDownBit(x, len, c); + if ((x[0] & 1) != 0) + { + if (xc < 0) + { + xc += (int)Nat.Add(len, x, p, x); + } + else + { + xc += Nat.Sub(len, x, p, x); + } + } + + Debug.Assert(xc == 0 || xc == -1); + Nat.ShiftDownBit(x, len, (uint)xc); } } |