예제 #1
0
 internal void NextK(byte[] k)
 {
     for (;;)
     {
         drbg.GetBytes(k);
         BigInt.RShift(k, (k.Length << 3) - qlen);
         if (!BigInt.IsZero(k) && BigInt.CompareCT(k, q) < 0)
         {
             return;
         }
     }
 }
예제 #2
0
        internal RFC6979(IDigest h, byte[] q, byte[] x,
                         byte[] hv, int hvOff, int hvLen, bool deterministic)
        {
            if (h == null)
            {
                h = new SHA256();
            }
            else
            {
                h = h.Dup();
                h.Reset();
            }
            drbg = new HMAC_DRBG(h);
            mh   = new ModInt(q);
            qlen = mh.ModBitLength;
            int qolen = (qlen + 7) >> 3;

            this.q = new byte[qolen];
            Array.Copy(q, q.Length - qolen, this.q, 0, qolen);
            int hlen = hvLen << 3;

            if (hlen > qlen)
            {
                byte[] htmp = new byte[hvLen];
                Array.Copy(hv, hvOff, htmp, 0, hv.Length);
                BigInt.RShift(htmp, hlen - qlen);
                hv    = htmp;
                hvOff = 0;
            }
            mh.DecodeReduce(hv, hvOff, hvLen);
            ModInt mx = mh.Dup();

            mx.Decode(x);

            byte[] seed = new byte[(qolen << 1) + (deterministic ? 0 : 32)];
            mx.Encode(seed, 0, qolen);
            mh.Encode(seed, qolen, qolen);
            if (!deterministic)
            {
                RNG.GetBytes(seed, qolen << 1,
                             seed.Length - (qolen << 1));
            }
            drbg.SetSeed(seed);
        }
예제 #3
0
        public static bool VerifyRaw(ECPublicKey pk,
                                     byte[] hash, int hashOff, int hashLen,
                                     byte[] sig, int sigOff, int sigLen)
        {
            try {
                /*
                 * Get the curve.
                 */
                ECCurve curve = pk.Curve;

                /*
                 * Get r and s from signature. This also verifies
                 * that they do not exceed the subgroup order.
                 */
                if (sigLen == 0 || (sigLen & 1) != 0)
                {
                    return(false);
                }
                int    tlen = sigLen >> 1;
                ModInt oneQ = new ModInt(curve.SubgroupOrder);
                oneQ.Set(1);
                ModInt r = oneQ.Dup();
                ModInt s = oneQ.Dup();
                r.Decode(sig, sigOff, tlen);
                s.Decode(sig, sigOff + tlen, tlen);

                /*
                 * If either r or s was too large, it got set to
                 * zero. We also don't want real zeros.
                 */
                if (r.IsZero || s.IsZero)
                {
                    return(false);
                }

                /*
                 * Convert the hash value to an integer modulo q.
                 * As per FIPS 186-4, if the hash value is larger
                 * than q, then we keep the qlen leftmost bits of
                 * the hash value.
                 */
                int    qBitLength = oneQ.ModBitLength;
                int    hBitLength = hashLen << 3;
                byte[] hv;
                if (hBitLength <= qBitLength)
                {
                    hv = new byte[hashLen];
                    Array.Copy(hash, hashOff, hv, 0, hashLen);
                }
                else
                {
                    int qlen = (qBitLength + 7) >> 3;
                    hv = new byte[qlen];
                    Array.Copy(hash, hashOff, hv, 0, qlen);
                    int rs = (8 - (qBitLength & 7)) & 7;
                    BigInt.RShift(hv, rs);
                }
                ModInt z = oneQ.Dup();
                z.DecodeReduce(hv);

                /*
                 * Apply the verification algorithm:
                 *   w = 1/s mod q
                 *   u = z*w mod q
                 *   v = r*w mod q
                 *   T = u*G + v*Pub
                 *   test whether T.x mod q == r.
                 */
                /*
                 * w = 1/s mod q
                 */
                ModInt w = s.Dup();
                w.Invert();

                /*
                 * u = z*w mod q
                 */
                w.ToMonty();
                ModInt u = w.Dup();
                u.MontyMul(z);

                /*
                 * v = r*w mod q
                 */
                ModInt v = w.Dup();
                v.MontyMul(r);

                /*
                 * Compute u*G
                 */
                MutableECPoint T    = curve.MakeGenerator();
                uint           good = T.MulSpecCT(u.Encode());

                /*
                 * Compute v*iPub
                 */
                MutableECPoint M = pk.iPub.Dup();
                good &= M.MulSpecCT(v.Encode());

                /*
                 * Compute T = u*G+v*iPub
                 */
                uint nd = T.AddCT(M);
                M.DoubleCT();
                T.Set(M, ~nd);
                good &= ~T.IsInfinityCT;

                /*
                 * Get T.x, reduced modulo q.
                 * Signature is valid if and only if we get
                 * the same value as r (and we did not encounter
                 * an error previously).
                 */
                s.DecodeReduce(T.X);
                return((good & r.EqCT(s)) != 0);
            } catch (CryptoException) {
                /*
                 * Exceptions may occur if the key or signature
                 * have invalid values (non invertible, out of
                 * range...). Any such occurrence means that the
                 * signature is not valid.
                 */
                return(false);
            }
        }