// private static BigInteger[] verifyLucasSequence( // BigInteger p, // BigInteger P, // BigInteger Q, // BigInteger k) // { // BigInteger[] actual = fastLucasSequence(p, P, Q, k); // BigInteger[] plus1 = fastLucasSequence(p, P, Q, k.Add(BigInteger.One)); // BigInteger[] plus2 = fastLucasSequence(p, P, Q, k.Add(BigInteger.Two)); // // BigInteger[] check = stepLucasSequence(p, P, Q, actual, plus1); // // Debug.Assert(check[0].Equals(plus2[0])); // Debug.Assert(check[1].Equals(plus2[1])); // // return actual; // } // // private static BigInteger[] stepLucasSequence( // BigInteger p, // BigInteger P, // BigInteger Q, // BigInteger[] backTwo, // BigInteger[] backOne) // { // return new BigInteger[] // { // P.Multiply(backOne[0]).Subtract(Q.Multiply(backTwo[0])).Mod(p), // P.Multiply(backOne[1]).Subtract(Q.Multiply(backTwo[1])).Mod(p) // }; // } public override bool Equals( object obj) { if (obj == this) { return(true); } FpFieldElement other = obj as FpFieldElement; if (other == null) { return(false); } return(Equals(other)); }
protected bool Equals( FpFieldElement other) { return(q.Equals(other.q) && base.Equals(other)); }
// D.1.4 91 /** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public override ECFieldElement Sqrt() { if (!q.TestBit(0)) { throw Platform.CreateNotImplementedException("even value of q"); } // p mod 4 == 3 if (q.TestBit(1)) { // TODO Can this be optimised (inline the Square?) // z = g^(u+1) + p, p = 4u + 3 ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q)); return(z.Square().Equals(this) ? z : null); } // p mod 4 == 1 BigInteger qMinusOne = q.Subtract(BigInteger.One); BigInteger legendreExponent = qMinusOne.ShiftRight(1); if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) { return(null); } BigInteger u = qMinusOne.ShiftRight(2); BigInteger k = u.ShiftLeft(1).Add(BigInteger.One); BigInteger Q = this.x; BigInteger fourQ = Q.ShiftLeft(2).Mod(q); BigInteger U, V; do { Random rand = new Random(); BigInteger P; do { P = new BigInteger(q.BitLength, rand); }while (P.CompareTo(q) >= 0 || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne))); BigInteger[] result = fastLucasSequence(q, P, Q, k); U = result[0]; V = result[1]; if (V.Multiply(V).Mod(q).Equals(fourQ)) { // Integer division by 2, mod q if (V.TestBit(0)) { V = V.Add(q); } V = V.ShiftRight(1); Debug.Assert(V.Multiply(V).Mod(q).Equals(x)); return(new FpFieldElement(q, V)); } }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); // BigInteger qMinusOne = q.Subtract(BigInteger.One); // // BigInteger legendreExponent = qMinusOne.ShiftRight(1); // if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) // return null; // // Random rand = new Random(); // BigInteger fourX = x.ShiftLeft(2); // // BigInteger r; // do // { // r = new BigInteger(q.BitLength, rand); // } // while (r.CompareTo(q) >= 0 // || !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne))); // // BigInteger n1 = qMinusOne.ShiftRight(2); // BigInteger n2 = n1.Add(BigInteger.One); // // BigInteger wOne = WOne(r, x, q); // BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q); // BigInteger twoR = r.ShiftLeft(1); // // BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q) // .Multiply(x).Mod(q) // .Multiply(wSum).Mod(q); // // return new FpFieldElement(q, root); }