From 84cc8599afb92fc3e584804964f9fad4873befde Mon Sep 17 00:00:00 2001 From: Shawn Xie <35279399+shawnxie999@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:24:01 -0400 Subject: [PATCH] chore: Apply clang-format width 100 (#6516) --- include/xrpl/protocol/ConfidentialTransfer.h | 3 +- .../token/ConfidentialMPTClawback.h | 1 - .../token/ConfidentialMPTConvert.h | 1 - .../token/ConfidentialMPTConvertBack.h | 1 - .../token/ConfidentialMPTMergeInbox.h | 1 - .../transactors/token/ConfidentialMPTSend.h | 1 - src/libxrpl/ledger/View.cpp | 3 +- src/libxrpl/protocol/ConfidentialTransfer.cpp | 113 ++- .../token/ConfidentialMPTConvert.cpp | 5 +- .../token/ConfidentialMPTConvertBack.cpp | 5 +- .../tx/transactors/token/MPTokenAuthorize.cpp | 6 +- .../token/MPTokenIssuanceCreate.cpp | 3 +- .../transactors/token/MPTokenIssuanceSet.cpp | 42 +- src/test/app/ConfidentialTransfer_test.cpp | 661 +++++++++++++----- src/test/app/Invariants_test.cpp | 15 +- src/test/jtx/impl/mpt.cpp | 274 +++++--- src/test/jtx/mpt.h | 14 +- 17 files changed, 797 insertions(+), 352 deletions(-) diff --git a/include/xrpl/protocol/ConfidentialTransfer.h b/include/xrpl/protocol/ConfidentialTransfer.h index 88bc7b9b5f..176d360f12 100644 --- a/include/xrpl/protocol/ConfidentialTransfer.h +++ b/include/xrpl/protocol/ConfidentialTransfer.h @@ -44,7 +44,8 @@ incrementConfidentialVersion(STObject& mptoken) // Retrieve current version and increment. // Unsigned integer overflow is defined behavior in C++ (wraps to 0), // which is acceptable here. - mptoken[sfConfidentialBalanceVersion] = mptoken[~sfConfidentialBalanceVersion].value_or(0u) + 1u; + mptoken[sfConfidentialBalanceVersion] = + mptoken[~sfConfidentialBalanceVersion].value_or(0u) + 1u; } /** diff --git a/include/xrpl/tx/transactors/token/ConfidentialMPTClawback.h b/include/xrpl/tx/transactors/token/ConfidentialMPTClawback.h index 40e1577590..779d372a48 100644 --- a/include/xrpl/tx/transactors/token/ConfidentialMPTClawback.h +++ b/include/xrpl/tx/transactors/token/ConfidentialMPTClawback.h @@ -40,4 +40,3 @@ public: }; } // namespace xrpl - diff --git a/include/xrpl/tx/transactors/token/ConfidentialMPTConvert.h b/include/xrpl/tx/transactors/token/ConfidentialMPTConvert.h index 719cedbefc..1f939b9037 100644 --- a/include/xrpl/tx/transactors/token/ConfidentialMPTConvert.h +++ b/include/xrpl/tx/transactors/token/ConfidentialMPTConvert.h @@ -42,4 +42,3 @@ public: }; } // namespace xrpl - diff --git a/include/xrpl/tx/transactors/token/ConfidentialMPTConvertBack.h b/include/xrpl/tx/transactors/token/ConfidentialMPTConvertBack.h index 5b4aa889e2..e0a59f78e5 100644 --- a/include/xrpl/tx/transactors/token/ConfidentialMPTConvertBack.h +++ b/include/xrpl/tx/transactors/token/ConfidentialMPTConvertBack.h @@ -43,4 +43,3 @@ public: }; } // namespace xrpl - diff --git a/include/xrpl/tx/transactors/token/ConfidentialMPTMergeInbox.h b/include/xrpl/tx/transactors/token/ConfidentialMPTMergeInbox.h index 2e4141ef0a..58ff9489cc 100644 --- a/include/xrpl/tx/transactors/token/ConfidentialMPTMergeInbox.h +++ b/include/xrpl/tx/transactors/token/ConfidentialMPTMergeInbox.h @@ -44,4 +44,3 @@ public: }; } // namespace xrpl - diff --git a/include/xrpl/tx/transactors/token/ConfidentialMPTSend.h b/include/xrpl/tx/transactors/token/ConfidentialMPTSend.h index f80dcfb827..8dca8716d1 100644 --- a/include/xrpl/tx/transactors/token/ConfidentialMPTSend.h +++ b/include/xrpl/tx/transactors/token/ConfidentialMPTSend.h @@ -50,4 +50,3 @@ public: }; } // namespace xrpl - diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index 931b7b0ac2..4f57f19e60 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -524,7 +524,8 @@ accountHolds( // Only if auth check is needed, as it needs to do an additional read // operation. Note featureSingleAssetVault will affect error codes. if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED && - (view.rules().enabled(featureSingleAssetVault) || view.rules().enabled(featureConfidentialTransfer))) + (view.rules().enabled(featureSingleAssetVault) || + view.rules().enabled(featureConfidentialTransfer))) { if (auto const err = requireAuth(view, mptIssue, account, AuthType::StrongAuth); !isTesSuccess(err)) diff --git a/src/libxrpl/protocol/ConfidentialTransfer.cpp b/src/libxrpl/protocol/ConfidentialTransfer.cpp index d6e4529f0e..e037e68e67 100644 --- a/src/libxrpl/protocol/ConfidentialTransfer.cpp +++ b/src/libxrpl/protocol/ConfidentialTransfer.cpp @@ -95,7 +95,10 @@ makeEcPair(Slice const& buffer, secp256k1_pubkey& out1, secp256k1_pubkey& out2) auto parsePubKey = [](Slice const& slice, secp256k1_pubkey& out) { return secp256k1_ec_pubkey_parse( - secp256k1Context(), &out, reinterpret_cast(slice.data()), slice.length()); + secp256k1Context(), + &out, + reinterpret_cast(slice.data()), + slice.length()); }; Slice s1{buffer.data(), ecGamalEncryptedLength}; @@ -112,7 +115,8 @@ serializeEcPair(secp256k1_pubkey const& in1, secp256k1_pubkey const& in2, Buffer { auto serializePubKey = [](secp256k1_pubkey const& pub, unsigned char* out) { size_t outLen = ecGamalEncryptedLength; // 33 bytes - int const ret = secp256k1_ec_pubkey_serialize(secp256k1Context(), out, &outLen, &pub, SECP256K1_EC_COMPRESSED); + int const ret = secp256k1_ec_pubkey_serialize( + secp256k1Context(), out, &outLen, &pub, SECP256K1_EC_COMPRESSED); return ret == 1 && outLen == ecGamalEncryptedLength; }; @@ -188,7 +192,8 @@ homomorphicSubtract(Slice const& a, Slice const& b, Buffer& out) secp256k1_pubkey diffC1; secp256k1_pubkey diffC2; - if (secp256k1_elgamal_subtract(secp256k1Context(), &diffC1, &diffC2, &aC1, &aC2, &bC1, &bC2) != 1) + if (secp256k1_elgamal_subtract(secp256k1Context(), &diffC1, &diffC2, &aC1, &aC2, &bC1, &bC2) != + 1) return tecINTERNAL; if (!serializeEcPair(diffC1, diffC2, out)) @@ -219,10 +224,12 @@ encryptAmount(uint64_t const amt, Slice const& pubKeySlice, Slice const& blindin return std::nullopt; secp256k1_pubkey c1, c2, pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return std::nullopt; - if (!secp256k1_elgamal_encrypt(secp256k1Context(), &c1, &c2, &pubKey, amt, blindingFactor.data())) + if (!secp256k1_elgamal_encrypt( + secp256k1Context(), &c1, &c2, &pubKey, amt, blindingFactor.data())) return std::nullopt; Buffer buf(ecGamalEncryptedTotalLength); @@ -239,10 +246,12 @@ encryptCanonicalZeroAmount(Slice const& pubKeySlice, AccountID const& account, M return std::nullopt; // LCOV_EXCL_LINE secp256k1_pubkey c1, c2, pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return std::nullopt; // LCOV_EXCL_LINE - if (!generate_canonical_encrypted_zero(secp256k1Context(), &c1, &c2, &pubKey, account.data(), mptId.data())) + if (!generate_canonical_encrypted_zero( + secp256k1Context(), &c1, &c2, &pubKey, account.data(), mptId.data())) return std::nullopt; // LCOV_EXCL_LINE Buffer buf(ecGamalEncryptedTotalLength); @@ -262,10 +271,12 @@ verifySchnorrProof(Slice const& pubKeySlice, Slice const& proofSlice, uint256 co return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE - if (secp256k1_mpt_pok_sk_verify(secp256k1Context(), proofSlice.data(), &pubKey, contextHash.data()) != 1) + if (secp256k1_mpt_pok_sk_verify( + secp256k1Context(), proofSlice.data(), &pubKey, contextHash.data()) != 1) return tecBAD_PROOF; return tesSUCCESS; @@ -278,19 +289,21 @@ verifyElGamalEncryption( Slice const& pubKeySlice, Slice const& ciphertext) { - if (ciphertext.size() != ecGamalEncryptedTotalLength || blindingFactor.size() != ecBlindingFactorLength || - pubKeySlice.size() != ecPubKeyLength) + if (ciphertext.size() != ecGamalEncryptedTotalLength || + blindingFactor.size() != ecBlindingFactorLength || pubKeySlice.size() != ecPubKeyLength) return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey c1, c2; if (!makeEcPair(ciphertext, c1, c2)) return tecINTERNAL; // LCOV_EXCL_LINE - if (secp256k1_elgamal_verify_encryption(secp256k1Context(), &c1, &c2, &pubKey, amount, blindingFactor.data()) != 1) + if (secp256k1_elgamal_verify_encryption( + secp256k1Context(), &c1, &c2, &pubKey, amount, blindingFactor.data()) != 1) return tecBAD_PROOF; return tesSUCCESS; @@ -304,13 +317,15 @@ verifyRevealedAmount( ConfidentialRecipient const& issuer, std::optional const& auditor) { - if (auto const res = verifyElGamalEncryption(amount, blindingFactor, holder.publicKey, holder.encryptedAmount); + if (auto const res = verifyElGamalEncryption( + amount, blindingFactor, holder.publicKey, holder.encryptedAmount); !isTesSuccess(res)) { return res; } - if (auto const res = verifyElGamalEncryption(amount, blindingFactor, issuer.publicKey, issuer.encryptedAmount); + if (auto const res = verifyElGamalEncryption( + amount, blindingFactor, issuer.publicKey, issuer.encryptedAmount); !isTesSuccess(res)) { return res; @@ -318,8 +333,8 @@ verifyRevealedAmount( if (auditor) { - if (auto const res = - verifyElGamalEncryption(amount, blindingFactor, auditor->publicKey, auditor->encryptedAmount); + if (auto const res = verifyElGamalEncryption( + amount, blindingFactor, auditor->publicKey, auditor->encryptedAmount); !isTesSuccess(res)) { return res; @@ -361,28 +376,33 @@ verifyMultiCiphertextEqualityProof( // Parse Shared C1 from the first recipient only if (i == 0) { - if (!secp256k1_ec_pubkey_parse(ctx, &c1, recipient.encryptedAmount.data(), ecGamalEncryptedLength)) + if (!secp256k1_ec_pubkey_parse( + ctx, &c1, recipient.encryptedAmount.data(), ecGamalEncryptedLength)) return tecINTERNAL; // LCOV_EXCL_LINE } else { // All C1 bytes must be the same if (std::memcmp( - recipient.encryptedAmount.data(), recipients[0].encryptedAmount.data(), ecGamalEncryptedLength) != - 0) + recipient.encryptedAmount.data(), + recipients[0].encryptedAmount.data(), + ecGamalEncryptedLength) != 0) { return tecBAD_PROOF; } } if (secp256k1_ec_pubkey_parse( - ctx, &c2_vec[i], recipient.encryptedAmount.data() + ecGamalEncryptedLength, ecGamalEncryptedLength) != - 1) + ctx, + &c2_vec[i], + recipient.encryptedAmount.data() + ecGamalEncryptedLength, + ecGamalEncryptedLength) != 1) { return tecINTERNAL; // LCOV_EXCL_LINE } - if (secp256k1_ec_pubkey_parse(ctx, &pk_vec[i], recipient.publicKey.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + ctx, &pk_vec[i], recipient.publicKey.data(), ecPubKeyLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE } @@ -412,7 +432,8 @@ verifyClawbackEqualityProof( return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE // Note: c2, c1 order - the proof is generated with c2 first (the encrypted @@ -433,7 +454,8 @@ checkEncryptedAmountFormat(STObject const& object) // Current usage of this function is only for ConfidentialMPTConvert and // ConfidentialMPTConvertBack transactions, which already enforce that these fields // are present. - if (!object.isFieldPresent(sfHolderEncryptedAmount) || !object.isFieldPresent(sfIssuerEncryptedAmount)) + if (!object.isFieldPresent(sfHolderEncryptedAmount) || + !object.isFieldPresent(sfIssuerEncryptedAmount)) return temMALFORMED; // LCOV_EXCL_LINE if (object[sfHolderEncryptedAmount].length() != ecGamalEncryptedTotalLength || @@ -444,7 +466,8 @@ checkEncryptedAmountFormat(STObject const& object) if (hasAuditor && object[sfAuditorEncryptedAmount].length() != ecGamalEncryptedTotalLength) return temBAD_CIPHERTEXT; - if (!isValidCiphertext(object[sfHolderEncryptedAmount]) || !isValidCiphertext(object[sfIssuerEncryptedAmount])) + if (!isValidCiphertext(object[sfHolderEncryptedAmount]) || + !isValidCiphertext(object[sfIssuerEncryptedAmount])) return temBAD_CIPHERTEXT; if (hasAuditor && !isValidCiphertext(object[sfAuditorEncryptedAmount])) @@ -475,11 +498,13 @@ verifyAmountPcmLinkage( return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pcm; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pcm, pcmSlice.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pcm, pcmSlice.data(), ecPedersenCommitmentLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE if (secp256k1_elgamal_pedersen_link_verify( @@ -515,11 +540,13 @@ verifyBalancePcmLinkage( return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pubKey; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pubKey, pubKeySlice.data(), ecPubKeyLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE secp256k1_pubkey pcm; - if (secp256k1_ec_pubkey_parse(secp256k1Context(), &pcm, pcmSlice.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse( + secp256k1Context(), &pcm, pcmSlice.data(), ecPedersenCommitmentLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE // Note: c2, c1 order - the linkage proof expects the message-containing @@ -545,7 +572,8 @@ verifyAggregatedBulletproof( if (m != 1 && m != 2) return tecINTERNAL; // LCOV_EXCL_LINE - std::size_t const expectedProofLen = (m == 1) ? ecSingleBulletproofLength : ecDoubleBulletproofLength; + std::size_t const expectedProofLen = + (m == 1) ? ecSingleBulletproofLength : ecDoubleBulletproofLength; if (proof.size() != expectedProofLen) return tecINTERNAL; // LCOV_EXCL_LINE @@ -559,7 +587,10 @@ verifyAggregatedBulletproof( return tecINTERNAL; // LCOV_EXCL_LINE if (secp256k1_ec_pubkey_parse( - ctx, &commitments[i], compressedCommitments[i].data(), ecPedersenCommitmentLength) != 1) + ctx, + &commitments[i], + compressedCommitments[i].data(), + ecPedersenCommitmentLength) != 1) return tecINTERNAL; // LCOV_EXCL_LINE } @@ -608,17 +639,20 @@ verifyAggregatedBulletproof( TER computeSendRemainder(Slice const& balanceCommitment, Slice const& amountCommitment, Buffer& out) { - if (balanceCommitment.size() != ecPedersenCommitmentLength || amountCommitment.size() != ecPedersenCommitmentLength) + if (balanceCommitment.size() != ecPedersenCommitmentLength || + amountCommitment.size() != ecPedersenCommitmentLength) return tecINTERNAL; auto const ctx = secp256k1Context(); secp256k1_pubkey pcBalance; - if (secp256k1_ec_pubkey_parse(ctx, &pcBalance, balanceCommitment.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse( + ctx, &pcBalance, balanceCommitment.data(), ecPedersenCommitmentLength) != 1) return tecINTERNAL; secp256k1_pubkey pcAmount; - if (secp256k1_ec_pubkey_parse(ctx, &pcAmount, amountCommitment.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse( + ctx, &pcAmount, amountCommitment.data(), ecPedersenCommitmentLength) != 1) return tecINTERNAL; // Negate PC_amount point to get -PC_amount @@ -634,7 +668,8 @@ computeSendRemainder(Slice const& balanceCommitment, Slice const& amountCommitme // Serialize result to compressed format out.alloc(ecPedersenCommitmentLength); size_t outLen = ecPedersenCommitmentLength; - if (secp256k1_ec_pubkey_serialize(ctx, out.data(), &outLen, &pcRem, SECP256K1_EC_COMPRESSED) != 1) + if (secp256k1_ec_pubkey_serialize(ctx, out.data(), &outLen, &pcRem, SECP256K1_EC_COMPRESSED) != + 1) return tecINTERNAL; return tesSUCCESS; @@ -650,7 +685,8 @@ computeConvertBackRemainder(Slice const& commitment, std::uint64_t amount, Buffe // Parse commitment from compressed format secp256k1_pubkey pcBalance; - if (secp256k1_ec_pubkey_parse(ctx, &pcBalance, commitment.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse(ctx, &pcBalance, commitment.data(), ecPedersenCommitmentLength) != + 1) return tecINTERNAL; // LCOV_EXCL_LINE // Convert amount to 32-byte big-endian scalar @@ -676,7 +712,8 @@ computeConvertBackRemainder(Slice const& commitment, std::uint64_t amount, Buffe // Serialize result to compressed format out.alloc(ecPedersenCommitmentLength); size_t outLen = ecPedersenCommitmentLength; - if (secp256k1_ec_pubkey_serialize(ctx, out.data(), &outLen, &pcRem, SECP256K1_EC_COMPRESSED) != 1 || + if (secp256k1_ec_pubkey_serialize(ctx, out.data(), &outLen, &pcRem, SECP256K1_EC_COMPRESSED) != + 1 || outLen != ecPedersenCommitmentLength) return tecINTERNAL; // LCOV_EXCL_LINE diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp index 4f11ca5f02..548e6ddc00 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvert.cpp @@ -137,8 +137,9 @@ ConfidentialMPTConvert::preclaim(PreclaimContext const& ctx) std::optional auditor; if (hasAuditor) { - auditor.emplace(ConfidentialRecipient{ - (*sleIssuance)[sfAuditorElGamalPublicKey], ctx.tx[sfAuditorEncryptedAmount]}); + auditor.emplace( + ConfidentialRecipient{ + (*sleIssuance)[sfAuditorElGamalPublicKey], ctx.tx[sfAuditorEncryptedAmount]}); } return verifyRevealedAmount( diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp index dcebe29c9b..b01477694c 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTConvertBack.cpp @@ -81,8 +81,9 @@ verifyProofs( bool const hasAuditor = issuance->isFieldPresent(sfAuditorElGamalPublicKey); if (hasAuditor) { - auditor.emplace(ConfidentialRecipient{ - (*issuance)[sfAuditorElGamalPublicKey], tx[sfAuditorEncryptedAmount]}); + auditor.emplace( + ConfidentialRecipient{ + (*issuance)[sfAuditorElGamalPublicKey], tx[sfAuditorEncryptedAmount]}); } // Run all verifications before returning any error to prevent timing attacks diff --git a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp index 8ee4d394b5..de2b9dc1c7 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp @@ -74,11 +74,13 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx) if (ctx.view.rules().enabled(featureConfidentialTransfer)) { - auto const sleMptIssuance = ctx.view.read(keylet::mptIssuance(ctx.tx[sfMPTokenIssuanceID])); + auto const sleMptIssuance = + ctx.view.read(keylet::mptIssuance(ctx.tx[sfMPTokenIssuanceID])); // if there still existing encrypted balances of MPT in // circulation - if (sleMptIssuance && (*sleMptIssuance)[~sfConfidentialOutstandingAmount].value_or(0) != 0) + if (sleMptIssuance && + (*sleMptIssuance)[~sfConfidentialOutstandingAmount].value_or(0) != 0) { // this MPT still has encrypted balance, since we don't know // if it's non-zero or not, we won't allow deletion of diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp index 11448d7f83..676e11ec82 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp @@ -21,7 +21,8 @@ MPTokenIssuanceCreate::checkExtraFeatures(PreflightContext const& ctx) // can not set tmfMPTCannotMutatePrivacy without featureConfidentialTransfer auto const mutableFlags = ctx.tx[~sfMutableFlags]; - if (mutableFlags && (*mutableFlags & tmfMPTCannotMutatePrivacy) && !ctx.rules.enabled(featureConfidentialTransfer)) + if (mutableFlags && (*mutableFlags & tmfMPTCannotMutatePrivacy) && + !ctx.rules.enabled(featureConfidentialTransfer)) return false; return true; diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp index 20e2e7719e..27c01342c0 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp @@ -1,9 +1,9 @@ +#include #include #include #include #include #include -#include namespace xrpl { @@ -53,7 +53,8 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) auto const hasAuditorElGamalKey = ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey); auto const txFlags = ctx.tx.getFlags(); - auto const mutatePrivacy = mutableFlags && ((*mutableFlags & (tmfMPTSetPrivacy | tmfMPTClearPrivacy))); + auto const mutatePrivacy = + mutableFlags && ((*mutableFlags & (tmfMPTSetPrivacy | tmfMPTClearPrivacy))); auto const hasDomain = ctx.tx.isFieldPresent(sfDomainID); auto const hasHolder = ctx.tx.isFieldPresent(sfHolder); @@ -84,7 +85,8 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) ctx.rules.enabled(featureConfidentialTransfer)) { // Is this transaction actually changing anything ? - if (txFlags == 0 && !hasDomain && !hasIssuerElGamalKey && !hasAuditorElGamalKey && !isMutate) + if (txFlags == 0 && !hasDomain && !hasIssuerElGamalKey && !hasAuditorElGamalKey && + !isMutate) return temMALFORMED; } @@ -233,16 +235,19 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx) if (mutableFlags) { if (std::any_of( - mptMutabilityFlags.begin(), mptMutabilityFlags.end(), [mutableFlags, &isMutableFlag](auto const& f) { - bool const canMutate = - f.isCannotMutate ? isMutableFlag(f.mutabilityFlag) : !isMutableFlag(f.mutabilityFlag); + mptMutabilityFlags.begin(), + mptMutabilityFlags.end(), + [mutableFlags, &isMutableFlag](auto const& f) { + bool const canMutate = f.isCannotMutate ? isMutableFlag(f.mutabilityFlag) + : !isMutableFlag(f.mutabilityFlag); return canMutate && (*mutableFlags & (f.setFlag | f.clearFlag)); })) return tecNO_PERMISSION; if ((*mutableFlags & tmfMPTSetPrivacy) || (*mutableFlags & tmfMPTClearPrivacy)) { - std::uint64_t const confidentialOA = (*sleMptIssuance)[~sfConfidentialOutstandingAmount].value_or(0); + std::uint64_t const confidentialOA = + (*sleMptIssuance)[~sfConfidentialOutstandingAmount].value_or(0); // If there's any confidential outstanding amount, disallow toggling // the lsfMPTCanPrivacy flag @@ -268,29 +273,34 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx) } // cannot update issuer public key - if (ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey) && sleMptIssuance->isFieldPresent(sfIssuerElGamalPublicKey)) + if (ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey) && + sleMptIssuance->isFieldPresent(sfIssuerElGamalPublicKey)) { return tecNO_PERMISSION; } // cannot update auditor public key - if (ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey) && sleMptIssuance->isFieldPresent(sfAuditorElGamalPublicKey)) + if (ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey) && + sleMptIssuance->isFieldPresent(sfAuditorElGamalPublicKey)) { return tecNO_PERMISSION; // LCOV_EXCL_LINE } - if (ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey) && !sleMptIssuance->isFlag(lsfMPTCanPrivacy)) + if (ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey) && + !sleMptIssuance->isFlag(lsfMPTCanPrivacy)) { return tecNO_PERMISSION; } - if (ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey) && !sleMptIssuance->isFlag(lsfMPTCanPrivacy)) + if (ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey) && + !sleMptIssuance->isFlag(lsfMPTCanPrivacy)) { return tecNO_PERMISSION; } // cannot upload key if there's circulating supply of COA - if ((ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey) || ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey)) && + if ((ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey) || + ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey)) && sleMptIssuance->isFieldPresent(sfConfidentialOutstandingAmount)) { return tecNO_PERMISSION; // LCOV_EXCL_LINE @@ -386,7 +396,9 @@ MPTokenIssuanceSet::doApply() if (auto const pubKey = ctx_.tx[~sfIssuerElGamalPublicKey]) { // This is enforced in preflight. - XRPL_ASSERT(sle->getType() == ltMPTOKEN_ISSUANCE, "MPTokenIssuanceSet::doApply : modifying MPTokenIssuance"); + XRPL_ASSERT( + sle->getType() == ltMPTOKEN_ISSUANCE, + "MPTokenIssuanceSet::doApply : modifying MPTokenIssuance"); sle->setFieldVL(sfIssuerElGamalPublicKey, *pubKey); } @@ -394,7 +406,9 @@ MPTokenIssuanceSet::doApply() if (auto const pubKey = ctx_.tx[~sfAuditorElGamalPublicKey]) { // This is enforced in preflight. - XRPL_ASSERT(sle->getType() == ltMPTOKEN_ISSUANCE, "MPTokenIssuanceSet::doApply : modifying MPTokenIssuance"); + XRPL_ASSERT( + sle->getType() == ltMPTOKEN_ISSUANCE, + "MPTokenIssuanceSet::doApply : modifying MPTokenIssuance"); sle->setFieldVL(sfAuditorElGamalPublicKey, *pubKey); } diff --git a/src/test/app/ConfidentialTransfer_test.cpp b/src/test/app/ConfidentialTransfer_test.cpp index 40096d01b7..293d76cee2 100644 --- a/src/test/app/ConfidentialTransfer_test.cpp +++ b/src/test/app/ConfidentialTransfer_test.cpp @@ -72,7 +72,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite getTrivialSendProofHex(size_t nRecipients) { size_t const sizeEquality = secp256k1_mpt_proof_equality_shared_r_size(nRecipients); - size_t const totalSize = sizeEquality + (2 * ecPedersenProofLength) + ecDoubleBulletproofLength; + size_t const totalSize = + sizeEquality + (2 * ecPedersenProofLength) + ecDoubleBulletproofLength; Buffer buf(totalSize); std::memset(buf.data(), 0, totalSize); @@ -100,7 +101,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -140,7 +142,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 1); @@ -170,7 +173,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, maxMPTokenAmount); @@ -189,8 +193,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Second convert with maxMPTokenAmount using raw JSON Buffer const blindingFactor = generateBlindingFactor(); - auto const holderCiphertext = mptAlice.encryptAmount(bob, maxMPTokenAmount, blindingFactor); - auto const issuerCiphertext = mptAlice.encryptAmount(alice, maxMPTokenAmount, blindingFactor); + auto const holderCiphertext = + mptAlice.encryptAmount(bob, maxMPTokenAmount, blindingFactor); + auto const issuerCiphertext = + mptAlice.encryptAmount(alice, maxMPTokenAmount, blindingFactor); Json::Value jv; jv[jss::Account] = bob.human(); @@ -220,7 +226,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const auditor("auditor"); MPTTester mptAlice(env, alice, {.holders = {bob}, .auditor = auditor}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -268,7 +275,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(alice); mptAlice.convert( - {.account = alice, .amt = 10, .holderPubKey = mptAlice.getPubKey(alice), .err = temMALFORMED}); + {.account = alice, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(alice), + .err = temMALFORMED}); } { @@ -285,9 +295,14 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(alice); mptAlice.generateKeyPair(bob); - mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice), .err = temDISABLED}); + mptAlice.set( + {.account = alice, .issuerPubKey = mptAlice.getPubKey(alice), .err = temDISABLED}); - mptAlice.convert({.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = temDISABLED}); + mptAlice.convert( + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = temDISABLED}); } { @@ -305,7 +320,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(bob); mptAlice.convert( - {.account = alice, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = temMALFORMED}); + {.account = alice, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = temMALFORMED}); // blinding factor length is invalid mptAlice.convert( @@ -372,11 +390,15 @@ class ConfidentialTransfer_test : public beast::unit_test::suite .err = temBAD_CIPHERTEXT}); // Holder public key is invalid (empty buffer) - mptAlice.convert({.account = bob, .amt = 10, .holderPubKey = Buffer{}, .err = temMALFORMED}); + mptAlice.convert( + {.account = bob, .amt = 10, .holderPubKey = Buffer{}, .err = temMALFORMED}); // Holder public key has correct length but invalid EC point data mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = makeZeroBuffer(ecPubKeyLength), .err = temMALFORMED}); + {.account = bob, + .amt = 10, + .holderPubKey = makeZeroBuffer(ecPubKeyLength), + .err = temMALFORMED}); } // when registering holder pub key, the transaction must include a @@ -387,7 +409,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -428,7 +451,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -447,7 +471,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite }); // proof must not be provided after pub key was registered - mptAlice.convert({.account = bob, .amt = 20, .fillSchnorrProof = true, .err = temMALFORMED}); + mptAlice.convert( + {.account = bob, .amt = 20, .fillSchnorrProof = true, .err = temMALFORMED}); } } @@ -471,7 +496,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(alice); mptAlice.generateKeyPair(bob); - mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice), .err = temDISABLED}); + mptAlice.set( + {.account = alice, .issuerPubKey = mptAlice.getPubKey(alice), .err = temDISABLED}); } // pub key is invalid @@ -481,7 +507,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -493,7 +520,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.set({.account = alice, .issuerPubKey = Buffer{}, .err = temMALFORMED}); // Issuer pub key has correct length but invalid EC point data - mptAlice.set({.account = alice, .issuerPubKey = makeZeroBuffer(ecPubKeyLength), .err = temMALFORMED}); + mptAlice.set( + {.account = alice, + .issuerPubKey = makeZeroBuffer(ecPubKeyLength), + .err = temMALFORMED}); // Auditor key is invalid length mptAlice.set( @@ -510,15 +540,24 @@ class ConfidentialTransfer_test : public beast::unit_test::suite .err = temMALFORMED}); // Cannot set auditor key without issuer key - mptAlice.set({.account = alice, .auditorPubKey = mptAlice.getPubKey(alice), .err = temMALFORMED}); + mptAlice.set( + {.account = alice, + .auditorPubKey = mptAlice.getPubKey(alice), + .err = temMALFORMED}); // Cannot set Holder and issuer Keys in the same transaction mptAlice.set( - {.account = alice, .holder = bob, .issuerPubKey = mptAlice.getPubKey(alice), .err = temMALFORMED}); + {.account = alice, + .holder = bob, + .issuerPubKey = mptAlice.getPubKey(alice), + .err = temMALFORMED}); // Cannot set Holder and auditor Keys in the same transaction mptAlice.set( - {.account = alice, .holder = bob, .auditorPubKey = mptAlice.getPubKey(alice), .err = temMALFORMED}); + {.account = alice, + .holder = bob, + .auditorPubKey = mptAlice.getPubKey(alice), + .err = temMALFORMED}); } // issuance has disabled confidential transfer @@ -537,7 +576,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(alice); mptAlice.generateKeyPair(bob); - mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice), .err = tecNO_PERMISSION}); + mptAlice.set( + {.account = alice, + .issuerPubKey = mptAlice.getPubKey(alice), + .err = tecNO_PERMISSION}); } } @@ -563,7 +605,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(bob); mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecNO_PERMISSION}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecNO_PERMISSION}); } // issuer has not uploaded their sfIssuerElGamalPublicKey @@ -573,7 +618,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -582,7 +628,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(bob); mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecNO_PERMISSION}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecNO_PERMISSION}); } // issuance does not exist @@ -592,7 +641,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.generateKeyPair(alice); @@ -603,7 +653,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(bob); mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecOBJECT_NOT_FOUND}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecOBJECT_NOT_FOUND}); } // bob has not created MPToken @@ -613,7 +666,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.generateKeyPair(alice); mptAlice.generateKeyPair(bob); @@ -621,7 +675,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice)}); mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecOBJECT_NOT_FOUND}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecOBJECT_NOT_FOUND}); } // Verification of Issuer and and holder ciphertexts @@ -631,7 +688,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -663,7 +721,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -675,7 +734,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(bob); mptAlice.convert( - {.account = bob, .amt = 200, .holderPubKey = mptAlice.getPubKey(bob), .err = tecINSUFFICIENT_FUNDS}); + {.account = bob, + .amt = 200, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecINSUFFICIENT_FUNDS}); } // holder cannot upload pk again @@ -685,7 +747,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -699,7 +762,11 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.convert({.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob)}); // cannot upload pk again - mptAlice.convert({.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecDUPLICATE}); + mptAlice.convert( + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecDUPLICATE}); } // cannot convert if locked @@ -709,7 +776,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -723,7 +791,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(bob); mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecINSUFFICIENT_FUNDS}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecINSUFFICIENT_FUNDS}); mptAlice.set({.account = alice, .holder = bob, .flags = tfMPTUnlock}); @@ -742,7 +813,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanPrivacy}); + {.ownerCount = 1, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = alice, .holder = bob}); @@ -758,7 +830,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.authorize({.account = alice, .holder = bob, .flags = tfMPTUnauthorize}); mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecINSUFFICIENT_FUNDS}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecINSUFFICIENT_FUNDS}); // auth bob mptAlice.authorize({ @@ -782,7 +857,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const auditor("auditor"); MPTTester mptAlice(env, alice, {.holders = {bob}, .auditor = auditor}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -813,7 +889,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -870,7 +947,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -899,7 +977,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -931,7 +1010,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -969,7 +1049,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.generateKeyPair(alice); @@ -1007,7 +1088,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.generateKeyPair(alice); @@ -1023,7 +1105,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -1049,7 +1132,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const carol("carol"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -1117,7 +1201,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const auditor("auditor"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}, .auditor = auditor}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -1409,7 +1494,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob, carol, dave, eve}}); // authorize bob, carol, dave (not eve) - mptAlice.create({.flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanPrivacy}); + mptAlice.create( + {.flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = alice, .holder = bob}); mptAlice.authorize({.account = carol}); @@ -1428,8 +1514,16 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice)}); // bob and carol convert some funds to confidential - mptAlice.convert({.account = bob, .amt = 60, .holderPubKey = mptAlice.getPubKey(bob), .err = tesSUCCESS}); - mptAlice.convert({.account = carol, .amt = 20, .holderPubKey = mptAlice.getPubKey(carol), .err = tesSUCCESS}); + mptAlice.convert( + {.account = bob, + .amt = 60, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tesSUCCESS}); + mptAlice.convert( + {.account = carol, + .amt = 20, + .holderPubKey = mptAlice.getPubKey(carol), + .err = tesSUCCESS}); // bob and carol merge inbox mptAlice.mergeInbox({ @@ -1612,7 +1706,11 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice)}); // Convert 60 out of 100 - mptAlice.convert({.account = bob, .amt = 60, .holderPubKey = mptAlice.getPubKey(bob), .err = tesSUCCESS}); + mptAlice.convert( + {.account = bob, + .amt = 60, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tesSUCCESS}); // bob merge inbox mptAlice.mergeInbox({ @@ -1620,7 +1718,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite }); mptAlice.convert( - {.account = carol, .amt = 20, .holderPubKey = mptAlice.getPubKey(carol), .err = tesSUCCESS}); + {.account = carol, + .amt = 20, + .holderPubKey = mptAlice.getPubKey(carol), + .err = tesSUCCESS}); // carol merge inbox mptAlice.mergeInbox({ @@ -1643,7 +1744,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const carol("carol"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanLock | tfMPTCanPrivacy | tfMPTCanTransfer}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanLock | tfMPTCanPrivacy | tfMPTCanTransfer}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -1657,21 +1759,32 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice)}); - mptAlice.convert({.account = bob, .amt = 60, .holderPubKey = mptAlice.getPubKey(bob), .err = tesSUCCESS}); + mptAlice.convert( + {.account = bob, + .amt = 60, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tesSUCCESS}); mptAlice.mergeInbox({ .account = bob, }); mptAlice.convert( - {.account = carol, .amt = 20, .holderPubKey = mptAlice.getPubKey(carol), .err = tesSUCCESS}); + {.account = carol, + .amt = 20, + .holderPubKey = mptAlice.getPubKey(carol), + .err = tesSUCCESS}); mptAlice.mergeInbox({ .account = carol, }); mptAlice.send( - {.account = bob, .dest = carol, .amt = 10, .proof = getTrivialSendProofHex(3), .err = tecBAD_PROOF}); + {.account = bob, + .dest = carol, + .amt = 10, + .proof = getTrivialSendProofHex(3), + .err = tecBAD_PROOF}); } // No Auditor key set, but auditor encrypted amt provided @@ -1746,7 +1859,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const carol("carol"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanLock | tfMPTCanPrivacy | tfMPTCanTransfer}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanLock | tfMPTCanPrivacy | tfMPTCanTransfer}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -1764,7 +1878,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.convert({.account = bob, .amt = 60, .holderPubKey = mptAlice.getPubKey(bob)}); mptAlice.mergeInbox({.account = bob}); - mptAlice.convert({.account = carol, .amt = 50, .holderPubKey = mptAlice.getPubKey(carol)}); + mptAlice.convert( + {.account = carol, .amt = 50, .holderPubKey = mptAlice.getPubKey(carol)}); mptAlice.mergeInbox({.account = carol}); // Bob has 60, tries to send 70. Invalid remaining balance. @@ -1812,7 +1927,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -1829,7 +1945,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite .holderPubKey = mptAlice.getPubKey(bob), }); - mptAlice.authorize({.account = bob, .flags = tfMPTUnauthorize, .err = tecHAS_OBLIGATIONS}); + mptAlice.authorize( + {.account = bob, .flags = tfMPTUnauthorize, .err = tecHAS_OBLIGATIONS}); } // cannot delete mptoken where it has encrypted balance @@ -1840,7 +1957,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const carol("carol"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -1866,7 +1984,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite }); // carol cannot delete even if he has encrypted zero amount - mptAlice.authorize({.account = carol, .flags = tfMPTUnauthorize, .err = tecHAS_OBLIGATIONS}); + mptAlice.authorize( + {.account = carol, .flags = tfMPTUnauthorize, .err = tecHAS_OBLIGATIONS}); } // can delete mptoken if outstanding confidential balance is zero @@ -1876,7 +1995,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.generateKeyPair(alice); @@ -1905,7 +2025,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.generateKeyPair(alice); @@ -1935,7 +2056,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -1979,7 +2101,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -2018,7 +2141,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 2); @@ -2047,14 +2171,16 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Edge case: maxMPTokenAmount // Using raw JSON to avoid automatic decryption checks in MPTTester // which don't work for very large amounts (brute-force decryption is slow) - // TODO: improve this test once there is bounded decryption or optimized decryption for large amounts + // TODO: improve this test once there is bounded decryption or optimized decryption for + // large amounts { Env env{*this, features}; Account const alice("alice"); Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, maxMPTokenAmount); @@ -2066,9 +2192,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Convert maxMPTokenAmount to confidential using raw JSON Buffer const convertBlindingFactor = generateBlindingFactor(); - auto const convertHolderCiphertext = mptAlice.encryptAmount(bob, maxMPTokenAmount, convertBlindingFactor); - auto const convertIssuerCiphertext = mptAlice.encryptAmount(alice, maxMPTokenAmount, convertBlindingFactor); - auto const convertContextHash = getConvertContextHash(bob.id(), mptAlice.issuanceID(), env.seq(bob)); + auto const convertHolderCiphertext = + mptAlice.encryptAmount(bob, maxMPTokenAmount, convertBlindingFactor); + auto const convertIssuerCiphertext = + mptAlice.encryptAmount(alice, maxMPTokenAmount, convertBlindingFactor); + auto const convertContextHash = + getConvertContextHash(bob.id(), mptAlice.issuanceID(), env.seq(bob)); auto const schnorrProof = mptAlice.getSchnorrProof(bob, convertContextHash); BEAST_EXPECT(schnorrProof.has_value()); @@ -2115,7 +2244,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Generate pedersen commitment for the known spending balance Buffer const pcBlindingFactor = generateBlindingFactor(); - Buffer const pedersenCommitment = mptAlice.getPedersenCommitment(maxMPTokenAmount, pcBlindingFactor); + Buffer const pedersenCommitment = + mptAlice.getPedersenCommitment(maxMPTokenAmount, pcBlindingFactor); // Generate the proof using known spending balance value auto const version = mptAlice.getMPTokenVersion(bob); @@ -2165,7 +2295,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const auditor("auditor"); MPTTester mptAlice(env, alice, {.holders = {bob}, .auditor = auditor}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -2225,7 +2356,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -2250,10 +2382,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.convertBack({.account = bob, .amt = 0, .err = temBAD_AMOUNT}); - mptAlice.convertBack({.account = bob, .amt = maxMPTokenAmount + 1, .err = temBAD_AMOUNT}); + mptAlice.convertBack( + {.account = bob, .amt = maxMPTokenAmount + 1, .err = temBAD_AMOUNT}); // invalid blinding factor length - mptAlice.convertBack({.account = alice, .amt = 30, .blindingFactor = Buffer{}, .err = temMALFORMED}); + mptAlice.convertBack( + {.account = alice, .amt = 30, .blindingFactor = Buffer{}, .err = temMALFORMED}); // Balance commitment has correct length but invalid EC point data mptAlice.convertBack( @@ -2262,26 +2396,48 @@ class ConfidentialTransfer_test : public beast::unit_test::suite .pedersenCommitment = makeZeroBuffer(ecPedersenCommitmentLength), .err = temMALFORMED}); - mptAlice.convertBack({.account = bob, .amt = 30, .holderEncryptedAmt = Buffer{}, .err = temBAD_CIPHERTEXT}); - - mptAlice.convertBack({.account = bob, .amt = 30, .issuerEncryptedAmt = Buffer{}, .err = temBAD_CIPHERTEXT}); + mptAlice.convertBack( + {.account = bob, + .amt = 30, + .holderEncryptedAmt = Buffer{}, + .err = temBAD_CIPHERTEXT}); mptAlice.convertBack( - {.account = bob, .amt = 30, .holderEncryptedAmt = getBadCiphertext(), .err = temBAD_CIPHERTEXT}); + {.account = bob, + .amt = 30, + .issuerEncryptedAmt = Buffer{}, + .err = temBAD_CIPHERTEXT}); mptAlice.convertBack( - {.account = bob, .amt = 30, .issuerEncryptedAmt = getBadCiphertext(), .err = temBAD_CIPHERTEXT}); + {.account = bob, + .amt = 30, + .holderEncryptedAmt = getBadCiphertext(), + .err = temBAD_CIPHERTEXT}); mptAlice.convertBack( - {.account = bob, .amt = 30, .auditorEncryptedAmt = makeZeroBuffer(10), .err = temBAD_CIPHERTEXT}); + {.account = bob, + .amt = 30, + .issuerEncryptedAmt = getBadCiphertext(), + .err = temBAD_CIPHERTEXT}); mptAlice.convertBack( - {.account = bob, .amt = 30, .auditorEncryptedAmt = getBadCiphertext(), .err = temBAD_CIPHERTEXT}); + {.account = bob, + .amt = 30, + .auditorEncryptedAmt = makeZeroBuffer(10), + .err = temBAD_CIPHERTEXT}); + + mptAlice.convertBack( + {.account = bob, + .amt = 30, + .auditorEncryptedAmt = getBadCiphertext(), + .err = temBAD_CIPHERTEXT}); // invalid proof length - mptAlice.convertBack({.account = bob, .amt = 30, .proof = Buffer{}, .err = temMALFORMED}); + mptAlice.convertBack( + {.account = bob, .amt = 30, .proof = Buffer{}, .err = temMALFORMED}); - mptAlice.convertBack({.account = bob, .amt = 30, .proof = makeZeroBuffer(100), .err = temMALFORMED}); + mptAlice.convertBack( + {.account = bob, .amt = 30, .proof = makeZeroBuffer(100), .err = temMALFORMED}); } } @@ -2298,7 +2454,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.generateKeyPair(alice); @@ -2336,7 +2493,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.generateKeyPair(alice); mptAlice.generateKeyPair(bob); @@ -2353,7 +2511,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -2375,7 +2534,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const carol("carol"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -2416,7 +2576,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanPrivacy}); + {.ownerCount = 1, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = alice, .holder = bob}); @@ -2467,7 +2628,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -2479,13 +2641,21 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.convert({.account = bob, .amt = 50, .holderPubKey = mptAlice.getPubKey(bob)}); mptAlice.mergeInbox({.account = bob}); - // Holder encrypted amount is valid format but mathematically incorrect for this convertBack + // Holder encrypted amount is valid format but mathematically incorrect for this + // convertBack mptAlice.convertBack( - {.account = bob, .amt = 10, .holderEncryptedAmt = getTrivialCiphertext(), .err = tecBAD_PROOF}); + {.account = bob, + .amt = 10, + .holderEncryptedAmt = getTrivialCiphertext(), + .err = tecBAD_PROOF}); - // Issuer encrypted amount is valid format but mathematically incorrect for this convertBack + // Issuer encrypted amount is valid format but mathematically incorrect for this + // convertBack mptAlice.convertBack( - {.account = bob, .amt = 10, .issuerEncryptedAmt = getTrivialCiphertext(), .err = tecBAD_PROOF}); + {.account = bob, + .amt = 10, + .issuerEncryptedAmt = getTrivialCiphertext(), + .err = tecBAD_PROOF}); } // Alice has NOT set an auditor key, but Bob provides @@ -2496,7 +2666,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -2556,7 +2727,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // ConvertBack where auditor ciphertext mathematically // correct, but contains invalid data (mismatching amount). mptAlice.convertBack( - {.account = bob, .amt = 10, .auditorEncryptedAmt = getTrivialCiphertext(), .err = tecBAD_PROOF}); + {.account = bob, + .amt = 10, + .auditorEncryptedAmt = getTrivialCiphertext(), + .err = tecBAD_PROOF}); } } @@ -2590,7 +2764,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Common setup: create MPT with privacy, convert both carol and bob auto setupMPT = [&](Env& env, MPTTester& mpt) { - mpt.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mpt.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mpt.authorize({.account = bob}); mpt.authorize({.account = carol}); mpt.pay(alice, bob, 100); @@ -2657,7 +2832,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite auto const credIdx = createCredential(env, carol); // Carol cannot send yet - Bob hasn't authorized this credential type - mpt.send({.account = carol, .dest = bob, .amt = 10, .credentials = {{credIdx}}, .err = tecNO_PERMISSION}); + mpt.send( + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = {{credIdx}}, + .err = tecNO_PERMISSION}); // Bob authorizes the credential type from dpIssuer env(deposit::authCredentials(bob, {{dpIssuer, credType}})); @@ -2702,7 +2882,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mpt.send({.account = carol, .dest = bob, .amt = 10, .err = tecNO_PERMISSION}); // But credential-based auth not set up, so this also fails - mpt.send({.account = carol, .dest = bob, .amt = 10, .credentials = {{credIdx}}, .err = tecNO_PERMISSION}); + mpt.send( + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = {{credIdx}}, + .err = tecNO_PERMISSION}); // Bob authorizes the credential type env(deposit::authCredentials(bob, {{dpIssuer, credType}})); @@ -2740,7 +2925,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Common setup: create MPT with privacy, convert carol and bob to confidential auto setupBasic = [&](Env& env, MPTTester& mpt) { - mpt.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mpt.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mpt.authorize({.account = bob}); mpt.authorize({.account = carol}); mpt.pay(alice, bob, 100); @@ -2782,7 +2968,11 @@ class ConfidentialTransfer_test : public beast::unit_test::suite tooManyCredentials.push_back(to_string(uint256(i))); mpt.send( - {.account = carol, .dest = bob, .amt = 10, .credentials = tooManyCredentials, .err = temMALFORMED}); + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = tooManyCredentials, + .err = temMALFORMED}); } // TEST 3: Preflight - Duplicate Credentials @@ -2802,7 +2992,11 @@ class ConfidentialTransfer_test : public beast::unit_test::suite std::string const credIdx = jv[jss::result][jss::index].asString(); mpt.send( - {.account = carol, .dest = bob, .amt = 10, .credentials = {{credIdx, credIdx}}, .err = temMALFORMED}); + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = {{credIdx, credIdx}}, + .err = temMALFORMED}); } // TEST 4: Preclaim - Credential Doesn't Exist @@ -2813,7 +3007,11 @@ class ConfidentialTransfer_test : public beast::unit_test::suite std::string const fakeCredIdx = to_string(uint256(999)); mpt.send( - {.account = carol, .dest = bob, .amt = 10, .credentials = {{fakeCredIdx}}, .err = tecBAD_CREDENTIALS}); + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = {{fakeCredIdx}}, + .err = tecBAD_CREDENTIALS}); } // TEST 5: Preclaim - Credential Doesn't Belong to Source Account @@ -2833,7 +3031,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite auto const jv = credentials::ledgerEntry(env, bob, dpIssuer, credType); std::string const credIdx = jv[jss::result][jss::index].asString(); - mpt.send({.account = carol, .dest = bob, .amt = 10, .credentials = {{credIdx}}, .err = tecBAD_CREDENTIALS}); + mpt.send( + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = {{credIdx}}, + .err = tecBAD_CREDENTIALS}); } // TEST 6: Preclaim - Credential Not Accepted @@ -2851,7 +3054,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite auto const jv = credentials::ledgerEntry(env, carol, dpIssuer, credType); std::string const credIdx = jv[jss::result][jss::index].asString(); - mpt.send({.account = carol, .dest = bob, .amt = 10, .credentials = {{credIdx}}, .err = tecBAD_CREDENTIALS}); + mpt.send( + {.account = carol, + .dest = bob, + .amt = 10, + .credentials = {{credIdx}}, + .err = tecBAD_CREDENTIALS}); } } @@ -2868,7 +3076,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const dave("dave"); MPTTester mptAlice(env, alice, {.holders = {bob, carol, dave}}); - mptAlice.create({.flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanClawback | tfMPTCanPrivacy}); + mptAlice.create( + {.flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanClawback | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); mptAlice.authorize({.account = carol}); @@ -2898,7 +3107,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // after setup, carol's spending balance is 120, inbox balance is 0. { // carol converts 120 to confidential - mptAlice.convert({.account = carol, .amt = 120, .holderPubKey = mptAlice.getPubKey(carol)}); + mptAlice.convert( + {.account = carol, .amt = 120, .holderPubKey = mptAlice.getPubKey(carol)}); // carol merge inbox mptAlice.mergeInbox({ @@ -2946,7 +3156,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const auditor("auditor"); MPTTester mptAlice(env, alice, {.holders = {bob, carol, dave}, .auditor = auditor}); - mptAlice.create({.flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanClawback | tfMPTCanPrivacy}); + mptAlice.create( + {.flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanClawback | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); mptAlice.authorize({.account = carol}); @@ -2980,7 +3191,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // after setup, carol's spending balance is 120, inbox balance is 0. { // carol converts 120 to confidential - mptAlice.convert({.account = carol, .amt = 120, .holderPubKey = mptAlice.getPubKey(carol)}); + mptAlice.convert( + {.account = carol, .amt = 120, .holderPubKey = mptAlice.getPubKey(carol)}); // carol merge inbox mptAlice.mergeInbox({ @@ -3030,7 +3242,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.create(); mptAlice.authorize({.account = bob}); - mptAlice.confidentialClaw({.account = alice, .holder = bob, .amt = 10, .proof = "123", .err = temDISABLED}); + mptAlice.confidentialClaw( + {.account = alice, .holder = bob, .amt = 10, .proof = "123", .err = temDISABLED}); } // test malformed @@ -3042,7 +3255,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const carol("carol"); MPTTester mptAlice(env, alice, {.holders = {bob, carol}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + mptAlice.create( + {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = carol}); @@ -3054,7 +3268,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.pay(alice, carol, 50); // only issuer can clawback - mptAlice.confidentialClaw({.account = carol, .holder = bob, .amt = 10, .err = temMALFORMED}); + mptAlice.confidentialClaw( + {.account = carol, .holder = bob, .amt = 10, .err = temMALFORMED}); // invalid issuance ID, whose issuer is not alice { @@ -3072,10 +3287,12 @@ class ConfidentialTransfer_test : public beast::unit_test::suite } // issuer cannot clawback from self - mptAlice.confidentialClaw({.account = alice, .holder = alice, .amt = 10, .err = temMALFORMED}); + mptAlice.confidentialClaw( + {.account = alice, .holder = alice, .amt = 10, .err = temMALFORMED}); // invalid amount - mptAlice.confidentialClaw({.account = alice, .holder = bob, .amt = 0, .err = temBAD_AMOUNT}); + mptAlice.confidentialClaw( + {.account = alice, .holder = bob, .amt = 0, .err = temBAD_AMOUNT}); // invalid proof length mptAlice.confidentialClaw( @@ -3100,7 +3317,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const dave("dave"); MPTTester mptAlice(env, alice, {.holders = {bob, carol, dave}}); - mptAlice.create({.flags = tfMPTCanTransfer | tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanPrivacy}); + mptAlice.create( + {.flags = + tfMPTCanTransfer | tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = alice, .holder = bob}); mptAlice.authorize({.account = carol}); @@ -3125,17 +3344,20 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // holder does not exist { Account const unknown("unknown"); - mptAlice.confidentialClaw({.account = alice, .holder = unknown, .amt = 10, .err = tecNO_TARGET}); + mptAlice.confidentialClaw( + {.account = alice, .holder = unknown, .amt = 10, .err = tecNO_TARGET}); } // dave does not hold mpt at all, no MPT object { - mptAlice.confidentialClaw({.account = alice, .holder = dave, .amt = 10, .err = tecOBJECT_NOT_FOUND}); + mptAlice.confidentialClaw( + {.account = alice, .holder = dave, .amt = 10, .err = tecOBJECT_NOT_FOUND}); } // carol has no confidential balance { - mptAlice.confidentialClaw({.account = alice, .holder = carol, .amt = 10, .err = tecNO_PERMISSION}); + mptAlice.confidentialClaw( + {.account = alice, .holder = carol, .amt = 10, .err = tecNO_PERMISSION}); } } @@ -3151,7 +3373,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.generateKeyPair(alice); mptAlice.set({.account = alice, .issuerPubKey = mptAlice.getPubKey(alice)}); - mptAlice.confidentialClaw({.account = alice, .holder = bob, .amt = 10, .err = tecNO_PERMISSION}); + mptAlice.confidentialClaw( + {.account = alice, .holder = bob, .amt = 10, .err = tecNO_PERMISSION}); } // no issuer key @@ -3164,7 +3387,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.authorize({.account = bob}); mptAlice.generateKeyPair(alice); - mptAlice.confidentialClaw({.account = alice, .holder = bob, .amt = 10, .err = tecNO_PERMISSION}); + mptAlice.confidentialClaw( + {.account = alice, .holder = bob, .amt = 10, .err = tecNO_PERMISSION}); } // issuance not found @@ -3199,7 +3423,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.flags = tfMPTCanTransfer | tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanLock | tfMPTCanPrivacy}); + {.flags = tfMPTCanTransfer | tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanLock | + tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.authorize({.account = alice, .holder = bob}); mptAlice.pay(alice, bob, 100); @@ -3259,7 +3484,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice = setupAccounts(env, alice, bob); - mptAlice.confidentialClaw({.account = alice, .holder = bob, .amt = 10000, .err = tecINSUFFICIENT_FUNDS}); + mptAlice.confidentialClaw( + {.account = alice, .holder = bob, .amt = 10000, .err = tecINSUFFICIENT_FUNDS}); } } @@ -3296,12 +3522,14 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // lambda function to test a set of bad clawback amounts that should // return tecBAD_PROOF - auto checkBadProofs = [&](MPTTester& mpt, Account const& holder, std::initializer_list amts) { - for (auto const badAmt : amts) - { - mpt.confidentialClaw({.account = alice, .holder = holder, .amt = badAmt, .err = tecBAD_PROOF}); - } - }; + auto checkBadProofs = + [&](MPTTester& mpt, Account const& holder, std::initializer_list amts) { + for (auto const badAmt : amts) + { + mpt.confidentialClaw( + {.account = alice, .holder = holder, .amt = badAmt, .err = tecBAD_PROOF}); + } + }; // SCENARIO 1: clawback from inbox only or spending only balances. // bob converts 500 and merge inbox, @@ -3317,7 +3545,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite .account = bob, }); // carol converts without merge - mptAlice.convert({.account = carol, .amt = 1000, .holderPubKey = mptAlice.getPubKey(carol)}); + mptAlice.convert( + {.account = carol, .amt = 1000, .holderPubKey = mptAlice.getPubKey(carol)}); // verify proof fails with invalid clawback amount // bob: 500 in Spending, 0 in Inbox @@ -3345,7 +3574,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.mergeInbox({ .account = bob, }); - mptAlice.convert({.account = carol, .amt = 400, .holderPubKey = mptAlice.getPubKey(carol)}); + mptAlice.convert( + {.account = carol, .amt = 400, .holderPubKey = mptAlice.getPubKey(carol)}); mptAlice.mergeInbox({ .account = carol, }); @@ -3380,7 +3610,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 0, .mutableFlags = tmfMPTCannotMutatePrivacy, .err = temDISABLED}); + mptAlice.create( + {.ownerCount = 0, .mutableFlags = tmfMPTCannotMutatePrivacy, .err = temDISABLED}); } // can not create mpt issuance with tmfMPTCannotMutatePrivacy when @@ -3391,7 +3622,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 0, .mutableFlags = tmfMPTCannotMutatePrivacy, .err = temDISABLED}); + mptAlice.create( + {.ownerCount = 0, .mutableFlags = tmfMPTCannotMutatePrivacy, .err = temDISABLED}); } // if lsmfMPTCannotMutatePrivacy is set, can not set/clear @@ -3402,11 +3634,16 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Account const bob("bob"); MPTTester mptAlice(env, alice, {.holders = {bob}}); - mptAlice.create({.ownerCount = 1, .flags = tfMPTCanTransfer, .mutableFlags = tmfMPTCannotMutatePrivacy}); + mptAlice.create( + {.ownerCount = 1, + .flags = tfMPTCanTransfer, + .mutableFlags = tmfMPTCannotMutatePrivacy}); - mptAlice.set({.account = alice, .mutableFlags = tmfMPTSetPrivacy, .err = tecNO_PERMISSION}); + mptAlice.set( + {.account = alice, .mutableFlags = tmfMPTSetPrivacy, .err = tecNO_PERMISSION}); - mptAlice.set({.account = alice, .mutableFlags = tmfMPTClearPrivacy, .err = tecNO_PERMISSION}); + mptAlice.set( + {.account = alice, .mutableFlags = tmfMPTClearPrivacy, .err = tecNO_PERMISSION}); } // Toggle lsfMPTCanPrivacy @@ -3417,7 +3654,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanPrivacy, .mutableFlags = tmfMPTCanMutateCanLock}); + {.ownerCount = 1, + .flags = tfMPTCanTransfer | tfMPTCanPrivacy, + .mutableFlags = tmfMPTCanMutateCanLock}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -3430,7 +3669,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite auto verifyToggle = [&](TER expectedResult, uint64_t amt) { if (!holderPubKeySet) mptAlice.convert( - {.account = bob, .amt = amt, .holderPubKey = mptAlice.getPubKey(bob), .err = expectedResult}); + {.account = bob, + .amt = amt, + .holderPubKey = mptAlice.getPubKey(bob), + .err = expectedResult}); else mptAlice.convert({ .account = bob, @@ -3497,8 +3739,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // set or clear lsfMPTCanPrivacy should fail because of // confidential outstanding balance - mptAlice.set({.account = alice, .mutableFlags = tmfMPTSetPrivacy, .err = tecNO_PERMISSION}); - mptAlice.set({.account = alice, .mutableFlags = tmfMPTClearPrivacy, .err = tecNO_PERMISSION}); + mptAlice.set( + {.account = alice, .mutableFlags = tmfMPTSetPrivacy, .err = tecNO_PERMISSION}); + mptAlice.set( + {.account = alice, .mutableFlags = tmfMPTClearPrivacy, .err = tecNO_PERMISSION}); // bob merge inbox mptAlice.mergeInbox({ @@ -3518,7 +3762,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // bob can not convert because lsfMPTCanPrivacy was cleared // successfully mptAlice.convert( - {.account = bob, .amt = 10, .holderPubKey = mptAlice.getPubKey(bob), .err = tecNO_PERMISSION}); + {.account = bob, + .amt = 10, + .holderPubKey = mptAlice.getPubKey(bob), + .err = tecNO_PERMISSION}); // can set lsfMPTCanPrivacy again when there's no confidential // outstanding balance @@ -3543,7 +3790,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // --------------- Setup test --------------- // mptAlice.create( - {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + {.ownerCount = 1, + .holderCount = 0, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -3570,12 +3819,15 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Buffer const blindingFactor = generateBlindingFactor(); Buffer const pcBlindingFactor = generateBlindingFactor(); - auto const spendingBalance = mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const spendingBalance = + mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); BEAST_EXPECT(spendingBalance.has_value()); - auto const encryptedSpendingBalance = mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const encryptedSpendingBalance = + mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); BEAST_EXPECT(encryptedSpendingBalance.has_value() && !encryptedSpendingBalance->empty()); - Buffer const pedersenCommitment = mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); + Buffer const pedersenCommitment = + mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); Buffer const issuerCiphertext = mptAlice.encryptAmount(alice, amt, blindingFactor); Buffer const bobCiphertext = mptAlice.encryptAmount(bob, amt, blindingFactor); auto const version = mptAlice.getMPTokenVersion(bob); @@ -3592,7 +3844,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite auto const combineProofs = [](Buffer const& pedersenProof, Buffer const& bulletproof) { Buffer combinedProof(pedersenProof.size() + bulletproof.size()); std::memcpy(combinedProof.data(), pedersenProof.data(), pedersenProof.size()); - std::memcpy(combinedProof.data() + pedersenProof.size(), bulletproof.data(), bulletproof.size()); + std::memcpy( + combinedProof.data() + pedersenProof.size(), + bulletproof.data(), + bulletproof.size()); return combinedProof; }; @@ -3603,8 +3858,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // The proof uses PC(1, rho) but the transaction submits PC(balance, rho). // Verification fails because the proof doesn't match the submitted commitment. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); - Buffer const badPedersenCommitment = mptAlice.getPedersenCommitment(1, pcBlindingFactor); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + Buffer const badPedersenCommitment = + mptAlice.getPedersenCommitment(1, pcBlindingFactor); Buffer const proof = mptAlice.getConvertBackProof( bob, amt, @@ -3631,7 +3888,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // The pedersen commitment PC = balance*G + rho*H requires the same rho // used in proof generation. Using a different rho breaks the linkage. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); Buffer const proof = mptAlice.getConvertBackProof( bob, @@ -3659,7 +3917,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // The proof claims balance=1 but the encrypted spending balance contains // the actual balance. Verification fails because the values don't match. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); Buffer const proof = mptAlice.getConvertBackProof( bob, @@ -3688,8 +3947,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // different pedersen commitment. Verification fails because the // submitted commitment doesn't match what the proof was generated for. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); - Buffer const badPedersenCommitment = mptAlice.getPedersenCommitment(1, pcBlindingFactor); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + Buffer const badPedersenCommitment = + mptAlice.getPedersenCommitment(1, pcBlindingFactor); Buffer const proof = mptAlice.getConvertBackProof( bob, amt, @@ -3717,7 +3978,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // sequence, issuanceID, amount, version). Using a different context hash // makes the proof invalid for this transaction, preventing replay attacks. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); uint256 const badContextHash{1}; Buffer const pedersenProof = mptAlice.getBalanceLinkageProof( bob, @@ -3750,7 +4012,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Test 6: Correct proof to verify the test setup is valid. // All parameters are correct, so the transaction should succeed. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); Buffer const proof = mptAlice.getConvertBackProof( bob, @@ -3788,7 +4051,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // --------------- Setup test --------------- // mptAlice.create( - {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + {.ownerCount = 1, + .holderCount = 0, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -3815,12 +4080,15 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Buffer const blindingFactor = generateBlindingFactor(); Buffer const pcBlindingFactor = generateBlindingFactor(); - auto const spendingBalance = mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const spendingBalance = + mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); BEAST_EXPECT(spendingBalance.has_value()); - auto const encryptedSpendingBalance = mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const encryptedSpendingBalance = + mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); BEAST_EXPECT(encryptedSpendingBalance.has_value() && !encryptedSpendingBalance->empty()); - Buffer const pedersenCommitment = mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); + Buffer const pedersenCommitment = + mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); Buffer const issuerCiphertext = mptAlice.encryptAmount(alice, amt, blindingFactor); Buffer const bobCiphertext = mptAlice.encryptAmount(bob, amt, blindingFactor); auto const version = mptAlice.getMPTokenVersion(bob); @@ -3837,7 +4105,10 @@ class ConfidentialTransfer_test : public beast::unit_test::suite auto const combineProofs = [](Buffer const& pedersenProof, Buffer const& bulletproof) { Buffer combinedProof(pedersenProof.size() + bulletproof.size()); std::memcpy(combinedProof.data(), pedersenProof.data(), pedersenProof.size()); - std::memcpy(combinedProof.data() + pedersenProof.size(), bulletproof.data(), bulletproof.size()); + std::memcpy( + combinedProof.data() + pedersenProof.size(), + bulletproof.data(), + bulletproof.size()); return combinedProof; }; @@ -3864,7 +4135,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // commitment was created with (balance - amount). The verifier computes // PC_rem = PC - amount*G and checks if the bulletproof matches, which fails. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); Buffer const bulletproof = mptAlice.getBulletproof( {1}, // wrong remaining balance @@ -3889,7 +4161,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // commitment PC = (balance - amount)*G + rho*H. Using a different rho // creates a commitment mismatch and verification fails. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); Buffer const bulletproof = mptAlice.getBulletproof( {*spendingBalance - amt}, @@ -3914,7 +4187,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // sequence, issuanceID, amount, version). Using a different context hash // makes the proof invalid for this transaction, preventing replay attacks. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); uint256 const badContextHash{1}; Buffer const bulletproof = mptAlice.getBulletproof( @@ -3938,7 +4212,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Test 4: Correct proof to verify the test setup is valid. // All parameters are correct, so the transaction should succeed. { - uint256 const contextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); + uint256 const contextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), env.seq(bob), version); Buffer const proof = mptAlice.getConvertBackProof( bob, @@ -3979,7 +4254,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + {.ownerCount = 1, + .holderCount = 0, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -4004,12 +4281,16 @@ class ConfidentialTransfer_test : public beast::unit_test::suite Buffer const blindingFactor = generateBlindingFactor(); Buffer const pcBlindingFactor = generateBlindingFactor(); - auto const spendingBalance = mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); - BEAST_EXPECT(spendingBalance.has_value() && *spendingBalance == 40); // because bob encrypted 40 - auto const encryptedSpendingBalance = mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const spendingBalance = + mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + BEAST_EXPECT( + spendingBalance.has_value() && *spendingBalance == 40); // because bob encrypted 40 + auto const encryptedSpendingBalance = + mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); BEAST_EXPECT(encryptedSpendingBalance.has_value() && !encryptedSpendingBalance->empty()); - Buffer const pedersenCommitment = mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); + Buffer const pedersenCommitment = + mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); Buffer const issuerCiphertext = mptAlice.encryptAmount(alice, amt, blindingFactor); Buffer const bobCiphertext = mptAlice.encryptAmount(bob, amt, blindingFactor); @@ -4022,7 +4303,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite { uint32_t const seqA = env.seq(bob); uint32_t const oldVersion = currentVersion - 1; - uint256 const badContextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), seqA, oldVersion); + uint256 const badContextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), seqA, oldVersion); Buffer const proof = mptAlice.getConvertBackProof( bob, @@ -4083,7 +4365,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite { // Fetch updated sequence once more uint32_t const seqC = env.seq(bob); - uint256 const goodContextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), seqC, currentVersion); + uint256 const goodContextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), seqC, currentVersion); Buffer const proof = mptAlice.getConvertBackProof( bob, @@ -4125,7 +4408,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + {.ownerCount = 1, + .holderCount = 0, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 100); @@ -4144,16 +4429,20 @@ class ConfidentialTransfer_test : public beast::unit_test::suite .account = bob, }); - auto const spendingBalance = mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); - auto const encryptedSpendingBalance = mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const spendingBalance = + mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const encryptedSpendingBalance = + mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); auto const version = mptAlice.getMPTokenVersion(bob); Buffer const pcBlindingFactor = generateBlindingFactor(); - Buffer const pedersenCommitment = mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); + Buffer const pedersenCommitment = + mptAlice.getPedersenCommitment(*spendingBalance, pcBlindingFactor); // Generate a valid proof pi for Amount m1 = 10 uint64_t const amtA = 10; uint32_t const currentSeq = env.seq(bob); - uint256 const contextHashA = getConvertBackContextHash(bob, mptAlice.issuanceID(), currentSeq, version); + uint256 const contextHashA = + getConvertBackContextHash(bob, mptAlice.issuanceID(), currentSeq, version); Buffer const proofA = mptAlice.getConvertBackProof( bob, @@ -4200,7 +4489,9 @@ class ConfidentialTransfer_test : public beast::unit_test::suite MPTTester mptAlice(env, alice, {.holders = {bob}}); mptAlice.create( - {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); + {.ownerCount = 1, + .holderCount = 0, + .flags = tfMPTCanTransfer | tfMPTCanLock | tfMPTCanPrivacy}); mptAlice.authorize({.account = bob}); mptAlice.pay(alice, bob, 1000); @@ -4220,14 +4511,17 @@ class ConfidentialTransfer_test : public beast::unit_test::suite mptAlice.mergeInbox({.account = bob}); auto const versionV = mptAlice.getMPTokenVersion(bob); - auto const spendingBalanceV = mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); - auto const encryptedSpendingBalanceV = mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const spendingBalanceV = + mptAlice.getDecryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); + auto const encryptedSpendingBalanceV = + mptAlice.getEncryptedBalance(bob, MPTTester::HOLDER_ENCRYPTED_SPENDING); // Parameters for the intended ConvertBack transaction uint64_t const amt = 10; Buffer const blindingFactor = generateBlindingFactor(); Buffer const pcBlindingFactor = generateBlindingFactor(); - Buffer const pedersenCommitment = mptAlice.getPedersenCommitment(*spendingBalanceV, pcBlindingFactor); + Buffer const pedersenCommitment = + mptAlice.getPedersenCommitment(*spendingBalanceV, pcBlindingFactor); Buffer const issuerCiphertext = mptAlice.encryptAmount(alice, amt, blindingFactor); Buffer const bobCiphertext = mptAlice.encryptAmount(bob, amt, blindingFactor); @@ -4241,7 +4535,8 @@ class ConfidentialTransfer_test : public beast::unit_test::suite // Attack: Attempt to reuse proof tied to Version v at ledger Version v+1 uint32_t const currentSeq = env.seq(bob); // Proof is explicitly generated using the outdated Version v - uint256 const oldContextHash = getConvertBackContextHash(bob, mptAlice.issuanceID(), currentSeq, versionV); + uint256 const oldContextHash = + getConvertBackContextHash(bob, mptAlice.issuanceID(), currentSeq, versionV); Buffer const oldProof = mptAlice.getConvertBackProof( bob, diff --git a/src/test/app/Invariants_test.cpp b/src/test/app/Invariants_test.cpp index 75568dbe35..c6d3f1ad40 100644 --- a/src/test/app/Invariants_test.cpp +++ b/src/test/app/Invariants_test.cpp @@ -3804,7 +3804,8 @@ class Invariants_test : public beast::unit_test::suite // Generate an MPT with privacy, issue 100 tokens to A2. // Perform a confidential conversion to populate encrypted state. - auto const precloseConfidential = [&mptID](Account const& A1, Account const& A2, Env& env) -> bool { + auto const precloseConfidential = + [&mptID](Account const& A1, Account const& A2, Env& env) -> bool { MPTTester mpt(env, A1, {.holders = {A2}, .fund = false}); mpt.create({.flags = tfMPTCanTransfer | tfMPTCanPrivacy}); mptID = mpt.issuanceID(); @@ -3858,7 +3859,8 @@ class Invariants_test : public beast::unit_test::suite precloseConfidential); // requiresPrivacyFlag - auto const precloseNoPrivacy = [&mptID](Account const& A1, Account const& A2, Env& env) -> bool { + auto const precloseNoPrivacy = [&mptID]( + Account const& A1, Account const& A2, Env& env) -> bool { MPTTester mpt(env, A1, {.holders = {A2}, .fund = false}); // completely omitted the tfMPTCanPrivacy flag here. mpt.create({.flags = tfMPTCanTransfer}); @@ -3911,7 +3913,8 @@ class Invariants_test : public beast::unit_test::suite return false; sleIssuance->setFieldU64( - sfConfidentialOutstandingAmount, sleIssuance->getFieldU64(sfConfidentialOutstandingAmount) - 10); + sfConfidentialOutstandingAmount, + sleIssuance->getFieldU64(sfConfidentialOutstandingAmount) - 10); ac.view().update(sleIssuance); return true; @@ -3923,7 +3926,8 @@ class Invariants_test : public beast::unit_test::suite // badVersion doInvariantCheck( - {"MPToken sfConfidentialBalanceVersion not updated when sfConfidentialBalanceSpending changed"}, + {"MPToken sfConfidentialBalanceVersion not updated when sfConfidentialBalanceSpending " + "changed"}, [&mptID](Account const& A1, Account const& A2, ApplyContext& ac) { auto sleToken = ac.view().peek(keylet::mptoken(mptID, A2.id())); if (!sleToken) @@ -3940,7 +3944,8 @@ class Invariants_test : public beast::unit_test::suite precloseConfidential); // Skipping Deleted MPTs (Issuance deleted) - auto const precloseOrphan = [&mptID](Account const& A1, Account const& A2, Env& env) -> bool { + auto const precloseOrphan = [&mptID]( + Account const& A1, Account const& A2, Env& env) -> bool { MPTTester mpt(env, A1, {.holders = {A2}, .fund = false}); mpt.create({.flags = tfMPTCanTransfer | tfMPTCanPrivacy}); mptID = mpt.issuanceID(); diff --git a/src/test/jtx/impl/mpt.cpp b/src/test/jtx/impl/mpt.cpp index 8f678aabda..629daad23d 100644 --- a/src/test/jtx/impl/mpt.cpp +++ b/src/test/jtx/impl/mpt.cpp @@ -46,7 +46,11 @@ MPTTester::makeHolders(std::vector const& holders) } MPTTester::MPTTester(Env& env, Account const& issuer, MPTInit const& arg) - : env_(env), issuer_(issuer), holders_(makeHolders(arg.holders)), auditor_(arg.auditor), close_(arg.close) + : env_(env) + , issuer_(issuer) + , holders_(makeHolders(arg.holders)) + , auditor_(arg.auditor) + , close_(arg.close) { if (arg.fund) { @@ -465,7 +469,8 @@ MPTTester::set(MPTSet const& arg) auto const auditorPubKey = getPubKey(*auditor_); if (!auditorPubKey) - Throw("MPTTester::set: auditor's pubkey is not set"); + Throw( + "MPTTester::set: auditor's pubkey is not set"); return strHex((*sle)[sfAuditorElGamalPublicKey]) == strHex(*auditorPubKey); } @@ -527,8 +532,9 @@ MPTTester::checkMPTokenOutstandingAmount(std::int64_t expectedAmount) const [[nodiscard]] bool MPTTester::checkIssuanceConfidentialBalance(std::int64_t expectedAmount) const { - return forObject( - [&](SLEP const& sle) { return expectedAmount == (*sle)[~sfConfidentialOutstandingAmount].value_or(0); }); + return forObject([&](SLEP const& sle) { + return expectedAmount == (*sle)[~sfConfidentialOutstandingAmount].value_or(0); + }); } [[nodiscard]] bool @@ -717,7 +723,8 @@ MPTTester::getClawbackProof( return std::nullopt; } - if (!secp256k1_ec_pubkey_parse(ctx, &c2, ciphertextBlob.data() + ecGamalEncryptedLength, ecGamalEncryptedLength)) + if (!secp256k1_ec_pubkey_parse( + ctx, &c2, ciphertextBlob.data() + ecGamalEncryptedLength, ecGamalEncryptedLength)) { return std::nullopt; } @@ -755,7 +762,8 @@ MPTTester::getSchnorrProof(Account const& account, uint256 const& ctxHash) const Buffer proof(ecSchnorrProofLength); - if (secp256k1_mpt_pok_sk_prove(secp256k1Context(), proof.data(), &pk, privKey->data(), ctxHash.data()) != 1) + if (secp256k1_mpt_pok_sk_prove( + secp256k1Context(), proof.data(), &pk, privKey->data(), ctxHash.data()) != 1) { return std::nullopt; } @@ -810,7 +818,8 @@ MPTTester::getConfidentialSendProof( return std::nullopt; } - if (!secp256k1_ec_pubkey_parse(ctx, &c2_vec[i], ctData + ecGamalEncryptedLength, ecGamalEncryptedLength)) + if (!secp256k1_ec_pubkey_parse( + ctx, &c2_vec[i], ctData + ecGamalEncryptedLength, ecGamalEncryptedLength)) return std::nullopt; if (!secp256k1_ec_pubkey_parse(ctx, &pk_vec[i], recipient.publicKey.data(), ecPubKeyLength)) @@ -835,9 +844,13 @@ MPTTester::getConfidentialSendProof( } auto const amountLinkageProof = getAmountLinkageProof( - *senderPubKey, Buffer(blindingFactor.data(), ecBlindingFactorLength), contextHash, amountParams); + *senderPubKey, + Buffer(blindingFactor.data(), ecBlindingFactorLength), + contextHash, + amountParams); - auto const balanceLinkageProof = getBalanceLinkageProof(sender, contextHash, *senderPubKey, balanceParams); + auto const balanceLinkageProof = + getBalanceLinkageProof(sender, contextHash, *senderPubKey, balanceParams); std::uint64_t const remainingBalance = balanceParams.amt - amount; @@ -849,8 +862,10 @@ MPTTester::getConfidentialSendProof( secp256k1_mpt_scalar_add(rho_rem, balanceParams.blindingFactor.data(), neg_rho_m); // Generate bulletproof for the amount and remaining balance - Buffer const bulletproof = - getBulletproof({amount, remainingBalance}, {amountParams.blindingFactor, Buffer(rho_rem, 32)}, contextHash); + Buffer const bulletproof = getBulletproof( + {amount, remainingBalance}, + {amountParams.blindingFactor, Buffer(rho_rem, 32)}, + contextHash); OPENSSL_cleanse(neg_rho_m, 32); OPENSSL_cleanse(rho_rem, 32); @@ -859,7 +874,8 @@ MPTTester::getConfidentialSendProof( auto const sizeBalanceLinkage = balanceLinkageProof.size(); auto const sizeBulletproof = bulletproof.size(); - size_t const proofSize = sizeEquality + sizeAmountLinkage + sizeBalanceLinkage + sizeBulletproof; + size_t const proofSize = + sizeEquality + sizeAmountLinkage + sizeBalanceLinkage + sizeBulletproof; Buffer proof(proofSize); auto ptr = proof.data(); @@ -907,7 +923,8 @@ MPTTester::getPedersenCommitment(std::uint64_t const amount, Buffer const& peder // Serialize commitment to compressed format (33 bytes) unsigned char compressedCommitment[ecPedersenCommitmentLength]; size_t outLen = ecPedersenCommitmentLength; - if (secp256k1_ec_pubkey_serialize(ctx, compressedCommitment, &outLen, &commitment, SECP256K1_EC_COMPRESSED) != 1 || + if (secp256k1_ec_pubkey_serialize( + ctx, compressedCommitment, &outLen, &commitment, SECP256K1_EC_COMPRESSED) != 1 || outLen != ecPedersenCommitmentLength) { Throw("Pedersen commitment serialization failed"); @@ -935,17 +952,20 @@ MPTTester::getConvertBackProof( if (!holderPubKey) return makeZeroBuffer(expectedProofLength); - Buffer const pedersenProof = getBalanceLinkageProof(holder, contextHash, *holderPubKey, pcParams); + Buffer const pedersenProof = + getBalanceLinkageProof(holder, contextHash, *holderPubKey, pcParams); // Generate bulletproof for the remaining balance (balance - amount) // Use the same blinding factor as the one used to generate the PC_balance std::uint64_t const remainingBalance = pcParams.amt - amount; - Buffer const bulletproof = getBulletproof({remainingBalance}, {pcParams.blindingFactor}, contextHash); + Buffer const bulletproof = + getBulletproof({remainingBalance}, {pcParams.blindingFactor}, contextHash); // Combine pedersen proof and bulletproof Buffer combinedProof(pedersenProof.size() + bulletproof.size()); std::memcpy(combinedProof.data(), pedersenProof.data(), pedersenProof.size()); - std::memcpy(combinedProof.data() + pedersenProof.size(), bulletproof.data(), bulletproof.size()); + std::memcpy( + combinedProof.data() + pedersenProof.size(), bulletproof.data(), bulletproof.size()); return combinedProof; } @@ -959,13 +979,20 @@ MPTTester::getEncryptedBalance(Account const& account, EncryptedBalanceType opti if (auto const sle = env_.le(keylet::mptoken(*id_, account.id()))) { if (option == HOLDER_ENCRYPTED_INBOX && sle->isFieldPresent(sfConfidentialBalanceInbox)) - return Buffer((*sle)[sfConfidentialBalanceInbox].data(), (*sle)[sfConfidentialBalanceInbox].size()); - if (option == HOLDER_ENCRYPTED_SPENDING && sle->isFieldPresent(sfConfidentialBalanceSpending)) - return Buffer((*sle)[sfConfidentialBalanceSpending].data(), (*sle)[sfConfidentialBalanceSpending].size()); + return Buffer( + (*sle)[sfConfidentialBalanceInbox].data(), + (*sle)[sfConfidentialBalanceInbox].size()); + if (option == HOLDER_ENCRYPTED_SPENDING && + sle->isFieldPresent(sfConfidentialBalanceSpending)) + return Buffer( + (*sle)[sfConfidentialBalanceSpending].data(), + (*sle)[sfConfidentialBalanceSpending].size()); if (option == ISSUER_ENCRYPTED_BALANCE && sle->isFieldPresent(sfIssuerEncryptedBalance)) - return Buffer((*sle)[sfIssuerEncryptedBalance].data(), (*sle)[sfIssuerEncryptedBalance].size()); + return Buffer( + (*sle)[sfIssuerEncryptedBalance].data(), (*sle)[sfIssuerEncryptedBalance].size()); if (option == AUDITOR_ENCRYPTED_BALANCE && sle->isFieldPresent(sfAuditorEncryptedBalance)) - return Buffer((*sle)[sfAuditorEncryptedBalance].data(), (*sle)[sfAuditorEncryptedBalance].size()); + return Buffer( + (*sle)[sfAuditorEncryptedBalance].data(), (*sle)[sfAuditorEncryptedBalance].size()); } return {}; @@ -1065,7 +1092,8 @@ MPTTester::convert(MPTConvert const& arg) std::optional auditorCiphertext; Buffer blindingFactor; - fillConversionCiphertexts(arg, jv, holderCiphertext, issuerCiphertext, auditorCiphertext, blindingFactor); + fillConversionCiphertexts( + arg, jv, holderCiphertext, issuerCiphertext, auditorCiphertext, blindingFactor); jv[sfBlindingFactor.jsonName] = strHex(blindingFactor); if (arg.proof) @@ -1076,7 +1104,8 @@ MPTTester::convert(MPTConvert const& arg) // if fillSchnorrProof is explicitly set, follow its value; // otherwise, default to generating the proof only if holder pub key is // present. - auto const contextHash = getConvertContextHash(arg.account->id(), *id_, env_.seq(*arg.account)); + auto const contextHash = + getConvertContextHash(arg.account->id(), *id_, env_.seq(*arg.account)); auto const proof = getSchnorrProof(*arg.account, contextHash); if (proof) @@ -1107,39 +1136,47 @@ MPTTester::convert(MPTConvert const& arg) { auto const postConfidentialOutstanding = getIssuanceConfidentialBalance(); env_.require(mptbalance(*this, *arg.account, holderAmt - *arg.amt)); - env_.require(requireAny( - [&]() -> bool { return prevConfidentialOutstanding + *arg.amt == postConfidentialOutstanding; })); + env_.require(requireAny([&]() -> bool { + return prevConfidentialOutstanding + *arg.amt == postConfidentialOutstanding; + })); auto const postInboxBalance = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_INBOX); auto const postIssuerBalance = getDecryptedBalance(*arg.account, ISSUER_ENCRYPTED_BALANCE); - auto const postSpendingBalance = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); + auto const postSpendingBalance = + getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); if (!postInboxBalance || !postIssuerBalance || !postSpendingBalance) Throw("Failed to get post-convert balance"); if (arg.auditorEncryptedAmt || auditor_) { - auto const postAuditorBalance = getDecryptedBalance(*arg.account, AUDITOR_ENCRYPTED_BALANCE); + auto const postAuditorBalance = + getDecryptedBalance(*arg.account, AUDITOR_ENCRYPTED_BALANCE); if (!postAuditorBalance) Throw("Failed to get post-convert auditor balance"); // auditor's encrypted balance is updated correctly - env_.require(requireAny([&]() -> bool { return *prevAuditorBalance + *arg.amt == *postAuditorBalance; })); + env_.require(requireAny( + [&]() -> bool { return *prevAuditorBalance + *arg.amt == *postAuditorBalance; })); } // spending balance should not change - env_.require(requireAny([&]() -> bool { return *postSpendingBalance == *prevSpendingBalance; })); + env_.require( + requireAny([&]() -> bool { return *postSpendingBalance == *prevSpendingBalance; })); // issuer's encrypted balance is updated correctly - env_.require(requireAny([&]() -> bool { return *prevIssuerBalance + *arg.amt == *postIssuerBalance; })); + env_.require(requireAny( + [&]() -> bool { return *prevIssuerBalance + *arg.amt == *postIssuerBalance; })); // holder's inbox balance is updated correctly - env_.require(requireAny([&]() -> bool { return *prevInboxBalance + *arg.amt == *postInboxBalance; })); + env_.require(requireAny( + [&]() -> bool { return *prevInboxBalance + *arg.amt == *postInboxBalance; })); // sum of holder's inbox and spending balance should equal to issuer's // encrypted balance - env_.require( - requireAny([&]() -> bool { return *postInboxBalance + *postSpendingBalance == *postIssuerBalance; })); + env_.require(requireAny([&]() -> bool { + return *postInboxBalance + *postSpendingBalance == *postIssuerBalance; + })); if (arg.holderPubKey) { @@ -1154,7 +1191,8 @@ MPTTester::convert(MPTConvert const& arg) "MPTTester::convert: holder's pubkey is " "not set"); - return strHex((*sle)[sfHolderElGamalPublicKey]) == strHex(*holderPubKey); + return strHex((*sle)[sfHolderElGamalPublicKey]) == + strHex(*holderPubKey); } return false; }, @@ -1192,15 +1230,18 @@ MPTTester::send(MPTConfidentialSend const& arg) jv[sfMPTokenIssuanceID] = to_string(*id_); } - Buffer const blindingFactor = arg.blindingFactor ? *arg.blindingFactor : generateBlindingFactor(); + Buffer const blindingFactor = + arg.blindingFactor ? *arg.blindingFactor : generateBlindingFactor(); // fill in the encrypted amounts if not provided - auto const senderAmt = - arg.senderEncryptedAmt ? *arg.senderEncryptedAmt : encryptAmount(*arg.account, *arg.amt, blindingFactor); - auto const destAmt = - arg.destEncryptedAmt ? *arg.destEncryptedAmt : encryptAmount(*arg.dest, *arg.amt, blindingFactor); - auto const issuerAmt = - arg.issuerEncryptedAmt ? *arg.issuerEncryptedAmt : encryptAmount(issuer_, *arg.amt, blindingFactor); + auto const senderAmt = arg.senderEncryptedAmt + ? *arg.senderEncryptedAmt + : encryptAmount(*arg.account, *arg.amt, blindingFactor); + auto const destAmt = arg.destEncryptedAmt ? *arg.destEncryptedAmt + : encryptAmount(*arg.dest, *arg.amt, blindingFactor); + auto const issuerAmt = arg.issuerEncryptedAmt + ? *arg.issuerEncryptedAmt + : encryptAmount(issuer_, *arg.amt, blindingFactor); std::optional auditorAmt; if (arg.auditorEncryptedAmt) @@ -1279,8 +1320,8 @@ MPTTester::send(MPTConfidentialSend const& arg) else { auto const version = getMPTokenVersion(*arg.account); - auto const ctxHash = - getSendContextHash(arg.account->id(), *id_, env_.seq(*arg.account), arg.dest->id(), version); + auto const ctxHash = getSendContextHash( + arg.account->id(), *id_, env_.seq(*arg.account), arg.dest->id(), version); auto const nRecipients = getConfidentialRecipientCount(auditorAmt.has_value()); std::vector recipients; @@ -1310,7 +1351,8 @@ MPTTester::send(MPTConfidentialSend const& arg) recipients.push_back({Slice(*auditorPubKey), *auditorAmt}); } - auto const prevEncryptedSenderSpending = getEncryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); + auto const prevEncryptedSenderSpending = + getEncryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); std::optional proof; @@ -1342,7 +1384,8 @@ MPTTester::send(MPTConfidentialSend const& arg) else { size_t const sizeEquality = secp256k1_mpt_prove_same_plaintext_multi_size(nRecipients); - size_t const dummySize = sizeEquality + 2 * ecPedersenProofLength + ecDoubleBulletproofLength; + size_t const dummySize = + sizeEquality + 2 * ecPedersenProofLength + ecDoubleBulletproofLength; jv[sfZKProof.jsonName] = strHex(makeZeroBuffer(dummySize)); } @@ -1360,7 +1403,8 @@ MPTTester::send(MPTConfidentialSend const& arg) // Sender's post confidential state auto const postSenderInbox = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_INBOX); - auto const postSenderSpending = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); + auto const postSenderSpending = + getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); auto const postSenderIssuer = getDecryptedBalance(*arg.account, ISSUER_ENCRYPTED_BALANCE); if (!postSenderInbox || !postSenderSpending || !postSenderIssuer) @@ -1384,44 +1428,56 @@ MPTTester::send(MPTConfidentialSend const& arg) // Verify sender changes env_.require(requireAny([&]() -> bool { - return *prevSenderSpending >= *arg.amt && *postSenderSpending == *prevSenderSpending - *arg.amt; + return *prevSenderSpending >= *arg.amt && + *postSenderSpending == *prevSenderSpending - *arg.amt; })); env_.require(requireAny([&]() -> bool { return postSenderInbox == prevSenderInbox; })); env_.require(requireAny([&]() -> bool { - return *prevSenderIssuer >= *arg.amt && *postSenderIssuer == *prevSenderIssuer - *arg.amt; + return *prevSenderIssuer >= *arg.amt && + *postSenderIssuer == *prevSenderIssuer - *arg.amt; })); // Verify destination changes - env_.require(requireAny([&]() -> bool { return *postDestInbox == *prevDestInbox + *arg.amt; })); + env_.require( + requireAny([&]() -> bool { return *postDestInbox == *prevDestInbox + *arg.amt; })); env_.require(requireAny([&]() -> bool { return *postDestSpending == *prevDestSpending; })); - env_.require(requireAny([&]() -> bool { return *postDestIssuer == *prevDestIssuer + *arg.amt; })); + env_.require( + requireAny([&]() -> bool { return *postDestIssuer == *prevDestIssuer + *arg.amt; })); // Cross checks - env_.require(requireAny([&]() -> bool { return *postSenderInbox + *postSenderSpending == *postSenderIssuer; })); - env_.require(requireAny([&]() -> bool { return *postDestInbox + *postDestSpending == *postDestIssuer; })); + env_.require(requireAny( + [&]() -> bool { return *postSenderInbox + *postSenderSpending == *postSenderIssuer; })); + env_.require(requireAny( + [&]() -> bool { return *postDestInbox + *postDestSpending == *postDestIssuer; })); // Version: sender increments by 1; receiver version is unchanged by incoming sends - env_.require(requireAny([&]() -> bool { return getMPTokenVersion(*arg.account) == prevSenderVersion + 1; })); - env_.require(requireAny([&]() -> bool { return getMPTokenVersion(*arg.dest) == prevDestVersion; })); + env_.require(requireAny( + [&]() -> bool { return getMPTokenVersion(*arg.account) == prevSenderVersion + 1; })); + env_.require( + requireAny([&]() -> bool { return getMPTokenVersion(*arg.dest) == prevDestVersion; })); if (arg.auditorEncryptedAmt || auditor_) { - auto const postSenderAuditor = getDecryptedBalance(*arg.account, AUDITOR_ENCRYPTED_BALANCE); + auto const postSenderAuditor = + getDecryptedBalance(*arg.account, AUDITOR_ENCRYPTED_BALANCE); auto const postDestAuditor = getDecryptedBalance(*arg.dest, AUDITOR_ENCRYPTED_BALANCE); if (!postSenderAuditor || !postDestAuditor) Throw("Failed to get Post-send balance"); env_.require(requireAny([&]() -> bool { - return *postSenderAuditor == *postSenderIssuer && *postDestAuditor == *postDestIssuer; + return *postSenderAuditor == *postSenderIssuer && + *postDestAuditor == *postDestIssuer; })); // verify sender env_.require(requireAny([&]() -> bool { - return prevSenderAuditor >= *arg.amt && *postSenderAuditor == *prevSenderAuditor - *arg.amt; + return prevSenderAuditor >= *arg.amt && + *postSenderAuditor == *prevSenderAuditor - *arg.amt; })); // verify dest - env_.require(requireAny([&]() -> bool { return *postDestAuditor == *prevDestAuditor + *arg.amt; })); + env_.require(requireAny( + [&]() -> bool { return *postDestAuditor == *prevDestAuditor + *arg.amt; })); } } } @@ -1454,7 +1510,8 @@ MPTTester::confidentialClaw(MPTConfidentialClawback const& arg) else { std::uint32_t const seq = env_.seq(account); - uint256 const contextHash = getClawbackContextHash(account.id(), *id_, seq, arg.holder->id()); + uint256 const contextHash = + getClawbackContextHash(account.id(), *id_, seq, arg.holder->id()); auto const privKey = getPrivKey(account); if (!privKey || privKey->size() != ecPrivKeyLength) @@ -1483,18 +1540,24 @@ MPTTester::confidentialClaw(MPTConfidentialClawback const& arg) env_.require(mptbalance(*this, *arg.holder, holderPubAmt)); // Verify COA and OA are reduced correctly - env_.require(requireAny([&]() -> bool { return prevCOA >= *arg.amt && postCOA == prevCOA - *arg.amt; })); - env_.require(requireAny([&]() -> bool { return prevOA >= *arg.amt && postOA == prevOA - *arg.amt; })); + env_.require(requireAny( + [&]() -> bool { return prevCOA >= *arg.amt && postCOA == prevCOA - *arg.amt; })); + env_.require(requireAny( + [&]() -> bool { return prevOA >= *arg.amt && postOA == prevOA - *arg.amt; })); // Verify holder's confidential balances are zeroed out - env_.require( - requireAny([&]() -> bool { return getDecryptedBalance(*arg.holder, HOLDER_ENCRYPTED_INBOX) == 0; })); - env_.require( - requireAny([&]() -> bool { return getDecryptedBalance(*arg.holder, HOLDER_ENCRYPTED_SPENDING) == 0; })); - env_.require( - requireAny([&]() -> bool { return getDecryptedBalance(*arg.holder, ISSUER_ENCRYPTED_BALANCE) == 0; })); - env_.require( - requireAny([&]() -> bool { return getDecryptedBalance(*arg.holder, AUDITOR_ENCRYPTED_BALANCE) == 0; })); + env_.require(requireAny([&]() -> bool { + return getDecryptedBalance(*arg.holder, HOLDER_ENCRYPTED_INBOX) == 0; + })); + env_.require(requireAny([&]() -> bool { + return getDecryptedBalance(*arg.holder, HOLDER_ENCRYPTED_SPENDING) == 0; + })); + env_.require(requireAny([&]() -> bool { + return getDecryptedBalance(*arg.holder, ISSUER_ENCRYPTED_BALANCE) == 0; + })); + env_.require(requireAny([&]() -> bool { + return getDecryptedBalance(*arg.holder, AUDITOR_ENCRYPTED_BALANCE) == 0; + })); // Verify version is incremented env_.require(requireAny([&]() -> bool { return postVersion == prevVersion + 1; })); @@ -1546,7 +1609,8 @@ MPTTester::getPrivKey(Account const& account) const } Buffer -MPTTester::encryptAmount(Account const& account, uint64_t const amt, Buffer const& blindingFactor) const +MPTTester::encryptAmount(Account const& account, uint64_t const amt, Buffer const& blindingFactor) + const { if (auto const pubKey = getPubKey(account)) { @@ -1637,20 +1701,24 @@ MPTTester::mergeInbox(MPTMergeInbox const& arg) if (submit(arg, jv) == tesSUCCESS) { auto const postInboxBalance = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_INBOX); - auto const postSpendingBalance = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); + auto const postSpendingBalance = + getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); auto const postIssuerBalance = getDecryptedBalance(*arg.account, ISSUER_ENCRYPTED_BALANCE); if (!postInboxBalance || !postSpendingBalance || !postIssuerBalance) Throw("Failed to get post-mergeInbox balances"); env_.require(requireAny([&]() -> bool { - return *postSpendingBalance == *prevInboxBalance + *prevSpendingBalance && *postInboxBalance == 0; + return *postSpendingBalance == *prevInboxBalance + *prevSpendingBalance && + *postInboxBalance == 0; })); - env_.require(requireAny([&]() -> bool { return *prevIssuerBalance == *postIssuerBalance; })); - env_.require( - requireAny([&]() -> bool { return *postSpendingBalance + *postInboxBalance == *postIssuerBalance; })); + requireAny([&]() -> bool { return *prevIssuerBalance == *postIssuerBalance; })); + + env_.require(requireAny([&]() -> bool { + return *postSpendingBalance + *postInboxBalance == *postIssuerBalance; + })); } } @@ -1711,7 +1779,8 @@ MPTTester::convertBack(MPTConvertBack const& arg) std::optional auditorCiphertext; Buffer blindingFactor; - fillConversionCiphertexts(arg, jv, holderCiphertext, issuerCiphertext, auditorCiphertext, blindingFactor); + fillConversionCiphertexts( + arg, jv, holderCiphertext, issuerCiphertext, auditorCiphertext, blindingFactor); jv[sfBlindingFactor] = strHex(blindingFactor); @@ -1739,8 +1808,10 @@ MPTTester::convertBack(MPTConvertBack const& arg) // if the caller generated ciphertexts themselves, they should also // generate the proof themselves from the blinding factor - uint256 const contextHash = getConvertBackContextHash(arg.account->id(), *id_, env_.seq(*arg.account), version); - auto const prevEncryptedSpendingBalance = getEncryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); + uint256 const contextHash = + getConvertBackContextHash(arg.account->id(), *id_, env_.seq(*arg.account), version); + auto const prevEncryptedSpendingBalance = + getEncryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); Buffer proof; // generate a dummy proof if no encrypted amount field, so that other @@ -1778,40 +1849,47 @@ MPTTester::convertBack(MPTConvertBack const& arg) { auto const postConfidentialOutstanding = getIssuanceConfidentialBalance(); env_.require(mptbalance(*this, *arg.account, holderAmt + *arg.amt)); - env_.require(requireAny( - [&]() -> bool { return prevConfidentialOutstanding - *arg.amt == postConfidentialOutstanding; })); + env_.require(requireAny([&]() -> bool { + return prevConfidentialOutstanding - *arg.amt == postConfidentialOutstanding; + })); auto const postInboxBalance = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_INBOX); auto const postIssuerBalance = getDecryptedBalance(*arg.account, ISSUER_ENCRYPTED_BALANCE); - auto const postSpendingBalance = getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); + auto const postSpendingBalance = + getDecryptedBalance(*arg.account, HOLDER_ENCRYPTED_SPENDING); if (!postInboxBalance || !postIssuerBalance || !postSpendingBalance) Throw("Failed to get post-convertBack balance"); if (arg.auditorEncryptedAmt || auditor_) { - auto const postAuditorBalance = getDecryptedBalance(*arg.account, AUDITOR_ENCRYPTED_BALANCE); + auto const postAuditorBalance = + getDecryptedBalance(*arg.account, AUDITOR_ENCRYPTED_BALANCE); if (!postAuditorBalance) Throw("Failed to get post-convertBack balance"); // auditor's encrypted balance is updated correctly - env_.require(requireAny([&]() -> bool { return *prevAuditorBalance - *arg.amt == *postAuditorBalance; })); + env_.require(requireAny( + [&]() -> bool { return *prevAuditorBalance - *arg.amt == *postAuditorBalance; })); } // inbox balance should not change env_.require(requireAny([&]() -> bool { return *postInboxBalance == *prevInboxBalance; })); // issuer's encrypted balance is updated correctly - env_.require(requireAny([&]() -> bool { return *prevIssuerBalance - *arg.amt == *postIssuerBalance; })); + env_.require(requireAny( + [&]() -> bool { return *prevIssuerBalance - *arg.amt == *postIssuerBalance; })); // holder's spending balance is updated correctly - env_.require(requireAny([&]() -> bool { return *prevSpendingBalance - *arg.amt == *postSpendingBalance; })); + env_.require(requireAny( + [&]() -> bool { return *prevSpendingBalance - *arg.amt == *postSpendingBalance; })); // sum of holder's inbox and spending balance should equal to issuer's // encrypted balance - env_.require( - requireAny([&]() -> bool { return *postInboxBalance + *postSpendingBalance == *postIssuerBalance; })); + env_.require(requireAny([&]() -> bool { + return *postInboxBalance + *postSpendingBalance == *postIssuerBalance; + })); } } @@ -1823,8 +1901,10 @@ MPTTester::getAmountLinkageProof( PedersenProofParams const& params) const { if (params.blindingFactor.size() != ecBlindingFactorLength || - params.pedersenCommitment.size() != ecPedersenCommitmentLength || pubKey.size() != ecPubKeyLength || - params.encryptedAmt.size() != ecGamalEncryptedTotalLength || blindingFactor.size() != ecBlindingFactorLength) + params.pedersenCommitment.size() != ecPedersenCommitmentLength || + pubKey.size() != ecPubKeyLength || + params.encryptedAmt.size() != ecGamalEncryptedTotalLength || + blindingFactor.size() != ecBlindingFactorLength) return makeZeroBuffer(ecPedersenProofLength); secp256k1_pubkey c1, c2; @@ -1841,7 +1921,8 @@ MPTTester::getAmountLinkageProof( return Buffer(); secp256k1_pubkey pcm; - if (secp256k1_ec_pubkey_parse(ctx, &pcm, params.pedersenCommitment.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse( + ctx, &pcm, params.pedersenCommitment.data(), ecPedersenCommitmentLength) != 1) return Buffer(); Buffer proof(ecPedersenProofLength); @@ -1871,7 +1952,8 @@ MPTTester::getBalanceLinkageProof( PedersenProofParams const& params) const { if (params.blindingFactor.size() != ecBlindingFactorLength || - params.pedersenCommitment.size() != ecPedersenCommitmentLength || pubKey.size() != ecPubKeyLength || + params.pedersenCommitment.size() != ecPedersenCommitmentLength || + pubKey.size() != ecPubKeyLength || params.encryptedAmt.size() != ecGamalEncryptedTotalLength) return makeZeroBuffer(ecPedersenProofLength); @@ -1889,7 +1971,8 @@ MPTTester::getBalanceLinkageProof( return Buffer(); secp256k1_pubkey pcm; - if (secp256k1_ec_pubkey_parse(ctx, &pcm, params.pedersenCommitment.data(), ecPedersenCommitmentLength) != 1) + if (secp256k1_ec_pubkey_parse( + ctx, &pcm, params.pedersenCommitment.data(), ecPedersenCommitmentLength) != 1) return Buffer(); Buffer proof(ecPedersenProofLength); @@ -1935,7 +2018,9 @@ MPTTester::getBulletproof( std::vector blindingsFlat(m * ecBlindingFactorLength); for (std::size_t i = 0; i < m; ++i) std::memcpy( - blindingsFlat.data() + i * ecBlindingFactorLength, blindingFactors[i].data(), ecBlindingFactorLength); + blindingsFlat.data() + i * ecBlindingFactorLength, + blindingFactors[i].data(), + ecBlindingFactorLength); secp256k1_pubkey pk_base; if (secp256k1_mpt_get_h_generator(secp256k1Context(), &pk_base) != 1) @@ -1958,7 +2043,8 @@ MPTTester::getBulletproof( Throw("Bulletproof generation failed"); } - std::size_t const expectedLen = (m == 1) ? ecSingleBulletproofLength : ecDoubleBulletproofLength; + std::size_t const expectedLen = + (m == 1) ? ecSingleBulletproofLength : ecDoubleBulletproofLength; if (proofLen != expectedLen) Throw("Unexpected bulletproof length"); diff --git a/src/test/jtx/mpt.h b/src/test/jtx/mpt.h index 03d45a39c7..3fd861e4ec 100644 --- a/src/test/jtx/mpt.h +++ b/src/test/jtx/mpt.h @@ -365,7 +365,8 @@ public: checkIssuanceConfidentialBalance(std::int64_t expectedAmount) const; [[nodiscard]] bool - checkFlags(uint32_t const expectedFlags, std::optional const& holder = std::nullopt) const; + checkFlags(uint32_t const expectedFlags, std::optional const& holder = std::nullopt) + const; [[nodiscard]] bool checkMetadata(std::string const& metadata) const; @@ -420,7 +421,9 @@ public: getIssuanceConfidentialBalance() const; std::optional - getEncryptedBalance(Account const& account, EncryptedBalanceType option = HOLDER_ENCRYPTED_INBOX) const; + getEncryptedBalance( + Account const& account, + EncryptedBalanceType option = HOLDER_ENCRYPTED_INBOX) const; MPT operator[](std::string const& name) const; @@ -455,8 +458,11 @@ public: getIssuanceOutstandingBalance() const; std::optional - getClawbackProof(Account const& holder, std::uint64_t amount, Buffer const& privateKey, uint256 const& txHash) - const; + getClawbackProof( + Account const& holder, + std::uint64_t amount, + Buffer const& privateKey, + uint256 const& txHash) const; std::optional getSchnorrProof(Account const& account, uint256 const& ctxHash) const;