Exemplo n.º 1
0
        public void Test_verify_commit_sum_one_keys()
        {
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            Commitment Commit(ulong value, SecretKey blinding)
            {
                return(secp.Commit(value, blinding));
            }

            Assert.True(secp.verify_commit_sum(
                            new[] { Commit(5, SecretKey.OneKey) },
                            new[] { Commit(5, SecretKey.OneKey) }
                            ));

            //// we expect this not to verify
            //// even though the values add up to 0
            //// the keys themselves do not add to 0

            Assert.False(secp.verify_commit_sum(
                             new[] { Commit(3, SecretKey.OneKey), Commit(2, SecretKey.OneKey) },
                             new[] { Commit(5, SecretKey.OneKey) }));


            //// to get these to verify we need to
            //// use the same "sum" of blinding factors on both sides

            var twoKey = secp.blind_sum(new [] { SecretKey.OneKey, SecretKey.OneKey }, new SecretKey[] {});

            Assert.True(secp.verify_commit_sum(
                            new[] { Commit(3, SecretKey.OneKey), Commit(2, SecretKey.OneKey) },
                            new[] { Commit(5, twoKey) }));
        }
Exemplo n.º 2
0
        public void Test_commit_sum()
        {
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            Commitment Commit(ulong value, SecretKey blinding)
            {
                return(secp.Commit(value, blinding));
            }

            var blindA = SecretKey.New(secp, RandomNumberGenerator.Create());
            var blindB = SecretKey.New(secp, RandomNumberGenerator.Create());

            var commitA = Commit(3, blindA);
            var commitB = Commit(2, blindB);

            var blindC = secp.blind_sum(new [] { blindA, blindB }, new SecretKey[] {});

            var commitC = Commit(3 + 2, blindC);

            var commitD = secp.commit_sum(new[] { commitA, commitB }, new Commitment[] { });

            Assert.Equal(commitC.Value, commitD.Value);

            var blindE = secp.blind_sum(new[] { blindA }, new[] { blindB });

            var commitE = Commit(3 - 2, blindE);

            var commitF = secp.commit_sum(new[] { commitA }, new[] { commitB });

            Assert.Equal(commitE.Value, commitF.Value);
        }
Exemplo n.º 3
0
        public void Test_sign_with_pubkey_from_commitment()
        {
            var secp     = Secp256K1.WithCaps(ContextFlag.Commit);
            var blinding = SecretKey.New(secp, RandomNumberGenerator.Create());
            var commit   = secp.Commit(0, blinding);

            var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);

            var msg = Message.from_slice(msgBytes);

            var sig = secp.Sign(msg, blinding);

            var pubkeys = commit.to_two_pubkeys(secp);

            // check that we can successfully verify the signature with one of the public keys

            try
            {
                secp.Verify(msg, sig, pubkeys[0]);
            }
            catch (Exception)
            {
                try
                {
                    secp.Verify(msg, sig, pubkeys[1]);
                }
                catch (Exception ex)
                {
                    throw new Exception("this is not good", ex);
                }
            }
        }
Exemplo n.º 4
0
        public void Test_verify_commit_sum_zero_keys()
        {
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            Commitment Commit(ulong value)
            {
                var blinding = SecretKey.ZeroKey;

                return(secp.Commit(value, blinding));
            }

            Assert.True(secp.verify_commit_sum(
                            new Commitment[] {},
                            new Commitment[] { }
                            ));

            Assert.True(secp.verify_commit_sum(
                            new[] { Commit(5) },
                            new[] { Commit(5) }));

            Assert.True(secp.verify_commit_sum(
                            new[] { Commit(3), Commit(2) },
                            new[] { Commit(5) }
                            ));

            Assert.True(secp.verify_commit_sum(
                            new[] { Commit(2), Commit(4) },
                            new[] { Commit(1), Commit(5) }
                            ));
        }
Exemplo n.º 5
0
        public void Test_to_two_pubkeys()
        {
            var secp     = Secp256K1.WithCaps(ContextFlag.Commit);
            var blinding = SecretKey.New(secp, RandomNumberGenerator.Create());
            var commit   = secp.Commit(5, blinding);

            Assert.Equal(2, commit.to_two_pubkeys(secp).Length);
        }
Exemplo n.º 6
0
        // to_pubkey() is not currently working as secp does currently
        // provide an api to extract a public key from a commitment
        public void test_to_pubkey()
        {
            var secp     = Secp256K1.WithCaps(ContextFlag.Commit);
            var blinding = SecretKey.New(secp, RandomNumberGenerator.Create());
            var commit   = secp.Commit(5, blinding);

            Assert.Throws <Exception>(() =>
            {
                commit.to_pubkey(secp);
            });
        }
Exemplo n.º 7
0
        public static Keychain From_seed(byte[] seed)
        {
            var secp     = Secp256K1.WithCaps(ContextFlag.Commit);
            var extkey   = ExtendedKey.from_seed(secp, seed);
            var keychain = new Keychain(
                secp,
                extkey,
                new Dictionary <string, SecretKey>(), new ConcurrentDictionary <string, uint>())
            ;

            return(keychain);
        }
Exemplo n.º 8
0
        /// Builds a new block ready to mine from the header of the previous block,
        /// a vector of transactions and the reward information. Checks
        /// that all transactions are valid and calculates the Merkle tree.
        public static Block with_reward(BlockHeader prev, Transaction.Transaction[] txs, Output rewardOut,
                                        TxKernel rewardKern)
        {
            // note: the following reads easily but may not be the most efficient due to
            // repeated iterations, revisit if a problem
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            // validate each transaction and gather their kernels

            var kernels = txs.Select(tx => tx.verify_sig(secp)).ToList();

            kernels.Add(rewardKern);

            // build vectors with all inputs and all outputs, ordering them by hash
            // needs to be a fold so we don't end up with a vector of vectors and we
            // want to fully own the refs (not just a pointer like flat_map).

            var inputs  = new List <Input>();
            var outputs = new List <Output>();

            foreach (var tx in txs)
            {
                inputs.AddRange(tx.Inputs.Select(i => i.Clone()));

                outputs.AddRange(tx.Outputs.Select(o => o.Clone()));
            }

            outputs.Add(rewardOut);

            // calculate the overall Merkle tree and fees

            var bh = BlockHeader.Default();

            bh.Height    = prev.Height + 1;
            bh.Previous  = prev.Hash();
            bh.Timestamp = DateTime.UtcNow;

            bh.TotalDifficulty =
                Difficulty.From_num(prev.Pow.Clone().To_difficulty().Num + prev.TotalDifficulty.Clone().Num);

            var b = new Block
            {
                Header  = bh,
                Inputs  = inputs.ToArray(),
                Outputs = outputs.ToArray(),
                Kernels = kernels.ToArray()
            };

            return(b.Compact());
        }
Exemplo n.º 9
0
        public void Ecdh()
        {
            var s = Secp256K1.WithCaps(ContextFlag.SignOnly);

            var(sk1, pk1) = s.generate_keypair(RandomNumberGenerator.Create());
            var(sk2, pk2) = s.generate_keypair(RandomNumberGenerator.Create());

            var sec1   = SharedSecret.New(s, pk1, sk2);
            var sec2   = SharedSecret.New(s, pk2, sk1);
            var secOdd = SharedSecret.New(s, pk1, sk1);

            Assert.Equal(sec1.Value, sec2.Value);
            Assert.NotEqual(secOdd.Value, sec2.Value);
        }
Exemplo n.º 10
0
        public void Test_verify_commit_sum_random_keys()
        {
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            Commitment Commit(ulong value, SecretKey blinding)
            {
                return(secp.Commit(value, blinding));
            }

            var blindPos = SecretKey.New(secp, RandomNumberGenerator.Create());
            var blindNeg = SecretKey.New(secp, RandomNumberGenerator.Create());

            // now construct blinding factor to net out appropriately
            var blindSum = secp.blind_sum(new[] { blindPos }, new[] { blindNeg });

            secp.verify_commit_sum(
                new [] { Commit(101, blindPos) },
                new[] { Commit(75, blindNeg), Commit(26, blindSum) }
                );
        }
Exemplo n.º 11
0
        public void Test_pubkey_from_slice_bad_context()
        {
            var s  = Secp256K1.WithoutCaps();
            var sk = SecretKey.New(s, RandomNumberGenerator.Create());


            var ex = Assert.Throws <Exception>(() => { PublicKey.from_secret_key(s, sk); });

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

            s  = Secp256K1.WithCaps(ContextFlag.VerifyOnly);
            ex = Assert.Throws <Exception>(() => { PublicKey.from_secret_key(s, sk); });
            Assert.Equal("IncapableContext", ex.Message);

            s = Secp256K1.WithCaps(ContextFlag.SignOnly);
            PublicKey.from_secret_key(s, sk);

            s = Secp256K1.WithCaps(ContextFlag.Full);
            PublicKey.from_secret_key(s, sk);
        }
Exemplo n.º 12
0
        public void Test_key_derivation()
        {
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            var keychain = Keychain.From_random_seed();

            // use the keychain to derive a "key_id_set" based on the underlying seed
            var keyId = keychain.Derive_key_id(1);

            var msgBytes = new byte[32];
            var msg      = Message.from_slice(msgBytes);

            // now New a zero commitment using the key on the keychain associated with
            // the key_id_set
            var commit = keychain.Commit(0, keyId);

            // now check we can use our key to verify a signature from this zero commitment
            var sig = keychain.Sign(msg, keyId);

            secp.verify_from_commit(msg, sig, commit);
        }
Exemplo n.º 13
0
        public void Test_range_proof()
        {
            var secp       = Secp256K1.WithCaps(ContextFlag.Commit);
            var blinding   = SecretKey.New(secp, RandomNumberGenerator.Create());
            var commit     = secp.Commit(7, blinding);
            var msg        = ProofMessage.Empty();
            var rangeProof = secp.range_proof(0, 7, blinding, commit, msg.Clone());
            var proofRange = secp.verify_range_proof(commit, rangeProof);

            Assert.Equal <ulong>(0, proofRange.Min);

            var proofInfo = secp.range_proof_info(rangeProof);

            Assert.True(proofInfo.Success);
            Assert.Equal <ulong>(0, proofInfo.Min);

            //// check we get no information back for the value here
            Assert.Equal <ulong>(0, proofInfo.Value);

            proofInfo = secp.rewind_range_proof(commit, rangeProof, blinding);
            Assert.True(proofInfo.Success);
            Assert.Equal <ulong>(0, proofInfo.Min);
            Assert.Equal <ulong>(7, proofInfo.Value);

            //// check we cannot rewind a range proof without the original nonce
            var badNonce = SecretKey.New(secp, RandomNumberGenerator.Create());
            var badInfo  = secp.rewind_range_proof(commit, rangeProof, badNonce);

            Assert.False(badInfo.Success);
            Assert.Equal <ulong>(0, badInfo.Value);

            //// check we can construct and verify a range proof on value 0
            commit     = secp.Commit(0, blinding);
            rangeProof = secp.range_proof(0, 0, blinding, commit, msg);
            secp.verify_range_proof(commit, rangeProof);
            proofInfo = secp.rewind_range_proof(commit, rangeProof, blinding.Clone());
            Assert.True(proofInfo.Success);
            Assert.Equal <ulong>(0, proofInfo.Min);
            Assert.Equal <ulong>(0, proofInfo.Value);
        }
Exemplo n.º 14
0
        public void Test_add_exp_bad_context()
        {
            var s = Secp256K1.WithCaps(ContextFlag.Full);

            var(sk, pk) = s.generate_keypair(RandomNumberGenerator.Create());

            pk.add_exp_assign(s, sk);


            s = Secp256K1.WithCaps(ContextFlag.VerifyOnly);
            pk.add_exp_assign(s, sk);

            s = Secp256K1.WithCaps(ContextFlag.SignOnly);
            var ex = Assert.Throws <Exception>(() => { pk.add_exp_assign(s, sk); });

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


            s  = Secp256K1.WithCaps(ContextFlag.None);
            ex = Assert.Throws <Exception>(() => { pk.add_exp_assign(s, sk); });
            Assert.Equal("IncapableContext", ex.Message);
        }
Exemplo n.º 15
0
 public void Read(IReader reader)
 {
     Secp   = Secp256K1.WithCaps(ContextFlag.Commit);
     Commit = Ser.Ser.ReadCommitment(reader);
 }
Exemplo n.º 16
0
        public void Capabilities()
        {
            var none = Secp256K1.WithCaps(ContextFlag.None);
            var sign = Secp256K1.WithCaps(ContextFlag.SignOnly);
            var vrfy = Secp256K1.WithCaps(ContextFlag.VerifyOnly);
            var full = Secp256K1.WithCaps(ContextFlag.Full);

            var msgBytes = ByteUtil.Get_bytes(0, 32);
            var msg      = Message.from_slice(msgBytes);
            var rng      = RandomNumberGenerator.Create();

            // Try key generation
            var ex = Assert.Throws <Exception>(() => { none.generate_keypair(rng); });

            Assert.Equal("IncapableContext", ex.Message);
            ex = Assert.Throws <Exception>(() => { vrfy.generate_keypair(rng); });
            Assert.Equal("IncapableContext", ex.Message);

            sign.generate_keypair(rng);

            var fullKp = full.generate_keypair(rng);
            var sk     = fullKp.secretKey;
            var pk     = fullKp.publicKey;

            // Try signing
            ex = Assert.Throws <Exception>(() => { none.Sign(msg, sk); });
            Assert.Equal("IncapableContext", ex.Message);
            ex = Assert.Throws <Exception>(() => { vrfy.Sign(msg, sk); });
            Assert.Equal("IncapableContext", ex.Message);

            var ss = sign.Sign(msg, sk);
            var fs = full.Sign(msg, sk);

            Assert.Equal(ss.Value, fs.Value);

            ex = Assert.Throws <Exception>(() => { none.sign_recoverable(msg, sk); });
            Assert.Equal("IncapableContext", ex.Message);
            ex = Assert.Throws <Exception>(() => { vrfy.sign_recoverable(msg, sk); });
            Assert.Equal("IncapableContext", ex.Message);

            var srs = sign.sign_recoverable(msg, sk);
            var fsr = full.sign_recoverable(msg, sk);

            Assert.Equal(srs.Value, fsr.Value);

            var sig  = full.Sign(msg, sk);
            var sigr = full.sign_recoverable(msg, sk);

            // Try verifying
            ex = Assert.Throws <Exception>(() => { none.Verify(msg, sig, pk); });
            Assert.Equal("IncapableContext", ex.Message);
            ex = Assert.Throws <Exception>(() => { sign.Verify(msg, sig, pk); });
            Assert.Equal("IncapableContext", ex.Message);

            vrfy.Verify(msg, sig, pk);
            full.Verify(msg, sig, pk);

            // Try pk recovery
            ex = Assert.Throws <Exception>(() => { none.Recover(msg, sigr); });
            Assert.Equal("IncapableContext", ex.Message);
            ex = Assert.Throws <Exception>(() => { sign.Recover(msg, sigr); });
            Assert.Equal("IncapableContext", ex.Message);

            var vrc = vrfy.Recover(msg, sigr);
            var frc = full.Recover(msg, sigr);

            Assert.Equal(vrc.Value, frc.Value);
            Assert.Equal(frc.Value, pk.Value);

            // Check that we can produce keys from slices with no precomputation
            var pkSlice = pk.serialize_vec(none, false);
            var skSlice = sk.Value;
            var newPk   = PublicKey.from_slice(none, pkSlice);
            var newSk   = SecretKey.From_slice(none, skSlice);

            Assert.Equal(sk.Value, newSk.Value);
            Assert.Equal(pk.Value, newPk.Value);

            none.Dispose();
            sign.Dispose();
            vrfy.Dispose();
            full.Dispose();
        }