From 7f169ef8643ab0f1f4e8aa778435dbc8c9a40acd Mon Sep 17 00:00:00 2001 From: yinyiqian1 Date: Tue, 1 Sep 2026 18:16:32 -0400 Subject: [PATCH] update --- include/xrpl/protocol/Protocol.h | 5 ++ .../xrpl/protocol/detail/ledger_entries.macro | 2 + include/xrpl/protocol/detail/sfields.macro | 3 +- .../xrpl/protocol/detail/transactions.macro | 1 - .../ConfidentialMPTMirrorUpdate.h | 37 ----------- .../token/ConfidentialMPTMirrorUpdate.cpp | 12 ---- .../app/ConfidentialMPTKeyRotation_test.cpp | 63 +------------------ src/test/jtx/impl/mpt.cpp | 4 +- src/test/jtx/mpt.h | 1 - .../ConfidentialMPTMirrorUpdateTests.cpp | 21 ------- 10 files changed, 11 insertions(+), 138 deletions(-) diff --git a/include/xrpl/protocol/Protocol.h b/include/xrpl/protocol/Protocol.h index 1b88eea456..08543e8321 100644 --- a/include/xrpl/protocol/Protocol.h +++ b/include/xrpl/protocol/Protocol.h @@ -540,6 +540,11 @@ constexpr std::size_t kEcConvertBackProofLength = */ constexpr std::size_t kEcClawbackProofLength = SECP256K1_COMPACT_CLAWBACK_PROOF_SIZE; +/** + * Length of compact equality proof. + */ +constexpr std::size_t kEcEqualityProofLength = 128; + /** * Extra base fee multiplier charged to confidential MPT transactions. */ diff --git a/include/xrpl/protocol/detail/ledger_entries.macro b/include/xrpl/protocol/detail/ledger_entries.macro index a3e62466d6..7e8c1a6561 100644 --- a/include/xrpl/protocol/detail/ledger_entries.macro +++ b/include/xrpl/protocol/detail/ledger_entries.macro @@ -410,6 +410,7 @@ LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({ {sfAuditorEncryptionKey, SoeOptional}, {sfIssuerKeyEpoch, SoeOptional}, {sfAuditorKeyEpoch, SoeOptional}, + {sfInitialIssuerEncryptionKey, SoeOptional}, {sfConfidentialOutstandingAmount, SoeDefault}, })) @@ -431,6 +432,7 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({ {sfAuditorEncryptedBalance, SoeOptional}, {sfIssuerKeyMirrorEpoch, SoeOptional}, {sfAuditorKeyMirrorEpoch, SoeOptional}, + {sfIssuerMirrorEncryptionKey, SoeOptional}, {sfHolderEncryptionKey, SoeOptional}, })) diff --git a/include/xrpl/protocol/detail/sfields.macro b/include/xrpl/protocol/detail/sfields.macro index a92fb6aee2..37b5b53754 100644 --- a/include/xrpl/protocol/detail/sfields.macro +++ b/include/xrpl/protocol/detail/sfields.macro @@ -322,7 +322,8 @@ TYPED_SFIELD(sfAuditorEncryptedAmount, VL, 43) TYPED_SFIELD(sfAuditorEncryptionKey, VL, 44) TYPED_SFIELD(sfAmountCommitment, VL, 45) TYPED_SFIELD(sfBalanceCommitment, VL, 46) -TYPED_SFIELD(sfPreviousIssuerEncryptionKey, VL, 47) +TYPED_SFIELD(sfInitialIssuerEncryptionKey, VL, 47) +TYPED_SFIELD(sfIssuerMirrorEncryptionKey, VL, 48) // account (common) TYPED_SFIELD(sfAccount, ACCOUNT, 1) diff --git a/include/xrpl/protocol/detail/transactions.macro b/include/xrpl/protocol/detail/transactions.macro index 2ffee8972c..41b64a5566 100644 --- a/include/xrpl/protocol/detail/transactions.macro +++ b/include/xrpl/protocol/detail/transactions.macro @@ -1143,7 +1143,6 @@ TRANSACTION(ttCONFIDENTIAL_MPT_MIRROR_UPDATE, 92, ConfidentialMPTMirrorUpdate, {sfHolder, SoeOptional}, {sfIssuerEncryptedAmount, SoeOptional}, {sfAuditorEncryptedAmount, SoeOptional}, - {sfPreviousIssuerEncryptionKey, SoeOptional}, {sfZKProof, SoeRequired}, })) diff --git a/include/xrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdate.h b/include/xrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdate.h index fddd6f6b13..9afd15005c 100644 --- a/include/xrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdate.h +++ b/include/xrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdate.h @@ -136,32 +136,6 @@ public: return this->tx_->isFieldPresent(sfAuditorEncryptedAmount); } - /** - * @brief Get sfPreviousIssuerEncryptionKey (SoeOptional) - * @return The field value, or std::nullopt if not present. - */ - [[nodiscard]] - protocol_autogen::Optional - getPreviousIssuerEncryptionKey() const - { - if (hasPreviousIssuerEncryptionKey()) - { - return this->tx_->at(sfPreviousIssuerEncryptionKey); - } - return std::nullopt; - } - - /** - * @brief Check if sfPreviousIssuerEncryptionKey is present. - * @return True if the field is present, false otherwise. - */ - [[nodiscard]] - bool - hasPreviousIssuerEncryptionKey() const - { - return this->tx_->isFieldPresent(sfPreviousIssuerEncryptionKey); - } - /** * @brief Get sfZKProof (SoeRequired) * @return The field value. @@ -264,17 +238,6 @@ public: return *this; } - /** - * @brief Set sfPreviousIssuerEncryptionKey (SoeOptional) - * @return Reference to this builder for method chaining. - */ - ConfidentialMPTMirrorUpdateBuilder& - setPreviousIssuerEncryptionKey(std::decay_t const& value) - { - object_[sfPreviousIssuerEncryptionKey] = value; - return *this; - } - /** * @brief Set sfZKProof (SoeRequired) * @return Reference to this builder for method chaining. diff --git a/src/libxrpl/tx/transactors/token/ConfidentialMPTMirrorUpdate.cpp b/src/libxrpl/tx/transactors/token/ConfidentialMPTMirrorUpdate.cpp index ef695dbed1..f4c7233a7d 100644 --- a/src/libxrpl/tx/transactors/token/ConfidentialMPTMirrorUpdate.cpp +++ b/src/libxrpl/tx/transactors/token/ConfidentialMPTMirrorUpdate.cpp @@ -62,14 +62,6 @@ ConfidentialMPTMirrorUpdate::preflight(PreflightContext const& ctx) if (!hasIssuerAmount && !hasAuditorAmount) return temMALFORMED; - // The previous issuer key is required exactly for an issuer-mode - // re-encryption of the issuer mirror,either issuer key rotation or - // issuer/auditor key simultaneous rotation. - bool const hasPreviousIssuerKey = ctx.tx.isFieldPresent(sfPreviousIssuerEncryptionKey); - bool const needsPreviousIssuerKey = hasHolder && hasIssuerAmount; - if (hasPreviousIssuerKey != needsPreviousIssuerKey) - return temMALFORMED; - // Check the length of the encrypted amounts. Length check is cheaper than format check so put // it before the format check. if (hasIssuerAmount && ctx.tx[sfIssuerEncryptedAmount].length() != kEcGamalEncryptedTotalLength) @@ -86,10 +78,6 @@ ConfidentialMPTMirrorUpdate::preflight(PreflightContext const& ctx) if (hasAuditorAmount && !isValidCiphertext(ctx.tx[sfAuditorEncryptedAmount])) return temBAD_CIPHERTEXT; - // If previous issuer key is present, it must be a valid EC point. - if (hasPreviousIssuerKey && !isValidCompressedECPoint(ctx.tx[sfPreviousIssuerEncryptionKey])) - return temMALFORMED; - // todo: check zkproof return tesSUCCESS; diff --git a/src/test/app/ConfidentialMPTKeyRotation_test.cpp b/src/test/app/ConfidentialMPTKeyRotation_test.cpp index 5425bf5c0e..f3e166ae0d 100644 --- a/src/test/app/ConfidentialMPTKeyRotation_test.cpp +++ b/src/test/app/ConfidentialMPTKeyRotation_test.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -775,17 +774,11 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .ownerCount = 1, .flags = tfMPTCanTransfer | tfMPTCanHoldConfidentialBalance, }); - mptAlice.generateKeyPair(alice); - - // A valid EC point - auto const validKey = mptAlice.getPubKey(alice); - // Issuer mode but account is not the issuer. mptAlice.mirrorUpdate({ .account = bob, .holder = carol, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = temMALFORMED, }); @@ -794,7 +787,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = alice, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = temMALFORMED, }); @@ -812,37 +804,11 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .err = temMALFORMED, }); - // Holder mode, previousIssuerKey should not be present. - mptAlice.mirrorUpdate({ - .account = bob, - .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, - .err = temMALFORMED, - }); - - // Issuer mode, previousIssuerKey is provided but issuerEncryptedAmount is missing. - mptAlice.mirrorUpdate({ - .account = alice, - .holder = bob, - .auditorEncryptedAmount = validCipher, - .previousIssuerKey = validKey, - .err = temMALFORMED, - }); - - // Issuer mode, issuerEncryptedAmount is present but previousIssuerKey is missing. - mptAlice.mirrorUpdate({ - .account = alice, - .holder = bob, - .issuerEncryptedAmount = validCipher, - .err = temMALFORMED, - }); - // Issuer amount has the wrong length. mptAlice.mirrorUpdate({ .account = alice, .holder = bob, .issuerEncryptedAmount = gMakeZeroBuffer(10), - .previousIssuerKey = validKey, .err = temBAD_CIPHERTEXT, }); @@ -859,7 +825,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = getBadCiphertext(), - .previousIssuerKey = validKey, .err = temBAD_CIPHERTEXT, }); @@ -869,18 +834,8 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .holder = bob, .issuerEncryptedAmount = validCipher, .auditorEncryptedAmount = getBadCiphertext(), - .previousIssuerKey = validKey, .err = temBAD_CIPHERTEXT, }); - - // previousIssuerKey is present but not a valid EC point. - mptAlice.mirrorUpdate({ - .account = alice, - .holder = bob, - .issuerEncryptedAmount = validCipher, - .previousIssuerKey = gMakeZeroBuffer(kEcPubKeyLength), - .err = temMALFORMED, - }); } void @@ -890,7 +845,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase using namespace test::jtx; Buffer const& validCipher = getTrivialCiphertext(); - Buffer const& validKey = getTrivialCommitment(); // The issuance does not exist. { @@ -924,7 +878,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_PERMISSION, }); } @@ -943,7 +896,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_PERMISSION, }); } @@ -964,7 +916,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = carol, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_TARGET, }); } @@ -984,7 +935,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecOBJECT_NOT_FOUND, }); } @@ -1005,7 +955,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_PERMISSION, }); } @@ -1039,7 +988,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_PERMISSION, }); } @@ -1129,7 +1077,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .holder = bob, .issuerEncryptedAmount = validCipher, .auditorEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_PERMISSION, }); } @@ -1162,7 +1109,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .holder = bob, .issuerEncryptedAmount = validCipher, .auditorEncryptedAmount = validCipher, - .previousIssuerKey = validKey, .err = tecNO_PERMISSION, }); } @@ -1294,7 +1240,7 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase std::uint64_t const amount = 100; // Issuer mode issuer-mirror migration. The new issuer mirror is written - // and the auissuerditor mirror epoch advances to the issuer key epoch. + // and the auditor mirror epoch advances to the issuer key epoch. { Env env{*this, features}; Account const alice("alice"); @@ -1316,7 +1262,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = newIssuerCipher, - .previousIssuerKey = ct.mpt.getPubKey(alice), }); auto const sle = env.le(keylet::mptoken(ct.mpt.issuanceID(), bob.id())); @@ -1331,7 +1276,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = newIssuerCipher, - .previousIssuerKey = ct.mpt.getPubKey(alice), .err = tecNO_PERMISSION, }); } @@ -1408,7 +1352,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .holder = bob, .issuerEncryptedAmount = newIssuerCipher, .auditorEncryptedAmount = newAuditorCipher, - .previousIssuerKey = ct.mpt.getPubKey(alice), }); auto const sle = env.le(keylet::mptoken(ct.mpt.issuanceID(), bob.id())); @@ -1619,7 +1562,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = newIssuerCipher, - .previousIssuerKey = ct.mpt.getPubKey(alice), }); { @@ -1636,7 +1578,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .account = alice, .holder = bob, .issuerEncryptedAmount = newIssuerCipher, - .previousIssuerKey = ct.mpt.getPubKey(alice), .err = tecNO_PERMISSION, }); @@ -1727,7 +1668,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .holder = bob, .issuerEncryptedAmount = bothIssuerCipher, .auditorEncryptedAmount = bothAuditorCipher, - .previousIssuerKey = ct.mpt.getPubKey(issuerKey3), }); { @@ -1747,7 +1687,6 @@ class ConfidentialMPTKeyRotation_test : public ConfidentialTransferTestBase .holder = bob, .issuerEncryptedAmount = bothIssuerCipher, .auditorEncryptedAmount = bothAuditorCipher, - .previousIssuerKey = ct.mpt.getPubKey(issuerKey5), .err = tecNO_PERMISSION, }); } diff --git a/src/test/jtx/impl/mpt.cpp b/src/test/jtx/impl/mpt.cpp index 66a6333dca..57d2ab60b9 100644 --- a/src/test/jtx/impl/mpt.cpp +++ b/src/test/jtx/impl/mpt.cpp @@ -2588,8 +2588,6 @@ MPTTester::mirrorUpdate(MPTMirrorUpdate const& arg) jv[sfIssuerEncryptedAmount] = strHex(*arg.issuerEncryptedAmount); if (arg.auditorEncryptedAmount) jv[sfAuditorEncryptedAmount] = strHex(*arg.auditorEncryptedAmount); - if (arg.previousIssuerKey) - jv[sfPreviousIssuerEncryptionKey] = strHex(*arg.previousIssuerKey); // Placeholder for proof, the logic will be added in the future if (arg.zkProof) @@ -2598,7 +2596,7 @@ MPTTester::mirrorUpdate(MPTMirrorUpdate const& arg) } else { - jv[sfZKProof] = strHex(gMakeZeroBuffer(kEcGamalEncryptedTotalLength)); + jv[sfZKProof] = strHex(gMakeZeroBuffer(kEcEqualityProofLength)); } submit(arg, jv); diff --git a/src/test/jtx/mpt.h b/src/test/jtx/mpt.h index bdcbb67beb..6cd9be4a4f 100644 --- a/src/test/jtx/mpt.h +++ b/src/test/jtx/mpt.h @@ -371,7 +371,6 @@ struct MPTMirrorUpdate std::optional id = std::nullopt; std::optional issuerEncryptedAmount = std::nullopt; std::optional auditorEncryptedAmount = std::nullopt; - std::optional previousIssuerKey = std::nullopt; std::optional zkProof = std::nullopt; std::optional fee = std::nullopt; std::optional flags = std::nullopt; diff --git a/src/tests/libxrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdateTests.cpp index d3d99f94af..6cbeb008bd 100644 --- a/src/tests/libxrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdateTests.cpp +++ b/src/tests/libxrpl/protocol_autogen/transactions/ConfidentialMPTMirrorUpdateTests.cpp @@ -33,7 +33,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, BuilderSettersRoundTrip) auto const holderValue = canonical_ACCOUNT(); auto const issuerEncryptedAmountValue = canonical_VL(); auto const auditorEncryptedAmountValue = canonical_VL(); - auto const previousIssuerEncryptionKeyValue = canonical_VL(); auto const zKProofValue = canonical_VL(); ConfidentialMPTMirrorUpdateBuilder builder{ @@ -48,7 +47,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, BuilderSettersRoundTrip) builder.setHolder(holderValue); builder.setIssuerEncryptedAmount(issuerEncryptedAmountValue); builder.setAuditorEncryptedAmount(auditorEncryptedAmountValue); - builder.setPreviousIssuerEncryptionKey(previousIssuerEncryptionKeyValue); auto tx = builder.build(publicKey, secretKey); @@ -102,14 +100,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, BuilderSettersRoundTrip) EXPECT_TRUE(tx.hasAuditorEncryptedAmount()); } - { - auto const& expected = previousIssuerEncryptionKeyValue; - auto const actualOpt = tx.getPreviousIssuerEncryptionKey(); - ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPreviousIssuerEncryptionKey should be present"; - expectEqualField(expected, *actualOpt, "sfPreviousIssuerEncryptionKey"); - EXPECT_TRUE(tx.hasPreviousIssuerEncryptionKey()); - } - } // 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, @@ -130,7 +120,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, BuilderFromStTxRoundTrip) auto const holderValue = canonical_ACCOUNT(); auto const issuerEncryptedAmountValue = canonical_VL(); auto const auditorEncryptedAmountValue = canonical_VL(); - auto const previousIssuerEncryptionKeyValue = canonical_VL(); auto const zKProofValue = canonical_VL(); // Build an initial transaction @@ -145,7 +134,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, BuilderFromStTxRoundTrip) initialBuilder.setHolder(holderValue); initialBuilder.setIssuerEncryptedAmount(issuerEncryptedAmountValue); initialBuilder.setAuditorEncryptedAmount(auditorEncryptedAmountValue); - initialBuilder.setPreviousIssuerEncryptionKey(previousIssuerEncryptionKeyValue); auto initialTx = initialBuilder.build(publicKey, secretKey); @@ -197,13 +185,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, BuilderFromStTxRoundTrip) expectEqualField(expected, *actualOpt, "sfAuditorEncryptedAmount"); } - { - auto const& expected = previousIssuerEncryptionKeyValue; - auto const actualOpt = rebuiltTx.getPreviousIssuerEncryptionKey(); - ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPreviousIssuerEncryptionKey should be present"; - expectEqualField(expected, *actualOpt, "sfPreviousIssuerEncryptionKey"); - } - } // 3) Verify wrapper throws when constructed from wrong transaction type. @@ -269,8 +250,6 @@ TEST(TransactionsConfidentialMPTMirrorUpdateTests, OptionalFieldsReturnNullopt) EXPECT_FALSE(tx.getIssuerEncryptedAmount().has_value()); EXPECT_FALSE(tx.hasAuditorEncryptedAmount()); EXPECT_FALSE(tx.getAuditorEncryptedAmount().has_value()); - EXPECT_FALSE(tx.hasPreviousIssuerEncryptionKey()); - EXPECT_FALSE(tx.getPreviousIssuerEncryptionKey().has_value()); } }