Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="coinbase"></param>
        /// <param name="solution"></param>
        /// <param name="runningDistribution"></param>
        /// <returns></returns>
        public VerifyResult VerifyCoinbaseTransaction(Vout coinbase, ulong solution, decimal runningDistribution)
        {
            Guard.Argument(coinbase, nameof(coinbase)).NotNull();
            Guard.Argument(solution, nameof(solution)).NotZero().NotNegative();
            Guard.Argument(runningDistribution, nameof(runningDistribution)).NotZero().NotNegative();
            if (coinbase.Validate().Any())
            {
                return(VerifyResult.UnableToVerify);
            }
            if (coinbase.T != CoinType.Coinbase)
            {
                return(VerifyResult.UnableToVerify);
            }
            var verifyNetworkShare = VerifyNetworkShare(solution, coinbase.A.DivWithNanoTan(), runningDistribution);

            if (verifyNetworkShare == VerifyResult.UnableToVerify)
            {
                return(verifyNetworkShare);
            }
            using var pedersen = new Pedersen();
            var commitSum = pedersen.CommitSum(new List <byte[]> {
                coinbase.C
            }, new List <byte[]> {
                coinbase.C
            });

            return(commitSum == null ? VerifyResult.Succeed : VerifyResult.UnableToVerify);
        }
Beispiel #2
0
        public void Bullet_Proof_Extra_Commit_Wrong()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var bulletProof = new BulletProof())
                    {
                        // Correct extra commit
                        var   extraCommit = new byte[32];
                        var   blinding    = secp256k1.CreatePrivateKey();
                        ulong value       = 100033;
                        var   commit      = pedersen.Commit(value, blinding);
                        var   @struct     = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), extraCommit, null);
                        var   success     = bulletProof.Verify(commit, @struct.proof, extraCommit);

                        Assert.True(success);


                        //Wrong extra commit
                        var extraCommitWrong = new byte[32];
                        extraCommitWrong[0] = 1;
                        success             = bulletProof.Verify(commit, @struct.proof, extraCommitWrong);

                        Assert.False(success);
                    }
        }
Beispiel #3
0
        public void Bullet_Proof_Minimum_Amount()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var bulletProof = new BulletProof())
                    {
                        int   minValue = 1000;
                        ulong value    = 300;

                        // Correct value and minimum value
                        var blinding = secp256k1.CreatePrivateKey();
                        var commit   = pedersen.Commit(value, blinding);
                        var @struct  = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), null, null);
                        var success  = bulletProof.Verify(commit, @struct.proof, null);

                        Assert.True(success);

                        // Wrong value < 1000 and minimum value.
                        var commitWrong = pedersen.Commit(value, blinding);
                        @struct = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), null, null, minValue);
                        success = bulletProof.Verify(commit, @struct.proof, null, minValue);

                        Assert.False(success);
                    }
        }
Beispiel #4
0
        //TODO.. possibly remove?
        /// <summary>
        /// Split coin.
        /// </summary>
        /// <returns>The split.</returns>
        /// <param name="blinding">Blinding.</param>
        public (byte[], byte[]) Split(byte[] blinding, SecureString secret, SecureString salt, string stamp, int version)
        {
            Guard.Argument(blinding, nameof(blinding)).NotNull().MaxCount(32);

            using (var pedersen = new Pedersen())
            {
                var skey1 = DeriveKey(0, stamp, version, secret, salt);

                byte[] skey2 = new byte[32];

                try
                {
                    skey2 = pedersen.BlindSum(new List <byte[]> {
                        blinding
                    }, new List <byte[]> {
                        skey1
                    });
                }
                catch (Exception ex)
                {
                    logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                    throw ex;
                }

                return(skey1, skey2);
            }
        }
Beispiel #5
0
        public void Commit_Sum_Random_Keys()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    byte[] Commit(ulong value, byte[] blinding)
                    {
                        return(pedersen.Commit(value, blinding));
                    }

                    var blindPos = secp256k1.CreatePrivateKey();
                    var blindNeg = secp256k1.CreatePrivateKey();

                    var blindSum = pedersen.BlindSum(new List <byte[]> {
                        blindPos
                    }, new List <byte[]> {
                        blindNeg
                    });

                    Assert.True(pedersen.VerifyCommitSum(new List <byte[]> {
                        Commit(101, blindPos)
                    }, new List <byte[]> {
                        Commit(75, blindNeg), Commit(26, blindSum)
                    }));
                }
        }
        static void TestRangeProof()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var rangeProof = new RangeProof())
                    {
                        var blinding  = secp256k1.CreatePrivateKey();
                        var commit    = pedersen.Commit(100, blinding);
                        var msg       = "Message for signing";
                        var msgBytes  = Encoding.UTF8.GetBytes(msg);
                        var msgHash   = System.Security.Cryptography.SHA256.Create().ComputeHash(msgBytes);
                        var proof     = rangeProof.Proof(0, 100, blinding, commit, msgHash);
                        var verified  = rangeProof.Verify(commit, proof);
                        var proofInfo = rangeProof.Info(proof);

                        proofInfo = rangeProof.Rewind(commit, proof, blinding);

                        var badNonce = secp256k1.CreatePrivateKey();
                        var badInfo  = rangeProof.Rewind(commit, proof, badNonce);

                        commit = pedersen.Commit(0, blinding);
                        proof  = rangeProof.Proof(0, 0, blinding, commit, msgHash);
                        rangeProof.Verify(commit, proof);
                        proofInfo = rangeProof.Rewind(commit, proof, blinding);
                    }
        }
Beispiel #7
0
        public void Verify_Commit_Sum_Random_Keys_Switch()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    byte[] Commit(ulong value, byte[] blinding)
                    {
                        return(pedersen.Commit(value, blinding));
                    }

                    ulong posValue = 101;
                    ulong negValue = 75;

                    var blindPos = pedersen.BlindSwitch(posValue, secp256k1.CreatePrivateKey());
                    var blindNeg = pedersen.BlindSwitch(negValue, secp256k1.CreatePrivateKey());

                    var blindSum = pedersen.BlindSum(new List <byte[]> {
                        blindPos
                    }, new List <byte[]> {
                        blindNeg
                    });

                    var diff = posValue - negValue;

                    Assert.True(pedersen.VerifyCommitSum(new List <byte[]> {
                        Commit(posValue, blindPos)
                    }, new List <byte[]> {
                        Commit(negValue, blindNeg), Commit(diff, blindSum)
                    }));
                }
        }
Beispiel #8
0
        /// <summary>
        /// Builds the receiver.
        /// </summary>
        /// <returns>The receiver.</returns>
        public (ReceiverOutput, CoinDto) BuildReceiver()
        {
            ReceiverOutput receiver = null;
            CoinDto        coin     = null;

            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    var blind    = DeriveKey(Output());
                    var blindSum = pedersen.BlindSum(new List <byte[]> {
                        blind, blind
                    }, new List <byte[]> {
                    });
                    var commitPos = Commit((ulong)Output(), blind);
                    var commitNeg = Commit(0, blind);

                    Stamp(GetNewStamp());
                    Version(-1);

                    coin     = BuildCoin(blindSum, commitPos, commitNeg, true);
                    receiver = new ReceiverOutput(Output(), commitPos, blindSum);
                }

            return(receiver, coin);
        }
        static void TestToPublicKey()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    var blinding  = secp256k1.CreatePrivateKey();
                    var commitPos = pedersen.Commit(0, blinding);
                    var commitNeg = pedersen.Commit(0, blinding);

                    var blindSum = pedersen.BlindSum(new List <byte[]> {
                        blinding, blinding
                    }, new List <byte[]> {
                    });

                    var commitSum = pedersen.CommitSum(new List <byte[]> {
                        commitPos
                    }, new List <byte[]> {
                        commitNeg
                    });

                    var msg      = "Message for signing";
                    var msgBytes = Encoding.UTF8.GetBytes(msg);
                    var msgHash  = System.Security.Cryptography.SHA256.Create().ComputeHash(msgBytes);

                    var sig = secp256k1.Sign(msgHash, blinding);

                    var pubKey = pedersen.ToPublicKey(commitSum);

                    var verified1 = secp256k1.Verify(sig, msgHash, pubKey);
                    var pub       = secp256k1.CreatePublicKey(blinding);
                }
        }
Beispiel #10
0
        /// <summary>
        /// Builds the receiver.
        /// </summary>
        /// <returns>The receiver.</returns>
        public TaskResult <bool> Receiver(SecureString secret, ulong input, out CoinDto coin, out byte[] blind, out byte[] salt)
        {
            using (var pedersen = new Pedersen())
            {
                salt  = Cryptography.RandomBytes(16);
                coin  = MakeSingleCoin(secret, salt.ToHex().ToSecureString(), NewStamp(), -1);
                blind = DeriveKey(input, coin.Stamp, coin.Version, secret, salt.ToHex().ToSecureString());

                try
                {
                    var blindSum = pedersen.BlindSum(new List <byte[]> {
                        blind
                    }, new List <byte[]> {
                    });
                    var commitPos = pedersen.Commit(input, blind);
                    var commitSum = pedersen.CommitSum(new List <byte[]> {
                        commitPos
                    }, new List <byte[]> {
                    });

                    AttachEnvelope(blindSum, commitSum, input, secret, salt.ToHex().ToSecureString(), ref coin);
                }
                catch (Exception ex)
                {
                    logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                    return(TaskResult <bool> .CreateFailure(ex));
                }
            }

            return(TaskResult <bool> .CreateSuccess(true));
        }
Beispiel #11
0
        /// <summary>
        /// Attachs the envelope.
        /// </summary>
        /// <param name="blindSum">Blind sum.</param>
        /// <param name="commitSum">Commit sum.</param>
        /// <param name="balance">Balance.</param>
        /// <param name="secret">Secret.</param>
        /// <param name="coin">Coin.</param>
        private void AttachEnvelope(byte[] blindSum, byte[] commitSum, ulong balance, SecureString secret, SecureString salt, ref CoinDto coin)
        {
            var(k1, k2) = Split(blindSum, secret, salt, coin.Stamp, coin.Version);

            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var bulletProof = new BulletProof())
                    {
                        coin.Envelope.Commitment = commitSum.ToHex();
                        coin.Envelope.Proof      = k2.ToHex();
                        coin.Envelope.PublicKey  = pedersen.ToPublicKey(pedersen.Commit(0, k1)).ToHex();
                        coin.Hash = Hash(coin).ToHex();
                        coin.Envelope.Signature = secp256k1.Sign(coin.Hash.FromHex(), k1).ToHex();

                        var @struct = bulletProof.ProofSingle(balance, blindSum, Cryptography.RandomBytes(), null, null, null);
                        var success = bulletProof.Verify(commitSum, @struct.proof, null);

                        if (!success)
                        {
                            throw new ArgumentOutOfRangeException(nameof(success), "Bullet proof failed.");
                        }

                        coin.Envelope.RangeProof = @struct.proof.ToHex();
                    }
        }
Beispiel #12
0
        public void Sign_With_PubKey_From_Commitment()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    string ToHex(byte[] data)
                    {
                        return(BitConverter.ToString(data).Replace("-", string.Empty));
                    }

                    var blinding = secp256k1.CreatePrivateKey();
                    var commit   = pedersen.Commit(0, blinding);

                    var msg      = "Message for signing";
                    var msgBytes = Encoding.UTF8.GetBytes(msg);
                    var msgHash  = System.Security.Cryptography.SHA256.Create().ComputeHash(msgBytes);

                    var sig = secp256k1.Sign(msgHash, blinding);

                    var pubKey = pedersen.ToPublicKey(commit);

                    Assert.True(secp256k1.Verify(sig, msgHash, pubKey));

                    var actualPubKey = secp256k1.CreatePublicKey(blinding);

                    Assert.Equal(ToHex(pubKey), ToHex(actualPubKey));
                }
        }
Beispiel #13
0
        public void Verify_Commit_Sum_Zero_Keys()
        {
            using (var pedersen = new Pedersen())
            {
                byte[] Commit(ulong value)
                {
                    var zeroKey = new byte[32];

                    return(pedersen.Commit(value, zeroKey));
                }

                Assert.True(pedersen.VerifyCommitSum(new List <byte[]> {
                }, new List <byte[]> {
                }));

                Assert.True(pedersen.VerifyCommitSum(new List <byte[]> {
                    Commit(5)
                }, new List <byte[]> {
                    Commit(5)
                }));

                Assert.True(pedersen.VerifyCommitSum(new List <byte[]> {
                    Commit(3), Commit(2)
                }, new List <byte[]> {
                    Commit(5)
                }));

                Assert.True(pedersen.VerifyCommitSum(new List <byte[]> {
                    Commit(2), Commit(4)
                }, new List <byte[]> {
                    Commit(1), Commit(5)
                }));
            }
        }
Beispiel #14
0
        public void Bullet_Proof()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var bulletProof = new BulletProof())
                    {
                        // Correct value
                        ulong value    = 300;
                        var   blinding = secp256k1.CreatePrivateKey();
                        var   commit   = pedersen.Commit(value, blinding);
                        var   @struct  = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), null, null);
                        var   success  = bulletProof.Verify(commit, @struct.proof, null);

                        Assert.True(success);

                        // Wrong value
                        value = 1222344;
                        var commitWrong = pedersen.Commit(122111, blinding);
                        @struct = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), null, null);
                        success = bulletProof.Verify(commit, @struct.proof, null);

                        Assert.False(success);

                        // Wrong binding
                        value    = 122322;
                        commit   = pedersen.Commit(value, blinding);
                        blinding = secp256k1.CreatePrivateKey();
                        @struct  = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), null, null);
                        success  = bulletProof.Verify(commit, @struct.proof, null);

                        Assert.False(success);
                    }
        }
Beispiel #15
0
        /// <summary>
        /// Builds the receiver.
        /// </summary>
        /// <returns>The receiver.</returns>
        public CoinService BuildReceiver()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    var naTOutput = NaT(Output());
                    var blind     = DeriveKey(naTOutput);

                    byte[] blindSum = new byte[32];

                    try
                    {
                        blindSum = pedersen.BlindSum(new List <byte[]> {
                            blind, blind
                        }, new List <byte[]> {
                        });
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                        throw ex;
                    }

                    var commitPos = Commit(naTOutput, blind);
                    var commitNeg = Commit(0, blind);

                    Stamp(GetNewStamp());
                    Version(-1);

                    mintedCoin     = BuildCoin(blindSum, commitPos, commitNeg, true);
                    receiverOutput = new ReceiverOutput(Output(), commitPos, blindSum);
                }

            return(this);
        }
Beispiel #16
0
        public void To_Pubkey()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    var blinding = secp256k1.CreatePrivateKey();
                    var commit   = pedersen.Commit(5, blinding);
                    var pubKey   = pedersen.ToPublicKey(commit);

                    Assert.NotNull(pubKey);
                }
        }
Beispiel #17
0
        /// <summary>
        /// Builds the sender.
        /// </summary>
        /// <returns>The sender.</returns>
        public async Task <TaskResult <CoinDto> > Sender(Session session, PurchaseDto purchase)
        {
            CoinDto coin = null;

            using (var pedersen = new Pedersen())
            {
                try
                {
                    //TODO: Refactor signature to handle lambda expressions..
                    var txnsAll = await unitOfWork.GetTransactionRepository().All(session);

                    if (txnsAll.Result?.Any() != true)
                    {
                        throw new Exception("No transactions found!");
                    }

                    var txns = txnsAll.Result.Where(tx => purchase.Chain.Any(id => id == Guid.Parse(tx.TransactionId)));

                    var received = txns.FirstOrDefault(tx => tx.TransactionType == TransactionType.Receive);

                    coin = MakeSingleCoin(session.MasterKey, received.Salt.ToSecureString(), purchase.Stamp, purchase.Version);

                    var blindNeg  = DeriveKey(purchase.Input, received.Stamp, coin.Version, session.MasterKey, received.Salt.ToSecureString());
                    var commitNeg = pedersen.Commit(purchase.Input, blindNeg);

                    var commitNegs = txns.Where(tx => tx.TransactionType == TransactionType.Send)
                                     .Select(c => pedersen.Commit(c.Amount, DeriveKey(c.Amount, c.Stamp, c.Version, session.MasterKey, received.Salt.ToSecureString()))).ToList();

                    commitNegs.Add(commitNeg);

                    var blindNegSums = txns.Where(tx => tx.TransactionType == TransactionType.Send)
                                       .Select(c => DeriveKey(c.Amount, c.Stamp, c.Version, session.MasterKey, received.Salt.ToSecureString())).ToList();

                    blindNegSums.Add(blindNeg);

                    var blindSum = pedersen.BlindSum(new List <byte[]> {
                        received.Blind.FromHex()
                    }, blindNegSums);
                    var commitSum = pedersen.CommitSum(new List <byte[]> {
                        received.Commitment.FromHex()
                    }, commitNegs);

                    AttachEnvelope(blindSum, commitSum, purchase.Output, session.MasterKey, received.Salt.ToSecureString(), ref coin);
                }
                catch (Exception ex)
                {
                    logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                    return(TaskResult <CoinDto> .CreateFailure(ex));
                }
            }

            return(TaskResult <CoinDto> .CreateSuccess(coin));
        }
Beispiel #18
0
        public void Commit_Parse_Serialize()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    var commit = pedersen.Commit(5, secp256k1.CreatePrivateKey());
                    var parsed = pedersen.CommitParse(commit);
                    var ser    = pedersen.CommitSerialize(parsed);

                    Assert.Equal(ser, commit);
                }
        }
Beispiel #19
0
        /// <summary>
        /// Commit the specified amount.
        /// </summary>
        /// <returns>The commit.</returns>
        /// <param name="amount">Amount.</param>
        public byte[] Commit(ulong amount)
        {
            Guard.Argument(stamp, nameof(stamp)).NotNull().NotEmpty();
            Guard.Argument(password, nameof(password)).NotNull();

            using (var pedersen = new Pedersen())
            {
                var blind  = DeriveKey(Version(), Stamp(), Password()).FromHex();
                var commit = pedersen.Commit(amount, blind);

                return(commit);
            }
        }
Beispiel #20
0
        /// <summary>
        /// Commit the specified amount, version, stamp and password.
        /// </summary>
        /// <returns>The commit.</returns>
        /// <param name="amount">Amount.</param>
        /// <param name="version">Version.</param>
        /// <param name="stamp">Stamp.</param>
        /// <param name="password">Password.</param>
        public byte[] Commit(ulong amount, int version, string stamp, SecureString password)
        {
            Guard.Argument(stamp, nameof(stamp)).NotNull().NotEmpty();
            Guard.Argument(password, nameof(password)).NotNull();

            using (var pedersen = new Pedersen())
            {
                var blind  = DeriveKey(version, stamp, password).FromHex();
                var commit = pedersen.Commit(amount, blind);

                return(commit);
            }
        }
 static void Main(string[] args)
 {
     using (var secp256k1 = new Secp256k1())
         using (var pedersen = new Pedersen())
             using (var bulletProof = new BulletProof())
             {
                 // Correct valu
                 int   minValue = 1000;
                 ulong value    = 1000;
                 var   blinding = secp256k1.CreatePrivateKey();
                 var   commit   = pedersen.Commit(value, blinding);
                 var   @struct  = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), null, null);
                 var   success  = bulletProof.Verify(commit, @struct.proof, null);
             }
 }
Beispiel #22
0
        /// <summary>
        /// Commit the specified amount, version, stamp and password.
        /// </summary>
        /// <returns>The commit.</returns>
        /// <param name="amount">Amount.</param>
        /// <param name="version">Version.</param>
        /// <param name="stamp">Stamp.</param>
        /// <param name="password">Password.</param>
        public byte[] Commit(ulong amount, int version, string stamp, SecureString password)
        {
            if (string.IsNullOrEmpty(stamp))
            {
                throw new ArgumentException("message", nameof(stamp));
            }

            using (var pedersen = new Pedersen())
            {
                var blind  = DeriveKey(version, stamp, password).FromHex();
                var commit = pedersen.Commit(amount, blind);

                return(commit);
            }
        }
Beispiel #23
0
        public void Commit_Sum()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                {
                    string ToHex(byte[] data)
                    {
                        return(BitConverter.ToString(data).Replace("-", string.Empty));
                    }

                    var blindA = secp256k1.CreatePrivateKey();
                    var blindB = secp256k1.CreatePrivateKey();

                    var commitA = pedersen.Commit(3, blindA);

                    var commitB = pedersen.Commit(2, blindB);

                    var blindC = pedersen.BlindSum(new List <byte[]> {
                        blindA, blindB
                    }, new List <byte[]> {
                    });

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

                    var commitD = pedersen.CommitSum(new List <byte[]> {
                        commitA, commitB
                    }, new List <byte[]> {
                    });

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

                    var blindE = pedersen.BlindSum(new List <byte[]> {
                        blindA
                    }, new List <byte[]> {
                        blindB
                    });

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

                    var commitF = pedersen.CommitSum(new List <byte[]> {
                        commitA
                    }, new List <byte[]> {
                        commitB
                    });

                    Assert.Equal(ToHex(commitE), ToHex(commitF));
                }
        }
Beispiel #24
0
        /// <summary>
        /// Builds the sender.
        /// </summary>
        /// <returns>The sender.</returns>
        public CoinService BuildSender(SecureString secret)
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var rangeProof = new RangeProof())
                    {
                        Stamp(TransactionCoin().Stamp);
                        Version(TransactionCoin().Version);

                        MakeSingleCoin(secret);

                        try
                        {
                            var received = TransactionCoin().Chain.FirstOrDefault(tx => tx.TransactionType == TransactionType.Receive);

                            var blindNeg  = DeriveKey(TransactionCoin().Input, received.Stamp, Coin().Version, secret);
                            var commitNeg = pedersen.Commit(TransactionCoin().Input, blindNeg);

                            var commitNegs = TransactionCoin().Chain
                                             .Where(tx => tx.TransactionType == TransactionType.Send)
                                             .Select(c => pedersen.Commit(c.Amount, DeriveKey(c.Amount, c.Stamp, c.Version, secret))).ToList();

                            commitNegs.Add(commitNeg);

                            var blindNegSums = TransactionCoin().Chain
                                               .Where(tx => tx.TransactionType == TransactionType.Send)
                                               .Select(c => DeriveKey(c.Amount, c.Stamp, c.Version, secret)).ToList();

                            blindNegSums.Add(blindNeg);

                            var blindSum = pedersen.BlindSum(new List <byte[]> {
                                received.Blind.FromHex()
                            }, blindNegSums);
                            var commitSum = pedersen.CommitSum(new List <byte[]> {
                                received.Commitment.FromHex()
                            }, commitNegs);

                            AttachEnvelope(secp256k1, pedersen, rangeProof, blindSum, commitSum, TransactionCoin().Output, secret);
                        }
                        catch (Exception ex)
                        {
                            logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                            throw ex;
                        }
                    }

            return(this);
        }
Beispiel #25
0
        public void Bullet_Proof_Extra_Commit()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var bulletProof = new BulletProof())
                    {
                        var   extraCommit = new byte[32];
                        var   blinding    = secp256k1.GetSecretKey();
                        ulong value       = 100033;
                        var   commit      = pedersen.Commit(value, blinding);
                        var   @struct     = bulletProof.GenProof(value, blinding, (byte[])blinding.Clone(), (byte[])blinding.Clone(), extraCommit, null);
                        var   success     = bulletProof.Verify(commit, @struct.proof, extraCommit);

                        Assert.True(success);
                    }
        }
        static void TestRangeProofOnBlock()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var rangeProof = new RangeProof())
                    {
                        var blinding = secp256k1.CreatePrivateKey();

                        ulong posValue = NaT(3434545);
                        ulong negValue = NaT(1.123456789123456789);

                        var diff = posValue - negValue;

                        var blindPos = pedersen.BlindSwitch(posValue, blinding);
                        var blindNeg = pedersen.BlindSwitch(negValue, blinding);

                        var blindSum = pedersen.BlindSum(new List <byte[]> {
                            blindPos
                        }, new List <byte[]> {
                            blindNeg
                        });

                        var commitPos = pedersen.Commit(posValue, blindPos);
                        var commitNeg = pedersen.Commit(negValue, blindNeg);

                        var commitSum = pedersen.CommitSum(new List <byte[]> {
                            commitPos
                        }, new List <byte[]> {
                            commitNeg
                        });
                        var isVerified = pedersen.VerifyCommitSum(new List <byte[]> {
                            commitPos
                        }, new List <byte[]> {
                            commitNeg, commitSum
                        });

                        var commitChange = pedersen.Commit(diff, blinding);

                        var msg      = "Message for signing";
                        var msgBytes = Encoding.UTF8.GetBytes(msg);
                        var msgHash  = System.Security.Cryptography.SHA256.Create().ComputeHash(msgBytes);

                        var proofStruct = rangeProof.Proof(0, diff, blindSum, commitSum, msgHash);

                        var verified = rangeProof.Verify(commitSum, proofStruct);
                    }
        }
Beispiel #27
0
        /// <summary>
        /// Commit the specified amount and blind.
        /// </summary>
        /// <returns>The commit.</returns>
        /// <param name="amount">Amount.</param>
        /// <param name="blind">Blind.</param>
        public byte[] Commit(ulong amount, byte[] blind)
        {
            if (blind == null)
            {
                throw new ArgumentNullException(nameof(blind));
            }

            if (blind.Length > 32)
            {
                throw new IndexOutOfRangeException(nameof(blind));
            }

            using (var pedersen = new Pedersen())
            {
                var commit = pedersen.Commit(amount, blind);
                return(commit);
            }
        }
Beispiel #28
0
        /// <summary>
        /// Attaches the envelope.
        /// </summary>
        /// <param name="secp256k1">Secp256k1.</param>
        /// <param name="pedersen">Pedersen.</param>
        /// <param name="rangeProof">Range proof.</param>
        /// <param name="blindSum">Blind sum.</param>
        /// <param name="commitSum">Commit sum.</param>
        /// <param name="secret">Secret.</param>
        private void AttachEnvelope(Secp256k1 secp256k1, Pedersen pedersen, RangeProof rangeProof, byte[] blindSum, byte[] commitSum, ulong balance, SecureString secret)
        {
            var(k1, k2) = Split(blindSum, secret);

            Coin().Envelope.Commitment = commitSum.ToHex();
            Coin().Envelope.Proof      = k2.ToHex();
            Coin().Envelope.PublicKey  = pedersen.ToPublicKey(pedersen.Commit(0, k1)).ToHex();
            Coin().Hash = Hash(Coin()).ToHex();
            Coin().Envelope.Signature = secp256k1.Sign(Coin().Hash.FromHex(), k1).ToHex();

            proofStruct = rangeProof.Proof(0, balance, blindSum, commitSum, Coin().Hash.FromHex());

            var isVerified = rangeProof.Verify(commitSum, proofStruct);

            if (!isVerified)
            {
                throw new ArgumentOutOfRangeException(nameof(isVerified), "Range proof failed.");
            }
        }
Beispiel #29
0
        /// <summary>
        /// Commit the specified amount.
        /// </summary>
        /// <returns>The commit.</returns>
        /// <param name="amount">Amount.</param>
        public byte[] Commit(ulong amount)
        {
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }

            if (stamp == null)
            {
                throw new ArgumentNullException(nameof(stamp));
            }

            using (var pedersen = new Pedersen())
            {
                var blind  = DeriveKey(Version(), Stamp(), Password()).FromHex();
                var commit = pedersen.Commit(amount, blind);

                return(commit);
            }
        }
Beispiel #30
0
        /// <summary>
        /// Builds the receiver.
        /// </summary>
        /// <returns>The receiver.</returns>
        public CoinService BuildReceiver(SecureString secret)
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var rangeProof = new RangeProof())
                    {
                        Stamp(NewStamp());
                        Version(-1);

                        MakeSingleCoin(secret);

                        var blind = DeriveKey(TransactionCoin().Input, Stamp(), Coin().Version, secret);

                        byte[] blindSum = new byte[32];

                        try
                        {
                            blindSum = pedersen.BlindSum(new List <byte[]> {
                                blind
                            }, new List <byte[]> {
                            });

                            var commitPos = pedersen.Commit(TransactionCoin().Input, blind);
                            var commitSum = pedersen.CommitSum(new List <byte[]> {
                                commitPos
                            }, new List <byte[]> {
                            });

                            AttachEnvelope(secp256k1, pedersen, rangeProof, blindSum, commitSum, TransactionCoin().Input, secret);

                            transactionCoin.Blind = blindSum.ToHex();
                        }
                        catch (Exception ex)
                        {
                            logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                            throw ex;
                        }
                    }

            return(this);
        }