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 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); }
public void Read(IReader reader) { Features = (OutputFeatures)reader.read_u8(); Commit = Ser.Ser.ReadCommitment(reader); SwitchCommitHash = SwitchCommitHash.Readnew(reader); Proof = Ser.Ser.ReadRangeProof(reader); }
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); }
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); }
/// <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); } }
/// <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> /// 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); }
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); } }
public static void WriteRangeProof(this RangeProof rangeProof, IWriter writer) { writer.write_fixed_bytes(rangeProof.Proof); }
/// <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); }