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 #2
0
        public void ConfidentialEntry_And_ConfidentialEntryDao_Should_Be_Convertible()
        {
            var pubKeyBytes         = new byte[30];
            var pedersenCommitBytes = new byte[50];
            var rangeProof          = new RangeProof();

            var rnd = new Random();

            rnd.NextBytes(pubKeyBytes);
            rnd.NextBytes(pedersenCommitBytes);

            var original = new ConfidentialEntry
            {
                Nonce              = ulong.MaxValue,
                SenderPublicKey    = pubKeyBytes.ToByteString(),
                TransactionFees    = UInt256.Zero.ToUint256ByteString(),
                PedersenCommitment = pedersenCommitBytes.ToByteString(),
                RangeProof         = rangeProof
            };

            var transactionEntryDao = original.ToDao <ConfidentialEntry, ConfidentialEntryDao>(_mapperProvider);

            transactionEntryDao.SenderPublicKey.Should().Be(pubKeyBytes.KeyToString());
            transactionEntryDao.Nonce.Should().Be(ulong.MaxValue);
            transactionEntryDao.PedersenCommitment.Should().Be(pedersenCommitBytes.ToByteString().ToBase64());
            transactionEntryDao.RangeProof.Should().Be(rangeProof.ToByteString().ToBase64());

            var reconverted = transactionEntryDao.ToProtoBuff <ConfidentialEntryDao, ConfidentialEntry>(_mapperProvider);

            reconverted.Should().Be(original);
        }
Beispiel #3
0
 public void Read(IReader reader)
 {
     Features         = (OutputFeatures)reader.read_u8();
     Commit           = Ser.Ser.ReadCommitment(reader);
     SwitchCommitHash = SwitchCommitHash.Readnew(reader);
     Proof            = Ser.Ser.ReadRangeProof(reader);
 }
Beispiel #4
0
        public ProofInfo Rewind_range_proof(Identifier keyId, Commitment commit, RangeProof proof)
        {
            var nonce     = Derived_key(keyId);
            var proofInfo = Secp.rewind_range_proof(commit, proof, nonce);

            return(proofInfo);
        }
Beispiel #5
0
        public void RangeProofJsonToObject()
        {
            RangeProof expected = GetRangeProofObject();
            RangeProof result   = parser.ParseJsonToObject <RangeProof>(GetRangeProofJson());

            Assert.AreEqual(expected.commitmentIndex, result.commitmentIndex);
            Assert.AreEqual(expected.maxBirthYear, result.maxBirthYear);
            Assert.AreEqual(expected.minBirthYear, result.minBirthYear);
            Assert.AreEqual(expected.rangeProofType, result.rangeProofType);
            Assert.AreEqual(expected.targetDate, result.targetDate);
            Assert.AreEqual(expected.verifiersRangeProofId, result.verifiersRangeProofId);
            helper.CompareList <string>(expected.A, result.A);
            helper.CompareList <string>(expected.X, result.X);
            helper.CompareList <string>(expected.D, result.D);
        }
Beispiel #6
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);
        }
        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 #8
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 #9
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);
        }
Beispiel #10
0
        public void Range_Proof()
        {
            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var rangeProof = new RangeProof())
                    {
                        var blinding = secp256k1.CreatePrivateKey();
                        var commit   = pedersen.Commit(9, 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, 9, blinding, commit, msgHash);
                        var verified = rangeProof.Verify(commit, proof);
                        Assert.True(verified);

                        var proofInfo = rangeProof.Info(proof);
                        Assert.True(proofInfo.success);
                        Assert.Equal(0, (long)proofInfo.min);
                        Assert.Equal(0, (long)proofInfo.value);

                        proofInfo = rangeProof.Rewind(commit, proof, blinding);
                        Assert.True(proofInfo.success);
                        Assert.Equal(0, (long)proofInfo.min);
                        Assert.Equal(9, (long)proofInfo.value);

                        var badNonce = secp256k1.CreatePrivateKey();
                        var badInfo  = rangeProof.Rewind(commit, proof, badNonce);
                        Assert.False(badInfo.success);
                        Assert.Equal(0, (long)badInfo.value);

                        commit = pedersen.Commit(0, blinding);
                        proof  = rangeProof.Proof(0, 0, blinding, commit, msgHash);
                        rangeProof.Verify(commit, proof);
                        proofInfo = rangeProof.Rewind(commit, proof, blinding);
                        Assert.True(proofInfo.success);
                        Assert.Equal(0, (long)proofInfo.min);
                        Assert.Equal(0, (long)proofInfo.value);
                    }
        }
Beispiel #11
0
 public static void WriteRangeProof(this RangeProof rangeProof, IWriter writer)
 {
     writer.write_fixed_bytes(rangeProof.Proof);
 }
Beispiel #12
0
        /// <summary>
        /// Builds the coin.
        /// </summary>
        /// <returns>The coin.</returns>
        /// <param name="blindSum">Blind sum.</param>
        /// <param name="commitPos">Commit position.</param>
        /// <param name="commitNeg">Commit neg.</param>
        private CoinDto BuildCoin(byte[] blindSum, byte[] commitPos, byte[] commitNeg, bool isReceiver = false)
        {
            Guard.Argument(blindSum, nameof(blindSum)).NotNull().MaxCount(32);
            Guard.Argument(commitPos, nameof(commitPos)).NotNull().MaxCount(33);
            Guard.Argument(commitNeg, nameof(commitNeg)).NotNull().MaxCount(33);

            CoinDto coin = null;
            bool    isVerified;

            using (var secp256k1 = new Secp256k1())
                using (var pedersen = new Pedersen())
                    using (var rangeProof = new RangeProof())
                    {
                        try
                        {
                            var commitSum = pedersen.CommitSum(new List <byte[]> {
                                commitPos
                            }, new List <byte[]> {
                                commitNeg
                            });
                            var naTInput  = NaT(Input());
                            var naTOutput = NaT(Output());
                            var naTChange = naTInput - naTOutput;

                            isVerified = isReceiver
                        ? pedersen.VerifyCommitSum(new List <byte[]> {
                                commitPos, commitNeg
                            }, new List <byte[]> {
                                Commit(naTOutput, blindSum)
                            })
                        : pedersen.VerifyCommitSum(new List <byte[]> {
                                commitPos
                            }, new List <byte[]> {
                                commitNeg, commitSum
                            });

                            if (!isVerified)
                            {
                                throw new ArgumentOutOfRangeException(nameof(isVerified), "Verify commit sum failed.");
                            }

                            var(k1, k2) = Split(blindSum, isReceiver);

                            coin = MakeSingleCoin();

                            coin.Envelope.Commitment = isReceiver ? Commit(naTOutput, blindSum).ToHex() : commitSum.ToHex();
                            coin.Envelope.Proof      = k2.ToHex();
                            coin.Envelope.PublicKey  = pedersen.ToPublicKey(Commit(0, k1)).ToHex();
                            coin.Envelope.Signature  = secp256k1.Sign(Hash(coin), k1).ToHex();

                            coin.Hash = Hash(coin).ToHex();

                            proofStruct = isReceiver
                        ? rangeProof.Proof(0, naTOutput, blindSum, coin.Envelope.Commitment.FromHex(), coin.Hash.FromHex())
                        : rangeProof.Proof(0, naTChange, blindSum, coin.Envelope.Commitment.FromHex(), coin.Hash.FromHex());

                            isVerified = rangeProof.Verify(coin.Envelope.Commitment.FromHex(), proofStruct);

                            if (!isVerified)
                            {
                                throw new ArgumentOutOfRangeException(nameof(isVerified), "Range proof failed.");
                            }
                        }
                        catch (Exception ex)
                        {
                            logger.LogError($"Message: {ex.Message}\n Stack: {ex.StackTrace}");
                        }
                    }

            return(coin);
        }