示例#1
0
        /// Verify the transaction proof validity. Entails handling the commitment
        /// as a public key and checking the signature verifies with the fee as
        /// message.
        public void Verify(Secp256K1 secp)
        {
            var msg = Message.from_slice(TransactionHelper.kernel_sig_msg(Fee, LockHeight));
            var sig = Signiture.from_der(secp, ExcessSig);

            secp.verify_from_commit(msg, sig, Excess);
        }
示例#2
0
        /// The verification for a MimbleWimble transaction involves getting the
        /// excess of summing all commitments and using it as a public key
        /// to verify the embedded signature. The rational is that if the values
        /// sum to zero as they should in r.G + v.H then only k.G the excess
        /// of the sum of r.G should be left. And r.G is the definition of a
        /// public key generated using r as a private key.
        public TxKernel verify_sig(Secp256K1 secp)

        {
            var rsum = this.sum_commitments(secp);

            var msg = Message.from_slice(TransactionHelper.kernel_sig_msg(Fee, LockHeight));
            var sig = Signiture.from_der(secp, ExcessSig);

            // pretend the sum is a public key (which it is, being of the form r.G) and
            // verify the transaction sig with it
            //
            // we originally converted the commitment to a key_id here (commitment to zero)
            // and then passed the key_id to secp.verify()
            // the secp api no longer allows us to do this so we have wrapped the complexity
            // of generating a public key from a commitment behind verify_from_commit

            secp.verify_from_commit(msg, sig, rsum);

            var kernel = new TxKernel
            {
                Features   = KernelFeatures.DefaultKernel,
                Excess     = rsum,
                ExcessSig  = ExcessSig,
                Fee        = Fee,
                LockHeight = LockHeight
            };

            Log.Debug(
                "tx verify_sig: fee - {fee}, lock_height - {lock_height}",
                kernel.Fee,
                kernel.LockHeight
                );

            return(kernel);
        }
示例#3
0
        private static void Check_lax_sig(string expr)
        {
            var secp     = Secp256K1.WithoutCaps();
            var sigBytes = HexUtil.from_hex(expr);
            var sig      = Signiture.from_der/*_lax*/ (secp, sigBytes);

            Assert.NotEmpty(sig.Value);
        }
示例#4
0
        /// <summary>
        /// Resolves the parameter indicated by the <paramref name="sequence"/> to it's defining type.
        /// </summary>
        /// <param name="sequence">The sequence in the parameter list.</param>
        /// <returns>Null if it could not be resolved otherwise the TypeRef for the parameter.</returns>
        public TypeRef ResolveParameter(int sequence)
        {
            TypeRef resolvedType = null;

            // zero indicates the return parameter for a method, this is handled differently
            if (sequence != 0)
            {
                ParamSignatureToken token = Signiture.GetParameterTokens()[sequence - 1];
                return(token.ResolveParameter(Assembly, Parameters[sequence - 1]));
            }

            return(resolvedType);
        }
示例#5
0
        public void Test_bad_slice()
        {
            var s = Secp256K1.New();

            var ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, new byte[Constants.Constants.MaxSignatureSize + 1]); });

            Assert.Equal("InvalidSignature", ex.Message);

            ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, new byte[Constants.Constants.MaxSignatureSize]); });
            Assert.Equal("InvalidSignature", ex.Message);

            ex = Assert.Throws <Exception>(() => { Message.from_slice(new byte[Constants.Constants.MessageSize - 1]); });
            Assert.Equal("InvalidMessage", ex.Message);

            ex = Assert.Throws <Exception>(() => { Message.from_slice(new byte[Constants.Constants.MessageSize + 1]); });
            Assert.Equal("InvalidMessage", ex.Message);

            Message.from_slice(new byte[Constants.Constants.MessageSize]);
        }
示例#6
0
        public void Signature_serialize_roundtrip()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());


            for (var i = 0; i <= 100; i++)
            {
                var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
                var msg      = Message.from_slice(msgBytes);

                var kp = s.generate_keypair(RandomNumberGenerator.Create());
                var sk = kp.secretKey;

                var sig1 = s.Sign(msg, sk);
                var der  = sig1.serialize_der(s);
                var sig2 = Signiture.from_der(s, der);
                Assert.Equal(sig1.Value, sig2.Value);

                var compact = sig1.serialize_compact(s);
                var sig3    = Signiture.from_compact(s, compact);

                Assert.Equal(sig1.Value, sig3.Value);

                //round_trip_serde!(sig1);

                var ex = Assert.Throws <Exception>(() => { Signiture.from_compact(s, der); });
                Assert.Equal("InvalidSignature", ex.Message);

                ex = Assert.Throws <Exception>(() => { Signiture.from_compact(s, compact.Take(5).ToArray()); });
                Assert.Equal("InvalidSignature", ex.Message);


                ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, compact); });
                Assert.Equal("InvalidSignature", ex.Message);


                ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, der.Take(5).ToArray()); });
                Assert.Equal("InvalidSignature", ex.Message);
            }
        }
示例#7
0
        public void Test_low_s()
        {
            // nb this is a transaction on testnet
            // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9
            // input number 3
            var sigBytes = HexUtil.from_hex("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
            var pkBytes  = HexUtil.from_hex("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
            var msgBytes = HexUtil.from_hex("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");

            var secp = Secp256K1.New();
            var sig  = Signiture.from_der(secp, sigBytes);
            var pk   = PublicKey.from_slice(secp, pkBytes);
            var msg  = Message.from_slice(msgBytes);

            // without normalization we expect this will fail
            var ex = Assert.Throws <Exception>(() => { secp.Verify(msg, sig, pk); });

            Assert.Equal("IncorrectSignature", ex.Message);
            // after normalization it should pass
            sig.normalize_s(secp);
            secp.Verify(msg, sig, pk);
        }
示例#8
0
        /// *** This is a temporary work-around. ***
        /// We do not know which of the two possible public keys from the commit to use,
        /// so here we try both of them and succeed if either works.
        /// This is sub-optimal in terms of performance.
        /// I believe apoelstra has a strategy for fixing this in the secp256k1-zkp lib.
        public static void verify_from_commit(this Secp256K1 self, Message msg, Signiture sig, Commitment commit)
        {
            if (self.Caps != ContextFlag.Commit)
            {
                throw new Exception("IncapableContext");
            }

            // If we knew which one we cared about here we would just use it,
            // but for now return both so we can try them both.
            var pubkeys = commit.to_two_pubkeys(self);

            // Attempt to verify with the first public key,
            // if verify fails try the other one.
            // The first will fail on average 50% of the time.

            try
            {
                self.Verify(msg, sig, pubkeys[0]);
            }
            catch (Exception)
            {
                self.Verify(msg, sig, pubkeys[1]);
            }
        }