コード例 #1
0
ファイル: ECDsa.cs プロジェクト: wuqionglei/IceWallet
        public BigInteger[] GenerateSignature(byte[] message)
        {
            if (privateKey == null)
            {
                throw new InvalidOperationException();
            }
            BigInteger e = CalculateE(curve.N, message);
            BigInteger d = new BigInteger(privateKey.Reverse().Concat(new byte[1]).ToArray());
            BigInteger r, s;

            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {
                do
                {
                    BigInteger k;
                    do
                    {
                        do
                        {
                            k = rng.NextBigInteger(curve.N.GetBitLength());
                        }while (k.Sign == 0 || k.CompareTo(curve.N) >= 0);
                        ECPoint    p = ECPoint.Multiply(curve.G, k);
                        BigInteger x = p.X.Value;
                        r = x.Mod(curve.N);
                    }while (r.Sign == 0);
                    s = (k.ModInverse(curve.N) * (e + d * r)).Mod(curve.N);
                    if (s > curve.N / 2)
                    {
                        s = curve.N - s;
                    }
                }while (s.Sign == 0);
            }
            return(new BigInteger[] { r, s });
        }
コード例 #2
0
        public ECFieldElement Sqrt()
        {
            if (curve.Q.TestBit(1))
            {
                ECFieldElement z = new ECFieldElement(BigInteger.ModPow(Value, (curve.Q >> 2) + 1, curve.Q), curve);
                return(z.Square().Equals(this) ? z : null);
            }
            BigInteger qMinusOne        = curve.Q - 1;
            BigInteger legendreExponent = qMinusOne >> 1;

            if (BigInteger.ModPow(Value, legendreExponent, curve.Q) != 1)
            {
                return(null);
            }
            BigInteger u = qMinusOne >> 2;
            BigInteger k = (u << 1) + 1;
            BigInteger Q = this.Value;
            BigInteger fourQ = (Q << 2).Mod(curve.Q);
            BigInteger U, V;

            do
            {
                BigInteger P;
                do
                {
                    using (var rng = new RNGCryptoServiceProvider())
                        P = rng.NextBigInteger(curve.Q.GetBitLength());
                }while (P >= curve.Q || BigInteger.ModPow(P * P - fourQ, legendreExponent, curve.Q) != qMinusOne);
                BigInteger[] result = FastLucasSequence(curve.Q, P, Q, k);
                U = result[0];
                V = result[1];
                if ((V * V).Mod(curve.Q) == fourQ)
                {
                    if (V.TestBit(0))
                    {
                        V += curve.Q;
                    }
                    V >>= 1;
                    Debug.Assert((V * V).Mod(curve.Q) == Value);
                    return(new ECFieldElement(V, curve));
                }
            }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
            return(null);
        }