Пример #1
0
        private void InitSigner(BigInteger priv)
        {
            _signer = new ECDSASigner(new HMacDsaKCalculator(new Sha256Digest()));
            ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(priv, Secp256K1.Parameters());

            _signer.Init(true, privKey);
        }
Пример #2
0
        protected void SetVerifier(ECPoint pub)
        {
            Verifier = new ECDsaSigner();
            ECPublicKeyParameters parameters = new ECPublicKeyParameters(
                pub, Secp256K1.Parameters());

            Verifier.Init(false, parameters);
        }
Пример #3
0
        public static byte[] ComputePublicKey(byte[] publicGenBytes, uint accountNumber)
        {
            ECPoint    rootPubPoint = Secp256K1.Curve().DecodePoint(publicGenBytes);
            BigInteger scalar       = ComputeScalar(publicGenBytes, accountNumber);
            ECPoint    point        = Secp256K1.BasePoint().Multiply(scalar);
            ECPoint    offset       = rootPubPoint.Add(point);

            return(offset.GetEncoded(true));
        }
Пример #4
0
        public static BigInteger ComputeSecretKey(
            BigInteger privateGen,
            uint accountNumber)
        {
            ECPoint publicGen = ComputePublicGenerator(privateGen);

            return(ComputeScalar(publicGen.GetEncoded(true), accountNumber)
                   .Add(privateGen).Mod(Secp256K1.Order()));
        }
Пример #5
0
        private EcdsaSignature CreateEcdsaSignature(byte[] hash)
        {
            BigInteger[] sigs = _signer.GenerateSignature(hash);
            var          r    = sigs[0];
            var          s    = sigs[1];

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

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

            return(new EcdsaSignature(r, s));
        }
Пример #6
0
        /// <param name="seedBytes"> - a bytes sequence of arbitrary length which will be hashed </param>
        /// <param name="discriminator"> - nullable optional uint32 to hash </param>
        /// <returns> a number between [1, order -1] suitable as a private key
        ///  </returns>
        public static BigInteger ComputeScalar(byte[] seedBytes, uint?discriminator)
        {
            BigInteger key = null;

            for (uint i = 0; i <= 0xFFFFFFFFL; i++)
            {
                var sha512 = new Sha512(seedBytes);
                if (discriminator != null)
                {
                    sha512.AddU32(discriminator.Value);
                }
                sha512.AddU32(i);
                byte[] keyBytes = sha512.Finish256();
                key = Misc.UBigInt(keyBytes);
                if (key.CompareTo(BigInteger.Zero) == 1 &&
                    key.CompareTo(Secp256K1.Order()) == -1)
                {
                    break;
                }
            }
            return(key);
        }
Пример #7
0
 ///
 /// <param name="secretKey"> secret point on the curve as BigInteger </param>
 /// <returns> corresponding public point </returns>
 public static ECPoint ComputePublicKey(BigInteger secretKey)
 {
     return(Secp256K1.BasePoint().Multiply(secretKey));
 }
        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
            int rPos = 4, 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
            }

            byte[] rBytes = new byte[rLen];
            byte[] bytes  = new byte[sLen];

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

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

            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);
            }
            else
            {
                return(true);
            }
        }