Esempio n. 1
0
        private BigInteger Sqrt(BigInteger x, AnyRng rng)
        {
            if (!IsQuadraticResidue(x))
            {
                throw new InvalidOperationException();
            }

            BigInteger z;

            do
            {
                z = rng.NextBigInt(BigInteger.One, P);
            } while (IsQuadraticResidue(z));

            var   q = _eulerPower;
            ulong s = 1;

            while (q.IsEven)
            {
                s++;
                q /= 2;
            }

            var m = s;
            var c = BigInteger.ModPow(z, q, P);
            var t = BigInteger.ModPow(x, q, P);
            var r = BigInteger.ModPow(x, q / 2 + 1, P);

            while (true)
            {
                if (t.IsZero)
                {
                    return(BigInteger.Zero);
                }
                if (t.IsOne)
                {
                    return(r);
                }
                ulong i = 1;
                while (i < m)
                {
                    if (BigInteger.ModPow(t, BigInteger.ModPow(2, i, P), P).IsOne)
                    {
                        break;
                    }
                    i++;
                }

                if (i == m)
                {
                    throw new InvalidOperationException();
                }

                var b = BigInteger.ModPow(c, BigInteger.ModPow(2, m - i - 1, P), P);
                m = i;
                c = b * b % P;
                t = t * b * b % P;
                r = r * b % P;
            }
        }
Esempio n. 2
0
        public JacobianEcPoint Multiply(BigInteger k, JacobianEcPoint p, AnyRng rng)
        {
            if (k.Sign < 0)
            {
                k = -k;
                p = Negate(p);
            }

            if (k.IsZero)
            {
                return(JacobianEcPoint.Infinity);
            }
            if (k.IsOne)
            {
                return(p);
            }

            var ks = rng.NextBigInt(BigInteger.One, k);

            // return MultiplyAndAdd(ks, p, k - ks, p, rng);
            var(k1, k2) = ToNafBytes(k - ks, ks);
            var i = 0;

            while (i < k1.Length - 1)
            {
                var c = k1[i].NafValue() + k2[i].NafValue();
                if (c != 0)
                {
                    i++;
                    continue;
                }

                if (k2[i + 1].NafValue() > 0)
                {
                    k2[i + 1] = (byte)((k2[i + 1].H() << 4) | ((k2[i + 1].L() - 1) & 0xF));
                    k2[i]     = (byte)(((k2[i].H() + 2) << 4) | (k2[i].L() & 0xF));
                }
                else
                {
                    k2[i + 1] = (byte)((k2[i + 1].H() << 4) | ((k2[i + 1].L() + 1) & 0xF));
                    k2[i]     = (byte)(((k2[i].H() - 2) << 4) | (k2[i].L() & 0xF));
                }
            }

            var lut = new [] {
                JacobianEcPoint.Infinity,
                p,
                Double(p),
                Add(Double(p), p),
                Double(Double(p))
            };

            var r = lut[k1.Back().NafValue() + k2.Back().NafValue()];

            for (i = k1.Length - 2; i >= 0; i--)
            {
                var c = k1[i].NafValue() + k2[i].NafValue();
                r = Add(Double(Double(r)), c < 0 ? Negate(lut[-c]) : lut[c]);
            }

            return(r);
        }