Пример #1
0
        /// <summary>
        /// Impplements Cipolla's algorithm
        /// </summary>
        /// <param name="N"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public static BigInteger ModSqrt(BigInteger N, BigInteger p)
        {
            BigInteger a  = 0,
                       w2 = 0;
            BigInteger ls = 0;

            // Pick up any value 'a' such that 'w^2 = a^2 - N' is a non-quadratic
            // residue in Fp
            do
            {
                ++a;
                w2 = (a * a + p - N) % p;
                ls = LS(w2, p);
            } while (ls != p - 1);

            // In Fp^2, compute '(a + w)^((p + 1)/2) (mod p)'
            var r = new Fp2Point(1, 0);
            var s = new Fp2Point(a, 1);

            for (var n = (p + 1) / 2 % p; n > 0; n >>= 1)
            {
                if (!n.IsEven)
                {
                    r = Fp2Point.Mul(r, s, p, w2);
                }
                s = Fp2Point.Mul(s, s, p, w2);
            }

            // Check for errors
            if (r.x * r.x % p != N)
            {
                return(0);
            }
            if (r.y != 0)
            {
                return(0);
            }

            return(r.x);
        } // ModSqrt
Пример #2
0
 internal static Fp2Point Mul(Fp2Point a, Fp2Point b,
                              BigInteger p, BigInteger w2)
 {
     return(new Fp2Point((a.x * b.x + a.y * b.y * w2) % p,
                         (a.x * b.y + b.x * a.y) % p));
 }