Example #1
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.");
            }
        }
Example #2
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);
        }