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); return; } 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, ref ac); } if (Nat.IsOne(len, u)) { InversionResult(p, ac, a, z); return; } uint[] v = Nat.Copy(len, p); uint[] b = Nat.Create(len); int bc = 0; int uvLen = len; for (;;) { while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0) { --uvLen; } if (Nat.Gte(len, u, v)) { Nat.SubFrom(len, v, u); Debug.Assert((u[0] & 1) == 0); ac += Nat.SubFrom(len, b, a) - bc; InversionStep(p, u, uvLen, a, ref ac); if (Nat.IsOne(len, u)) { InversionResult(p, ac, a, z); return; } } else { Nat.SubFrom(len, u, v); Debug.Assert((v[0] & 1) == 0); bc += Nat.SubFrom(len, a, b) - ac; InversionStep(p, v, uvLen, b, ref bc); if (Nat.IsOne(len, v)) { InversionResult(p, bc, b, z); return; } } } }