xrpld
Loading...
Searching...
No Matches
test/jtx/impl/ConfidentialTransfer.cpp
1#include <test/jtx/ConfidentialTransfer.h>
2
3#include <test/jtx/Account.h>
4#include <test/jtx/Env.h>
5#include <test/jtx/mpt.h>
6
7#include <xrpl/basics/Buffer.h>
8#include <xrpl/basics/Slice.h>
9#include <xrpl/basics/base_uint.h>
10#include <xrpl/basics/contract.h>
11#include <xrpl/basics/strHex.h>
12#include <xrpl/protocol/ConfidentialTransfer.h>
13#include <xrpl/protocol/Protocol.h>
14#include <xrpl/protocol/TER.h>
15#include <xrpl/protocol/TxFlags.h>
16
17#include <utility/mpt_utility.h>
18
19#include <secp256k1.h>
20#include <secp256k1_mpt.h>
21
22#include <array>
23#include <cstddef>
24#include <cstdint>
25#include <cstring>
26#include <functional>
27#include <optional>
28#include <stdexcept>
29#include <string>
30#include <utility>
31#include <vector>
32
33namespace xrpl {
34
36 test::jtx::Env& env,
37 test::jtx::Account const& issuer,
38 std::vector<HolderInit> const& holders,
39 std::uint32_t flags,
41 : mpt{env, issuer, {.holders = extractAccounts(holders), .auditor = auditor}}
42{
43 mpt.create({.ownerCount = 1, .flags = flags});
44
45 for (auto const& h : holders)
46 {
47 mpt.authorize({.account = h.account});
48 if ((flags & tfMPTRequireAuth) != 0)
49 mpt.authorize({.account = issuer, .holder = h.account});
50 mpt.pay(issuer, h.account, h.payAmount);
51 }
52
53 mpt.generateKeyPair(issuer);
54 for (auto const& h : holders)
55 mpt.generateKeyPair(h.account);
56 if (auditor)
57 mpt.generateKeyPair(requireOptionalRef(auditor, "Missing auditor"));
58
59 mpt.set({
60 .account = issuer,
61 .issuerPubKey = mpt.getPubKey(issuer),
62 .auditorPubKey = auditor ? mpt.getPubKey(requireOptionalRef(auditor, "Missing auditor"))
63 : std::optional<Buffer>{},
64 });
65
66 for (auto const& h : holders)
67 {
68 mpt.convert({
69 .account = h.account,
70 .amt = h.convertAmount,
71 .holderPubKey = mpt.getPubKey(h.account),
72 });
73 mpt.mergeInbox({.account = h.account});
74 }
75}
76
77std::vector<test::jtx::Account>
79 std::vector<HolderInit> const& holders)
80{
82 accounts.reserve(holders.size());
83 for (auto const& h : holders)
84 accounts.push_back(h.account);
85 return accounts;
86}
87
88void
91 test::jtx::Account const& issuer,
93 std::vector<test::jtx::Account> const& keyOwners,
94 std::uint32_t flags)
95{
96 using namespace test::jtx;
97 mpt.create({
98 .ownerCount = 1,
99 .flags = flags,
100 });
101
102 for (auto const& holder : holders)
103 {
104 mpt.authorize({.account = holder});
105 mpt.pay(issuer, holder, 100);
106 mpt.generateKeyPair(holder);
107 }
108
109 mpt.generateKeyPair(issuer);
110 for (auto const& keyOwner : keyOwners)
111 mpt.generateKeyPair(keyOwner);
112}
113
114void
117 test::jtx::Account const& alice,
118 test::jtx::Account const& bob,
119 test::jtx::Account const& carol,
120 test::jtx::Account const& dave,
121 std::uint64_t bobAmt,
122 std::uint64_t carolAmt)
123{
124 using namespace test::jtx;
125 mpt.create({
126 .ownerCount = 1,
127 .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanHoldConfidentialBalance,
128 });
129 mpt.authorize({.account = bob});
130 mpt.authorize({.account = carol});
131 mpt.authorize({.account = dave});
132
133 if (bobAmt > 0)
134 mpt.pay(alice, bob, bobAmt);
135 if (carolAmt > 0)
136 mpt.pay(alice, carol, carolAmt);
137
138 mpt.generateKeyPair(alice);
139 mpt.generateKeyPair(bob);
140 mpt.generateKeyPair(carol);
141 mpt.generateKeyPair(dave);
142
143 mpt.set({
144 .account = alice,
145 .issuerPubKey = mpt.getPubKey(alice),
146 });
147
148 if (bobAmt > 0)
149 {
150 mpt.convert({
151 .account = bob,
152 .amt = bobAmt,
153 .holderPubKey = mpt.getPubKey(bob),
154 });
155 mpt.mergeInbox({.account = bob});
156 }
157 else
158 {
159 mpt.convert({
160 .account = bob,
161 .amt = 0,
162 .holderPubKey = mpt.getPubKey(bob),
163 });
164 }
165
166 if (carolAmt > 0)
167 {
168 mpt.convert({
169 .account = carol,
170 .amt = carolAmt,
171 .holderPubKey = mpt.getPubKey(carol),
172 });
173 mpt.mergeInbox({.account = carol});
174 }
175 else
176 {
177 mpt.convert({
178 .account = carol,
179 .amt = 0,
180 .holderPubKey = mpt.getPubKey(carol),
181 });
182 }
183
184 // dave: register pubkey only (0 spending/inbox)
185 mpt.convert({
186 .account = dave,
187 .amt = 0,
188 .holderPubKey = mpt.getPubKey(dave),
189 });
190}
191
194 test::jtx::Account const& sender,
195 test::jtx::Account const& dest,
196 test::jtx::Account const& issuer,
197 uint64_t amount,
199 : sendAmount(amount)
200 , version(mpt.getMPTokenVersion(sender))
204 , senderAmt(mpt.encryptAmount(sender, amount, blindingFactor))
205 , destAmt(mpt.encryptAmount(dest, amount, blindingFactor))
206 , issuerAmt(mpt.encryptAmount(issuer, amount, blindingFactor))
207 , auditorAmt(
208 auditor ? std::optional<Buffer>(mpt.encryptAmount(auditor->get(), amount, blindingFactor))
209 : std::nullopt)
210 , amountCommitment(mpt.getPedersenCommitment(amount, amountBlindingFactor))
211 , senderPubKey(requireOptional(mpt.getPubKey(sender), "Missing sender public key"))
212 , destPubKey(requireOptional(mpt.getPubKey(dest), "Missing destination public key"))
213 , issuerPubKey(requireOptional(mpt.getPubKey(issuer), "Missing issuer public key"))
214 , auditorPubKey(auditor ? mpt.getPubKey(auditor->get()) : std::nullopt)
216 mpt.getDecryptedBalance(sender, test::jtx::MPTTester::holderEncryptedSpending),
217 "Missing sender spending balance"))
219 mpt.getEncryptedBalance(sender, test::jtx::MPTTester::holderEncryptedSpending),
220 "Missing sender encrypted spending balance"))
221 , balanceCommitment(mpt.getPedersenCommitment(prevSpending, balanceBlindingFactor))
222{
223 recipients.push_back({
224 .publicKey = Slice(senderPubKey),
225 .encryptedAmount = senderAmt,
226 });
227 recipients.push_back({
228 .publicKey = Slice(destPubKey),
229 .encryptedAmount = destAmt,
230 });
231 recipients.push_back({
232 .publicKey = Slice(issuerPubKey),
233 .encryptedAmount = issuerAmt,
234 });
235 if (auditor)
236 {
237 recipients.push_back({
238 .publicKey = Slice(requireOptionalRef(auditorPubKey, "Missing auditor public key")),
239 .encryptedAmount = requireOptionalRef(auditorAmt, "Missing auditor encrypted amount"),
240 });
241 }
242}
243
247 test::jtx::Env& env,
248 test::jtx::Account const& sender,
249 test::jtx::Account const& dest) const
250{
251 auto const ctxHash =
252 getSendContextHash(sender.id(), mpt.issuanceID(), env.seq(sender), dest.id(), version);
253
254 return mpt.getConfidentialSendProof(
255 sender,
259 ctxHash,
260 {
261 .pedersenCommitment = amountCommitment,
262 .amt = sendAmount,
263 .encryptedAmt = senderAmt,
264 .blindingFactor = amountBlindingFactor,
265 },
266 {
267 .pedersenCommitment = balanceCommitment,
268 .amt = prevSpending,
269 .encryptedAmt = prevEncryptedSpending,
270 .blindingFactor = balanceBlindingFactor,
271 });
272}
273
276 test::jtx::Account const& sender,
277 test::jtx::Account const& dest,
278 Buffer const& proof,
279 std::optional<TER> err) const
280{
281 return {
282 .account = sender,
283 .dest = dest,
284 .amt = sendAmount,
285 .proof = strHex(proof),
286 .senderEncryptedAmt = senderAmt,
287 .destEncryptedAmt = destAmt,
288 .issuerEncryptedAmt = issuerAmt,
289 .auditorEncryptedAmt = auditorAmt,
290 .amountCommitment = amountCommitment,
291 .balanceCommitment = balanceCommitment,
292 .err = err,
293 };
294}
295
299 test::jtx::Account const& holder,
300 test::jtx::Account const& currentKey,
301 test::jtx::Account const& newKey)
302{
303 auto const spendingCt =
305 auto const inboxCt =
307 if (!spendingCt || !inboxCt)
308 return std::nullopt;
309
310 auto const spendingAmt = mpt.decryptAmount(currentKey, *spendingCt);
311 auto const inboxAmt = mpt.decryptAmount(currentKey, *inboxCt);
312 if (!spendingAmt || !inboxAmt)
313 return std::nullopt;
314
315 return std::pair{
316 mpt.encryptAmount(newKey, *spendingAmt, generateBlindingFactor()),
317 mpt.encryptAmount(newKey, *inboxAmt, generateBlindingFactor())};
318}
319
320Buffer const&
322{
323 static Buffer const kBadCiphertext = []() {
326
329 return buf;
330 }();
331
332 return kBadCiphertext;
333}
334
335Buffer const&
337{
338 static Buffer const kTrivialCiphertext = []() {
341
344
345 buf.data()[kEcCiphertextComponentLength - 1] = 0x01;
346 buf.data()[kEcGamalEncryptedTotalLength - 1] = 0x01;
347
348 return buf;
349 }();
350
351 return kTrivialCiphertext;
352}
353
354Buffer const&
356{
357 static Buffer const kTrivialCommitment = []() {
360
362 // Set last byte to make it a valid x-coordinate on the curve
363 buf.data()[kEcPedersenCommitmentLength - 1] = 0x01;
364
365 return buf;
366 }();
367
368 return kTrivialCommitment;
369}
370
386
387Buffer
389 std::array<uint64_t, 2> const& values,
390 std::array<Buffer, 2> const& blindingFactors,
391 UInt256 const& contextHash)
392{
393 auto* const ctx = mpt_secp256k1_context();
394
395 secp256k1_pubkey h;
396 secp256k1_mpt_get_h_generator(ctx, &h);
397
399 size_t proofLen = kEcDoubleBulletproofLength;
400
401 unsigned char blindings[64];
402 std::memcpy(blindings, blindingFactors[0].data(), 32);
403 std::memcpy(blindings + 32, blindingFactors[1].data(), 32);
404
405 if (secp256k1_bulletproof_prove_agg(
406 ctx, proof.data(), &proofLen, values.data(), blindings, 2, &h, contextHash.data()) == 0)
407 Throw<std::runtime_error>("Failed to generate forged bulletproof");
408
409 return proof;
410}
411
412Buffer
414 uint64_t value,
415 Buffer const& blindingFactor,
416 UInt256 const& contextHash)
417{
418 auto* const ctx = mpt_secp256k1_context();
419
420 secp256k1_pubkey h;
421 secp256k1_mpt_get_h_generator(ctx, &h);
422
424 size_t proofLen = kEcSingleBulletproofLength;
425
426 if (secp256k1_bulletproof_prove_agg(
427 ctx,
428 proof.data(),
429 &proofLen,
430 &value,
431 blindingFactor.data(),
432 1, // m = 1 (single bulletproof)
433 &h,
434 contextHash.data()) == 0)
435 Throw<std::runtime_error>("Failed to generate forged single bulletproof");
436
437 return proof;
438}
439
440Buffer
443 test::jtx::Account const& holder,
444 uint64_t claimedBalance,
445 uint64_t realBalance,
446 uint64_t amt,
447 Buffer const& pedersenCommitment,
448 Buffer const& encryptedSpendingBalance,
449 Buffer const& pcBlindingFactor,
450 UInt256 const& contextHash)
451{
452 if (pedersenCommitment.size() != kCompressedEcPointLength)
453 Throw<std::runtime_error>("getForgedConvertBackProof: bad pedersenCommitment length");
454 if (encryptedSpendingBalance.size() != kEcGamalEncryptedTotalLength)
455 {
456 Throw<std::runtime_error>("getForgedConvertBackProof: bad encryptedSpendingBalance length");
457 }
458 if (amt > realBalance)
459 Throw<std::runtime_error>("getForgedConvertBackProof: amt exceeds realBalance");
460
461 auto* const ctx = mpt_secp256k1_context();
462 auto const holderPubKey = requireOptional(mpt.getPubKey(holder), "Missing holder pubkey");
463 auto const holderPrivKey = requireOptional(mpt.getPrivKey(holder), "Missing holder privkey");
464
465 secp256k1_pubkey pkHolder;
466 if (secp256k1_ec_pubkey_parse(ctx, &pkHolder, holderPubKey.data(), kCompressedEcPointLength) !=
467 1)
468 Throw<std::runtime_error>("Failed to parse holder's public key");
469
470 secp256k1_pubkey pcB;
471 if (secp256k1_ec_pubkey_parse(ctx, &pcB, pedersenCommitment.data(), kCompressedEcPointLength) !=
472 1)
473 Throw<std::runtime_error>("Failed to parse pedersen commitment");
474
475 secp256k1_pubkey b1, b2;
476 if (secp256k1_ec_pubkey_parse(
477 ctx, &b1, encryptedSpendingBalance.data(), kCompressedEcPointLength) != 1 ||
478 secp256k1_ec_pubkey_parse(
479 ctx,
480 &b2,
481 encryptedSpendingBalance.data() + kCompressedEcPointLength,
483 Throw<std::runtime_error>("Failed to parse balance ciphertext");
484
485 Buffer sigmaProof(SECP256K1_COMPACT_CONVERTBACK_PROOF_SIZE);
486 if (secp256k1_compact_convertback_prove(
487 ctx,
488 sigmaProof.data(),
489 claimedBalance,
490 holderPrivKey.data(),
491 pcBlindingFactor.data(),
492 &pkHolder,
493 &b1,
494 &b2,
495 &pcB,
496 contextHash.data()) != 1)
497 Throw<std::runtime_error>("Failed to generate convertback sigma proof");
498
499 auto const forgedBulletproof =
500 getForgedSingleBulletproof(realBalance - amt, pcBlindingFactor, contextHash);
501
503 std::memcpy(proof.data(), sigmaProof.data(), SECP256K1_COMPACT_CONVERTBACK_PROOF_SIZE);
505 proof.data() + SECP256K1_COMPACT_CONVERTBACK_PROOF_SIZE,
506 forgedBulletproof.data(),
508
509 return proof;
510}
511
512Buffer
515 test::jtx::Env& env,
516 test::jtx::Account const& sender,
517 test::jtx::Account const& dest,
518 ConfidentialSendSetup const& setup)
519{
520 auto* const ctx = mpt_secp256k1_context();
521
522 secp256k1_pubkey c1;
523 std::vector<secp256k1_pubkey> c2Vec(setup.recipients.size());
524 std::vector<secp256k1_pubkey> pkVec(setup.recipients.size());
525 for (std::size_t i = 0; i < setup.recipients.size(); ++i)
526 {
527 auto const& r = setup.recipients[i];
528 if (i == 0 &&
529 secp256k1_ec_pubkey_parse(
530 ctx, &c1, r.encryptedAmount.data(), kCompressedEcPointLength) != 1)
531 Throw<std::runtime_error>("Failed to parse C1");
532 if (secp256k1_ec_pubkey_parse(
533 ctx,
534 &c2Vec[i],
535 r.encryptedAmount.data() + kCompressedEcPointLength,
537 Throw<std::runtime_error>("Failed to parse C2");
538 if (secp256k1_ec_pubkey_parse(
539 ctx, &pkVec[i], r.publicKey.data(), kCompressedEcPointLength) != 1)
540 Throw<std::runtime_error>("Failed to parse recipient pubkey");
541 }
542
543 secp256k1_pubkey pkSender, pcAmount, pcBalance, b1, b2;
544 if (secp256k1_ec_pubkey_parse(
545 ctx, &pkSender, setup.senderPubKey.data(), kCompressedEcPointLength) != 1 ||
546 secp256k1_ec_pubkey_parse(
547 ctx, &pcAmount, setup.amountCommitment.data(), kCompressedEcPointLength) != 1 ||
548 secp256k1_ec_pubkey_parse(
549 ctx, &pcBalance, setup.balanceCommitment.data(), kCompressedEcPointLength) != 1 ||
550 secp256k1_ec_pubkey_parse(
551 ctx, &b1, setup.prevEncryptedSpending.data(), kCompressedEcPointLength) != 1 ||
552 secp256k1_ec_pubkey_parse(
553 ctx,
554 &b2,
557 Throw<std::runtime_error>("Failed to parse commitments/ciphertext");
558
559 Buffer const senderPrivKey = requireOptional(mpt.getPrivKey(sender), "Missing sender privkey");
560 auto const ctxHash = getSendContextHash(
561 sender.id(), mpt.issuanceID(), env.seq(sender), dest.id(), setup.version);
562
563 Buffer sigmaProof(SECP256K1_COMPACT_STANDARD_PROOF_SIZE);
564 if (secp256k1_compact_standard_prove(
565 ctx,
566 sigmaProof.data(),
567 setup.sendAmount,
568 setup.prevSpending,
569 setup.blindingFactor.data(),
570 senderPrivKey.data(),
572 setup.recipients.size(),
573 &c1,
574 c2Vec.data(),
575 pkVec.data(),
576 &pcAmount,
577 &pkSender,
578 &pcBalance,
579 &b1,
580 &b2,
581 ctxHash.data()) != 1)
582 Throw<std::runtime_error>("Failed to generate sigma proof");
583
584 // Wraps (mod 2^64) for overdrafts, unlike the ledger's own homomorphic
585 // commitment subtraction (mod the curve order) — that mismatch is
586 // exactly what makes the forged proof fail verification.
587 // Computed without a wrapping `uint64` subtract: Clang UBSan treats
588 // unsigned overflow as fatal (see incrementConfidentialVersion).
589 std::uint64_t const remaining = setup.sendAmount <= setup.prevSpending
590 ? setup.prevSpending - setup.sendAmount
591 : ~setup.sendAmount + setup.prevSpending + 1;
592
593 Buffer negAmountBf(kEcBlindingFactorLength);
594 Buffer remainingBf(kEcBlindingFactorLength);
595 secp256k1_mpt_scalar_negate(negAmountBf.data(), setup.amountBlindingFactor.data());
596 secp256k1_mpt_scalar_add(
597 remainingBf.data(), setup.balanceBlindingFactor.data(), negAmountBf.data());
598
599 auto const forgedBulletproof = getForgedBulletproof(
600 {setup.sendAmount, remaining}, {setup.amountBlindingFactor, remainingBf}, ctxHash);
601
602 Buffer combinedProof(kEcSendProofLength);
603 std::memcpy(combinedProof.data(), sigmaProof.data(), SECP256K1_COMPACT_STANDARD_PROOF_SIZE);
605 combinedProof.data() + SECP256K1_COMPACT_STANDARD_PROOF_SIZE,
606 forgedBulletproof.data(),
608
609 return combinedProof;
610}
611
612} // namespace xrpl
pointer data()
Definition base_uint.h:117
Like std::vector<char> but better.
Definition Buffer.h:19
std::size_t size() const noexcept
Returns the number of bytes in the buffer.
Definition Buffer.h:123
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Buffer.h:148
static Buffer getForgedSingleBulletproof(uint64_t value, Buffer const &blindingFactor, UInt256 const &contextHash)
static Buffer getForgedSendProof(test::jtx::MPTTester &mpt, test::jtx::Env &env, test::jtx::Account const &sender, test::jtx::Account const &dest, ConfidentialSendSetup const &setup)
static std::optional< std::pair< Buffer, Buffer > > reencryptHolderBalances(test::jtx::MPTTester &mpt, test::jtx::Account const &holder, test::jtx::Account const &currentKey, test::jtx::Account const &newKey)
static void setupConfidentialIssuance(test::jtx::MPTTester &mpt, test::jtx::Account const &issuer, std::vector< test::jtx::Account > const &holders, std::vector< test::jtx::Account > const &keyOwners={}, std::uint32_t flags=tfMPTCanTransfer|tfMPTCanHoldConfidentialBalance)
static T requireOptional(std::optional< T > value, char const *message)
static void setupBatchEnv(test::jtx::MPTTester &mpt, test::jtx::Account const &alice, test::jtx::Account const &bob, test::jtx::Account const &carol, test::jtx::Account const &dave, std::uint64_t bobAmt, std::uint64_t carolAmt)
static T const & requireOptionalRef(std::optional< T > const &value, char const *message)
static Buffer getForgedBulletproof(std::array< uint64_t, 2 > const &values, std::array< Buffer, 2 > const &blindingFactors, UInt256 const &contextHash)
static Buffer getForgedConvertBackProof(test::jtx::MPTTester &mpt, test::jtx::Account const &holder, uint64_t claimedBalance, uint64_t realBalance, uint64_t amt, Buffer const &pedersenCommitment, Buffer const &encryptedSpendingBalance, Buffer const &pcBlindingFactor, UInt256 const &contextHash)
An immutable linear range of bytes.
Definition Slice.h:28
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
AccountID id() const
Returns the Account ID.
A transaction testing environment.
Definition Env.h:161
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:302
Test helper for creating, mutating, and asserting MPT and confidential MPT ledger state.
Definition mpt.h:512
static constexpr auto holderEncryptedInbox
Definition mpt.h:533
Buffer encryptAmount(Account const &account, uint64_t const amt, Buffer const &blindingFactor) const
Definition mpt.cpp:1914
void mergeInbox(MPTMergeInbox const &arg=MPTMergeInbox{}, std::source_location const &loc=std::source_location::current())
Definition mpt.cpp:2004
std::optional< Buffer > getEncryptedBalance(Account const &account, EncryptedBalanceType option=holderEncryptedInbox) const
Definition mpt.cpp:1136
std::uint32_t generateKeyPair(Account const &account)
Definition mpt.cpp:1877
MPTID const & issuanceID() const
Definition mpt.h:768
static constexpr auto holderEncryptedSpending
Definition mpt.h:534
std::optional< uint64_t > decryptAmount(Account const &account, Buffer const &amt, std::optional< std::uint32_t > epoch=std::nullopt) const
Definition mpt.cpp:1929
std::optional< Buffer > getConfidentialSendProof(Account const &sender, std::uint64_t const amount, std::vector< ConfidentialRecipient > const &recipients, Slice const &blindingFactor, UInt256 const &contextHash, PedersenProofParams const &amountParams, PedersenProofParams const &balanceParams) const
Definition mpt.cpp:1014
std::optional< Buffer > getPubKey(Account const &account, std::optional< std::uint32_t > epoch=std::nullopt) const
Definition mpt.cpp:1902
void pay(Account const &src, Account const &dest, std::int64_t amount, std::optional< TER > err=std::nullopt, std::optional< std::vector< std::string > > credentials=std::nullopt, std::source_location const &loc=std::source_location::current())
Definition mpt.cpp:826
void create(MPTCreate const &arg=MPTCreate{}, std::source_location const &loc=std::source_location::current())
Definition mpt.cpp:343
void set(MPTSet const &set={}, std::source_location const &loc=std::source_location::current())
Definition mpt.cpp:577
void authorize(MPTAuthorize const &arg=MPTAuthorize{}, std::source_location const &loc=std::source_location::current())
Definition mpt.cpp:455
void convert(MPTConvert const &arg=MPTConvert{}, std::source_location const &loc=std::source_location::current())
Definition mpt.cpp:1266
std::optional< Buffer > getPrivKey(Account const &account, std::optional< std::uint32_t > epoch=std::nullopt) const
Definition mpt.cpp:1908
T data(T... args)
T memcpy(T... args)
T memset(T... args)
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
constexpr std::uint8_t kEcCompressedPrefixEvenY
Compressed EC point prefix for even y-coordinate.
Definition Protocol.h:561
constexpr std::size_t kEcBlindingFactorLength
Length of the EC blinding factor in bytes.
Definition Protocol.h:495
constexpr std::size_t kCompressedEcPointLength
Length of EC point (compressed).
Definition Protocol.h:470
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:13
UInt256 getSendContextHash(AccountID const &account, UInt192 const &issuanceID, std::uint32_t sequence, AccountID const &destination, std::uint32_t version)
Generates the context hash for ConfidentialMPTSend transactions.
std::optional< Buffer > encryptAmount(uint64_t const amt, Slice const &pubKeySlice, Slice const &blindingFactor)
Encrypts an amount using ElGamal encryption.
constexpr std::size_t kEcGamalEncryptedTotalLength
EC ElGamal ciphertext length: two compressed EC points concatenated.
Definition Protocol.h:480
constexpr std::size_t kEcConvertBackProofLength
128 bytes compact sigma proof + 688 bytes single bulletproof.
Definition Protocol.h:535
BaseUInt< 256 > UInt256
Definition base_uint.h:580
constexpr std::size_t kEcSingleBulletproofLength
Length of single bulletproof (range proof for 1 commitment) in bytes.
Definition Protocol.h:510
constexpr std::size_t kEcPedersenCommitmentLength
Length of Pedersen Commitment (compressed).
Definition Protocol.h:505
constexpr std::size_t kEcCiphertextComponentLength
Length of one compressed EC point component in an EC ElGamal ciphertext.
Definition Protocol.h:475
constexpr std::size_t kEcDoubleBulletproofLength
Length of double bulletproof (range proof for 2 commitments) in bytes.
Definition Protocol.h:515
Buffer generateBlindingFactor()
Generates a cryptographically secure blinding factor (size=xrpl::kEcBlindingFactorLength).
constexpr std::size_t kEcSendProofLength
192 bytes compact sigma proof + 754 bytes double bulletproof.
Definition Protocol.h:525
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T push_back(T... args)
T reserve(T... args)
T size(T... args)
static std::vector< test::jtx::Account > extractAccounts(std::vector< HolderInit > const &holders)
ConfidentialEnv(test::jtx::Env &env, test::jtx::Account const &issuer, std::vector< HolderInit > const &holders, std::uint32_t flags=tfMPTCanLock|tfMPTCanHoldConfidentialBalance|tfMPTCanTransfer, std::optional< test::jtx::Account > auditor=std::nullopt)
std::optional< Buffer > generateProof(test::jtx::MPTTester &mpt, test::jtx::Env &env, test::jtx::Account const &sender, test::jtx::Account const &dest) const
test::jtx::MPTConfidentialSend sendArgs(test::jtx::Account const &sender, test::jtx::Account const &dest, Buffer const &proof, std::optional< TER > err=std::nullopt) const
ConfidentialSendSetup(test::jtx::MPTTester &mpt, test::jtx::Account const &sender, test::jtx::Account const &dest, test::jtx::Account const &issuer, uint64_t amount, std::optional< std::reference_wrapper< test::jtx::Account const > > auditor=std::nullopt)
Arguments for building a ConfidentialMPTSend test transaction.
Definition mpt.h:322