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) })); }
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); }
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); } } }
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) } )); }
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); }
// 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); }); }
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); }
/// 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()); }
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); }
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) } ); }
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); }
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); }
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); }
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); }
public void Read(IReader reader) { Secp = Secp256K1.WithCaps(ContextFlag.Commit); Commit = Ser.Ser.ReadCommitment(reader); }
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(); }