Ejemplo n.º 1
0
        public void can_always_recover_pubkey_from_signature_when_stopping_at_null()
        {
            var rand = new Random();

            for (int i = 0; i < 1000; i++)
            {
                var      key   = new Key();
                PosBlock block = new PosBlock(new BlockHeader()
                {
                    Time = (uint)rand.Next()
                });
                ECDSASignature signature = key.Sign(block.GetHash());
                block.BlockSignature = new BlockSignature {
                    Signature = signature.ToDER()
                };
                Assert.True(key.PubKey.Verify(block.GetHash(), new ECDSASignature(block.BlockSignature.Signature)));
                signature = ECDSASignature.FromDER(block.BlockSignature.Signature);
                bool match = false;
                for (int recId = 0; !match; recId++)
                {
                    PubKey pubKeyForSig = PubKey.RecoverFromSignature(recId, signature, block.GetHash(), true);
                    if (pubKeyForSig == null)
                    {
                        break;
                    }

                    match = pubKeyForSig == key.PubKey;
                }
                Assert.True(match);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks if block signature is valid.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns><c>true</c> if the signature is valid, <c>false</c> otherwise.</returns>
        private bool CheckBlockSignature(PosBlock block)
        {
            if (BlockStake.IsProofOfWork(block))
            {
                bool res = block.BlockSignature.IsEmpty();
                this.Logger.LogTrace("(-)[POW]:{0}", res);
                return(res);
            }

            if (block.BlockSignature.IsEmpty())
            {
                this.Logger.LogTrace("(-)[EMPTY]:false");
                return(false);
            }

            TxOut txout = block.Transactions[1].Outputs[1];

            if (PayToPubkeyTemplate.Instance.CheckScriptPubKey(txout.ScriptPubKey))
            {
                PubKey pubKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(txout.ScriptPubKey);
                bool   res    = pubKey.Verify(block.GetHash(), new ECDSASignature(block.BlockSignature.Signature));
                this.Logger.LogTrace("(-)[P2PK]:{0}", res);
                return(res);
            }

            // Block signing key also can be encoded in the nonspendable output.
            // This allows to not pollute UTXO set with useless outputs e.g. in case of multisig staking.

            List <Op> ops = txout.ScriptPubKey.ToOps().ToList();

            if (!ops.Any()) // script.GetOp(pc, opcode, vchPushValue))
            {
                this.Logger.LogTrace("(-)[NO_OPS]:false");
                return(false);
            }

            if (ops.ElementAt(0).Code != OpcodeType.OP_RETURN) // OP_RETURN)
            {
                this.Logger.LogTrace("(-)[NO_OP_RETURN]:false");
                return(false);
            }

            if (ops.Count != 2)
            {
                this.Logger.LogTrace("(-)[INVALID_OP_COUNT]:false");
                return(false);
            }

            byte[] data = ops.ElementAt(1).PushData;

            if (data.Length > MaxPushDataSize)
            {
                this.Logger.LogTrace("(-)[PUSH_DATA_TOO_LARGE]:false");
                return(false);
            }

            if (!ScriptEvaluationContext.IsCompressedOrUncompressedPubKey(data))
            {
                this.Logger.LogTrace("(-)[NO_PUSH_DATA]:false");
                return(false);
            }

            bool verifyRes = new PubKey(data).Verify(block.GetHash(), new ECDSASignature(block.BlockSignature.Signature));

            return(verifyRes);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Checks if block signature is valid.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <returns><c>true</c> if the signature is valid, <c>false</c> otherwise.</returns>
        bool CheckBlockSignature(PosBlock block)
        {
            if (BlockStake.IsProofOfWork(block))
            {
                var res = block.BlockSignature.IsEmpty();
                this.Logger.LogTrace("(-)[POW]:{0}", res);
                return(res);
            }

            var consensusRules = (PosConsensusRuleEngine)this.Parent;

            return(consensusRules.StakeValidator.CheckStakeSignature(block.BlockSignature, block.GetHash(),
                                                                     block.Transactions[1]));
        }