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
 internal SM2KeyExchange(AnyRng rng, HashAlgorithm hash, byte[] zValue, BigInteger privateKey, bool responder, EcKeyPair ephemeralKey)
 {
     _rng          = rng;
     _ephemeralKey = ephemeralKey;
     _hash         = hash;
     _privateKey   = privateKey;
     _zValue       = zValue;
     _responder    = responder;
 }
Esempio n. 3
0
        private SM2(IEcParameter param, HashAlgorithm hash, AnyRng rng)
        {
#if NETSTANDARD2_0 || NETSTANDARD2_1
            if (!hash.CanReuseTransform || !hash.CanTransformMultipleBlocks || hash.InputBlockSize != 1)
            {
                throw new ArgumentException(nameof(hash));
            }
#endif

            _rng   = rng;
            _hash  = hash;
            _param = param;
            _ident = Array.Empty <byte>();
        }
Esempio n. 4
0
        public BigInteger SolveY(BigInteger x, bool lsbSet, AnyRng rng)
        {
            var rhs = x * x * x + A * x + B;

            rhs %= P;
            var r = Sqrt(rhs, rng);

            if (r.IsZero)
            {
                return(r);
            }
            if (lsbSet == r.IsEven)
            {
                r = P - r;
            }
            return(r);
        }
Esempio n. 5
0
 public static SM2 Create(HashAlgorithm hash, AnyRng rng) => new SM2(FpParameter.SM2StandardParam, hash, rng);
Esempio n. 6
0
 public static SM2 Create(AnyRng rng) => Create(new SM3(), rng);
Esempio n. 7
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);
        }
Esempio n. 8
0
        public JacobianEcPoint MultiplyAndAdd(BigInteger k, JacobianEcPoint p, BigInteger m, JacobianEcPoint s, AnyRng rng)
        {
            if (k.Sign < 0)
            {
                k = -k;
                p = Negate(p);
            }
            if (m.Sign < 0)
            {
                m = -m;
                s = Negate(s);
            }

            if (k.IsZero)
            {
                return(Multiply(m, s, rng));
            }
            if (m.IsZero)
            {
                return(Multiply(k, p, rng));
            }
            if (k.IsOne)
            {
                return(Add(p, Multiply(m, s, rng)));
            }
            if (m.IsOne)
            {
                return(Add(s, Multiply(k, p, rng)));
            }

            var(kk, mm) = ToNafBytes(k, m);
            var i = 0;

            while (i < kk.Length - 1)
            {
                if (kk[i] != 0 || mm[i] != 0)
                {
                    i++;
                    continue;
                }

                switch (mm[i + 1])
                {
                case 0:
                    mm[i + 1] = 0x01;
                    mm[i]     = 0xE0;
                    break;

                case 0x0F:
                    mm[i + 1] = 0xF0;
                    mm[i]     = 0x20;
                    break;

                case 0x01:
                    mm[i + 1] = 0x10;
                    mm[i]     = 0xE0;
                    break;

                case 0xF0:
                    mm[i + 1] = 0x0F;
                    mm[i]     = 0xE0;
                    break;

                case 0x10:
                    mm[i + 1] = 0x01;
                    mm[i]     = 0x20;
                    break;

                default:
                    throw new Exception();
                }
            }

            var lut = new [] { // T[x,y] = lut[7x+y-1]
                s, Double(s), JacobianEcPoint.Infinity, Double(Double(s)),
                Add(p, Negate(Double(s))), Add(p, Negate(s)), p, Add(p, s), Add(p, Double(s)),
                JacobianEcPoint.Infinity, JacobianEcPoint.Infinity,
                Add(Double(p), Negate(Double(s))), Add(Double(p), Negate(s)),
                Double(p), Add(Double(p), s), Add(Double(p), Double(s))
            };

            var r = lut[kk.Back().NafValue() * 7 + mm.Back().NafValue() - 1];

            for (i = kk.Length - 2; i >= 0; i--)
            {
                r = Double(Double(r));
                if (kk[i] == 0)
                {
                    if (mm[i].NafValue() < 0)
                    {
                        r = Add(r, Negate(lut[-mm[i].NafValue() - 1]));
                    }
                    else
                    {
                        r = Add(r, lut[mm[i].NafValue() - 1]);
                    }
                }
                else if (kk[i].NafValue() < 0)
                {
                    r = Add(r, Negate(lut[-kk[i].NafValue() * 7 - mm[i].NafValue() - 1]));
                }
                else
                {
                    r = Add(r, lut[kk[i].NafValue() * 7 + mm[i].NafValue() - 1]);
                }
            }

            return(r);
        }