/// <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); }
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); } }
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); } }
//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); } }
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); } }
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) })); } }
/// <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); } }
/// <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)); }
/// <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(); } }
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)); } }
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) })); } }
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); } }
/// <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); }
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); } }
/// <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)); }
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); } }
/// <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); } }
/// <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); } }
/// <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); } }
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)); } }
/// <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); }
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); } }
/// <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); } }
/// <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."); } }
/// <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); } }
/// <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); }