Ejemplo n.º 1
0
        public bool Check(string passphrase, BitcoinAddress expectedAddress)
        {
            //Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
            byte[] passfactor = BitcoinEncryptedSecretEC.CalculatePassFactor(passphrase, LotSequence, OwnerEntropy);
            //Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
            byte[] passpoint = BitcoinEncryptedSecretEC.CalculatePassPoint(passfactor);
            byte[] derived   = BitcoinEncryptedSecretEC.CalculateDecryptionKey(passpoint, AddressHash, OwnerEntropy);

            //Decrypt encryptedpointb to yield pointb
            var pointbprefix = EncryptedPointB[0];

            pointbprefix = (byte)(pointbprefix ^ (byte)(derived[63] & (byte)0x01));

            //Optional since ArithmeticException will catch it, but it saves some times
            if (pointbprefix != 0x02 && pointbprefix != 0x03)
            {
                return(false);
            }
            var pointb = BitcoinEncryptedSecret.DecryptKey(EncryptedPointB.Skip(1).ToArray(), derived);

            pointb = new byte[] { pointbprefix }.Concat(pointb).ToArray();

            //4.ECMultiply pointb by passfactor. Use the resulting EC point as a public key

#if HAS_SPAN
            if (!NBitcoinContext.Instance.TryCreatePubKey(pointb, out var pk) || pk is null)
            {
                return(false);
            }
            PubKey pubkey = new PubKey(pk.TweakMul(passfactor), true);
#else
            var     curve = ECKey.Secp256k1;
            ECPoint pointbec;
            try
            {
                pointbec = curve.Curve.DecodePoint(pointb);
            }
            catch (ArgumentException)
            {
                return(false);
            }
            catch (ArithmeticException)
            {
                return(false);
            }
            PubKey pubkey = new PubKey(pointbec.Multiply(new BigInteger(1, passfactor)).GetEncoded());
#endif
            //and hash it into address using either compressed or uncompressed public key methodology as specifid in flagbyte.
            pubkey = IsCompressed ? pubkey.Compress() : pubkey.Decompress();

            var actualhash   = BitcoinEncryptedSecretEC.HashAddress(pubkey.GetAddress(ScriptPubKeyType.Legacy, Network));
            var expectedhash = BitcoinEncryptedSecretEC.HashAddress(expectedAddress);

            return(Utils.ArrayEqual(actualhash, expectedhash));
        }
        public bool Check(string passphrase, BitcoinAddress expectedAddress)
        {
            //Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
            byte[] passfactor = BitcoinEncryptedSecretEC.CalculatePassFactor(passphrase, this.LotSequence, this.OwnerEntropy);
            //Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
            byte[] passpoint = BitcoinEncryptedSecretEC.CalculatePassPoint(passfactor);
            byte[] derived   = BitcoinEncryptedSecretEC.CalculateDecryptionKey(passpoint, this.AddressHash, this.OwnerEntropy);

            //Decrypt encryptedpointb to yield pointb
            byte pointbprefix = this.EncryptedPointB[0];

            pointbprefix = (byte)(pointbprefix ^ (byte)(derived[63] & (byte)0x01));

            //Optional since ArithmeticException will catch it, but it saves some times
            if (pointbprefix != 0x02 && pointbprefix != 0x03)
            {
                return(false);
            }
            byte[] pointb = BitcoinEncryptedSecret.DecryptKey(this.EncryptedPointB.Skip(1).ToArray(), derived);
            pointb = new byte[] { pointbprefix }.Concat(pointb).ToArray();

            //4.ECMultiply pointb by passfactor. Use the resulting EC point as a public key
            X9ECParameters curve = ECKey.Secp256k1;
            ECPoint        pointbec;

            try
            {
                pointbec = curve.Curve.DecodePoint(pointb);
            }
            catch (ArgumentException)
            {
                return(false);
            }
            catch (ArithmeticException)
            {
                return(false);
            }
            var pubkey = new PubKey(pointbec.Multiply(new BigInteger(1, passfactor)).GetEncoded());

            //and hash it into address using either compressed or uncompressed public key methodology as specifid in flagbyte.
            pubkey = this.IsCompressed ? pubkey.Compress() : pubkey.Decompress();

            byte[] actualhash   = BitcoinEncryptedSecretEC.HashAddress(pubkey.GetAddress(this.Network));
            byte[] expectedhash = BitcoinEncryptedSecretEC.HashAddress(expectedAddress);

            return(Utils.ArrayEqual(actualhash, expectedhash));
        }