Beispiel #1
0
        public static bool Verify(byte[] data, byte[] sigBytes, BigInteger pub)
        {
            EcdsaSignature signature  = EcdsaSignature.DecodeFromDer(sigBytes);
            var            signer     = new ECDsaSigner();
            ECPoint        pubPoint   = Secp256K1.Curve().DecodePoint(pub.ToByteArray());
            var            parameters = new ECPublicKeyParameters(pubPoint, Secp256K1.Params());

            signer.Init(false, parameters);
            try
            {
                return(signer.VerifySignature(data, signature.R, signature.S));
            }
            catch (Exception)
            {
                return(false);
            }
        }
Beispiel #2
0
        private static EcdsaSignature CreateEcdsaSignature(byte[] bytes, BigInteger secret)
        {
            var signer  = new ECDsaSigner();
            var privKey = new ECPrivateKeyParameters(secret, Secp256K1.Params());

            signer.Init(true, privKey);
            BigInteger[] sigs = signer.GenerateSignature(bytes);
            BigInteger   r = sigs[0], s = sigs[1];

            BigInteger otherS = Secp256K1.Order().Subtract(s);

            if (s.CompareTo(otherS) == 1)
            {
                s = otherS;
            }

            return(new EcdsaSignature(r, s));
        }
Beispiel #3
0
        public static IKeyPair CreateKeyPair(byte[] seedBytes)
        {
            BigInteger secret, pub, privateGen, order = Secp256K1.Order();

            byte[] privateGetBytes;
            byte[] publicGetBytes;

            int i = 0, seq = 0;

            while (true)
            {
                privateGetBytes = HashedIncrement(seedBytes, i++);
                privateGen      = Utils.Utils.UBigInt(privateGetBytes);
                if (privateGen.CompareTo(order) == -1)
                {
                    break;
                }
            }

            publicGetBytes = Secp256K1.BasePointMultipliedBy(privateGen);

            i = 0;
            while (true)
            {
                byte[] secretBytes = HashedIncrement(AppendIntBytes(publicGetBytes, seq), i++);
                secret = Utils.Utils.UBigInt(secretBytes);
                if (secret.CompareTo(order) == -1)
                {
                    break;
                }
            }

            secret = secret.Add(privateGen).Mod(order);
            pub    = Utils.Utils.UBigInt(Secp256K1.BasePointMultipliedBy(secret));

            return(new KeyPair(secret, pub));
        }
Beispiel #4
0
        public static bool CheckIsCanonical(byte[] sig, bool strict)
        {
            // Make sure signature is canonical
            // To protect against signature morphing attacks

            // Signature should be:
            // <30> <len> [ <02> <lenR> <R> ] [ <02> <lenS> <S> ]
            // where
            // 6 <= len <= 70
            // 1 <= lenR <= 33
            // 1 <= lenS <= 33

            int sigLen = sig.Length;

            if ((sigLen < 8) || (sigLen > 72))
            {
                return(false);
            }

            if ((sig[0] != 0x30) || (sig[1] != (sigLen - 2)))
            {
                return(false);
            }

            // Find R and check its length
            const int rPos = 4;
            int       rLen = sig[rPos - 1];

            if ((rLen < 1) || (rLen > 33) || ((rLen + 7) > sigLen))
            {
                return(false);
            }

            // Find S and check its length
            int sPos = rLen + 6, sLen = sig[sPos - 1];

            if ((sLen < 1) || (sLen > 33) || ((rLen + sLen + 6) != sigLen))
            {
                return(false);
            }

            if ((sig[rPos - 2] != 0x02) || (sig[sPos - 2] != 0x02))
            {
                return(false); // R or S have wrong type
            }
            if ((sig[rPos] & 0x80) != 0)
            {
                return(false); // R is negative
            }
            if ((sig[rPos] == 0) && rLen == 1)
            {
                return(false); // R is zero
            }
            if ((sig[rPos] == 0) && ((sig[rPos + 1] & 0x80) == 0))
            {
                return(false); // R is padded
            }
            if ((sig[sPos] & 0x80) != 0)
            {
                return(false); // S is negative
            }
            if ((sig[sPos] == 0) && sLen == 1)
            {
                return(false); // S is zero
            }
            if ((sig[sPos] == 0) && ((sig[sPos + 1] & 0x80) == 0))
            {
                return(false); // S is padded
            }
            var rBytes = new byte[rLen];
            var sBytes = new byte[sLen];

            Array.Copy(sig, rPos, rBytes, 0, rLen);
            Array.Copy(sig, sPos, sBytes, 0, sLen);

            BigInteger r = new BigInteger(1, rBytes), s = new BigInteger(1, sBytes);

            BigInteger order = Secp256K1.Order();

            if (r.CompareTo(order) != -1 || s.CompareTo(order) != -1)
            {
                return(false); // R or S greater than modulus
            }

            if (strict)
            {
                return(order.Subtract(s).CompareTo(s) != -1);
            }

            return(true);
        }