mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-18 21:10:02 +00:00
Apply clang-format due to new column size (#6311)
This commit is contained in:
@@ -29,8 +29,7 @@ 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;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -79,10 +78,7 @@ makeEcPair(Slice const& buffer, secp256k1_pubkey& out1, secp256k1_pubkey& out2);
|
||||
|
||||
// serialize two secp256k1_pubkey components back into compressed 66-byte form
|
||||
bool
|
||||
serializeEcPair(
|
||||
secp256k1_pubkey const& in1,
|
||||
secp256k1_pubkey const& in2,
|
||||
Buffer& buffer);
|
||||
serializeEcPair(secp256k1_pubkey const& in1, secp256k1_pubkey const& in2, Buffer& buffer);
|
||||
|
||||
/**
|
||||
* @brief Verifies that a buffer contains two valid, parsable EC public keys.
|
||||
@@ -100,22 +96,13 @@ homomorphicSubtract(Slice const& a, Slice const& b, Buffer& out);
|
||||
|
||||
// returns ciphertext and the blinding factor used
|
||||
std::optional<Buffer>
|
||||
encryptAmount(
|
||||
uint64_t const amt,
|
||||
Slice const& pubKeySlice,
|
||||
Slice const& blindingFactor);
|
||||
encryptAmount(uint64_t const amt, Slice const& pubKeySlice, Slice const& blindingFactor);
|
||||
|
||||
std::optional<Buffer>
|
||||
encryptCanonicalZeroAmount(
|
||||
Slice const& pubKeySlice,
|
||||
AccountID const& account,
|
||||
MPTID const& mptId);
|
||||
encryptCanonicalZeroAmount(Slice const& pubKeySlice, AccountID const& account, MPTID const& mptId);
|
||||
|
||||
TER
|
||||
verifySchnorrProof(
|
||||
Slice const& pubKeySlice,
|
||||
Slice const& proofSlice,
|
||||
uint256 const& contextHash);
|
||||
verifySchnorrProof(Slice const& pubKeySlice, Slice const& proofSlice, uint256 const& contextHash);
|
||||
|
||||
TER
|
||||
verifyElGamalEncryption(
|
||||
@@ -218,10 +205,7 @@ verifyBalancePcmLinkage(
|
||||
* @brief Generates a new secp256k1 key pair.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
secp256k1_elgamal_generate_keypair(
|
||||
secp256k1_context const* ctx,
|
||||
unsigned char* privkey,
|
||||
secp256k1_pubkey* pubkey);
|
||||
secp256k1_elgamal_generate_keypair(secp256k1_context const* ctx, unsigned char* privkey, secp256k1_pubkey* pubkey);
|
||||
|
||||
/**
|
||||
* @brief Encrypts a 64-bit amount using ElGamal.
|
||||
@@ -302,19 +286,14 @@ generate_canonical_encrypted_zero(
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
generate_random_scalar(
|
||||
secp256k1_context const* ctx,
|
||||
unsigned char* scalar_bytes);
|
||||
generate_random_scalar(secp256k1_context const* ctx, unsigned char* scalar_bytes);
|
||||
|
||||
/**
|
||||
* Computes the point M = amount * G.
|
||||
* IMPORTANT: This function MUST NOT be called with amount = 0.
|
||||
*/
|
||||
SECP256K1_API int
|
||||
compute_amount_point(
|
||||
secp256k1_context const* ctx,
|
||||
secp256k1_pubkey* mG,
|
||||
uint64_t amount);
|
||||
compute_amount_point(secp256k1_context const* ctx, secp256k1_pubkey* mG, uint64_t amount);
|
||||
|
||||
/**
|
||||
* Builds the challenge hash input for the NON-ZERO amount case.
|
||||
|
||||
@@ -469,8 +469,7 @@ 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))
|
||||
amount.clear(mptIssue);
|
||||
|
||||
@@ -45,8 +45,7 @@ getClawbackContextHash(
|
||||
AccountID const& holder)
|
||||
{
|
||||
Serializer s;
|
||||
addCommonZKPFields(
|
||||
s, ttCONFIDENTIAL_CLAWBACK, account, sequence, issuanceID);
|
||||
addCommonZKPFields(s, ttCONFIDENTIAL_CLAWBACK, account, sequence, issuanceID);
|
||||
|
||||
s.add64(amount);
|
||||
s.addBitString(holder);
|
||||
@@ -55,15 +54,10 @@ getClawbackContextHash(
|
||||
}
|
||||
|
||||
uint256
|
||||
getConvertContextHash(
|
||||
AccountID const& account,
|
||||
std::uint32_t sequence,
|
||||
uint192 const& issuanceID,
|
||||
std::uint64_t amount)
|
||||
getConvertContextHash(AccountID const& account, std::uint32_t sequence, uint192 const& issuanceID, std::uint64_t amount)
|
||||
{
|
||||
Serializer s;
|
||||
addCommonZKPFields(
|
||||
s, ttCONFIDENTIAL_CONVERT, account, sequence, issuanceID);
|
||||
addCommonZKPFields(s, ttCONFIDENTIAL_CONVERT, account, sequence, issuanceID);
|
||||
|
||||
s.add64(amount);
|
||||
|
||||
@@ -79,8 +73,7 @@ getConvertBackContextHash(
|
||||
std::uint32_t version)
|
||||
{
|
||||
Serializer s;
|
||||
addCommonZKPFields(
|
||||
s, ttCONFIDENTIAL_CONVERT_BACK, account, sequence, issuanceID);
|
||||
addCommonZKPFields(s, ttCONFIDENTIAL_CONVERT_BACK, account, sequence, issuanceID);
|
||||
|
||||
s.add64(amount);
|
||||
s.addInteger(version);
|
||||
@@ -93,10 +86,7 @@ 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<unsigned char const*>(slice.data()),
|
||||
slice.length());
|
||||
secp256k1Context(), &out, reinterpret_cast<unsigned char const*>(slice.data()), slice.length());
|
||||
};
|
||||
|
||||
Slice s1{buffer.data(), ecGamalEncryptedLength};
|
||||
@@ -109,15 +99,11 @@ makeEcPair(Slice const& buffer, secp256k1_pubkey& out1, secp256k1_pubkey& out2)
|
||||
}
|
||||
|
||||
bool
|
||||
serializeEcPair(
|
||||
secp256k1_pubkey const& in1,
|
||||
secp256k1_pubkey const& in2,
|
||||
Buffer& buffer)
|
||||
serializeEcPair(secp256k1_pubkey const& in1, secp256k1_pubkey const& in2, Buffer& 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;
|
||||
};
|
||||
|
||||
@@ -143,8 +129,7 @@ isValidCiphertext(Slice const& buffer)
|
||||
TER
|
||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
||||
{
|
||||
if (a.length() != ecGamalEncryptedTotalLength ||
|
||||
b.length() != ecGamalEncryptedTotalLength)
|
||||
if (a.length() != ecGamalEncryptedTotalLength || b.length() != ecGamalEncryptedTotalLength)
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey aC1;
|
||||
@@ -158,8 +143,7 @@ homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
||||
secp256k1_pubkey sumC1;
|
||||
secp256k1_pubkey sumC2;
|
||||
|
||||
if (secp256k1_elgamal_add(
|
||||
secp256k1Context(), &sumC1, &sumC2, &aC1, &aC2, &bC1, &bC2) != 1)
|
||||
if (secp256k1_elgamal_add(secp256k1Context(), &sumC1, &sumC2, &aC1, &aC2, &bC1, &bC2) != 1)
|
||||
return tecINTERNAL;
|
||||
|
||||
if (!serializeEcPair(sumC1, sumC2, out))
|
||||
@@ -171,8 +155,7 @@ homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
||||
TER
|
||||
homomorphicSubtract(Slice const& a, Slice const& b, Buffer& out)
|
||||
{
|
||||
if (a.length() != ecGamalEncryptedTotalLength ||
|
||||
b.length() != ecGamalEncryptedTotalLength)
|
||||
if (a.length() != ecGamalEncryptedTotalLength || b.length() != ecGamalEncryptedTotalLength)
|
||||
return tecINTERNAL;
|
||||
|
||||
secp256k1_pubkey aC1;
|
||||
@@ -186,8 +169,7 @@ 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))
|
||||
@@ -209,10 +191,7 @@ generateBlindingFactor()
|
||||
}
|
||||
|
||||
std::optional<Buffer>
|
||||
encryptAmount(
|
||||
uint64_t const amt,
|
||||
Slice const& pubKeySlice,
|
||||
Slice const& blindingFactor)
|
||||
encryptAmount(uint64_t const amt, Slice const& pubKeySlice, Slice const& blindingFactor)
|
||||
{
|
||||
Buffer buf(ecGamalEncryptedTotalLength);
|
||||
|
||||
@@ -226,8 +205,7 @@ encryptAmount(
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
// Encrypt the amount
|
||||
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;
|
||||
|
||||
// Serialize the ciphertext pair into the buffer
|
||||
@@ -238,10 +216,7 @@ encryptAmount(
|
||||
}
|
||||
|
||||
std::optional<Buffer>
|
||||
encryptCanonicalZeroAmount(
|
||||
Slice const& pubKeySlice,
|
||||
AccountID const& account,
|
||||
MPTID const& mptId)
|
||||
encryptCanonicalZeroAmount(Slice const& pubKeySlice, AccountID const& account, MPTID const& mptId)
|
||||
{
|
||||
if (pubKeySlice.size() != ecPubKeyLength)
|
||||
return std::nullopt; // LCOV_EXCL_LINE
|
||||
@@ -252,13 +227,7 @@ encryptCanonicalZeroAmount(
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
// Encrypt the amount
|
||||
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;
|
||||
|
||||
Buffer buf(ecGamalEncryptedTotalLength);
|
||||
@@ -271,10 +240,7 @@ encryptCanonicalZeroAmount(
|
||||
}
|
||||
|
||||
TER
|
||||
verifySchnorrProof(
|
||||
Slice const& pubKeySlice,
|
||||
Slice const& proofSlice,
|
||||
uint256 const& contextHash)
|
||||
verifySchnorrProof(Slice const& pubKeySlice, Slice const& proofSlice, uint256 const& contextHash)
|
||||
{
|
||||
// sanity check proof length
|
||||
if (proofSlice.size() != ecSchnorrProofLength)
|
||||
@@ -287,8 +253,7 @@ verifySchnorrProof(
|
||||
secp256k1_pubkey pubKey;
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
int result = secp256k1_mpt_pok_sk_verify(
|
||||
secp256k1Context(), proofSlice.data(), &pubKey, contextHash.data());
|
||||
int result = secp256k1_mpt_pok_sk_verify(secp256k1Context(), proofSlice.data(), &pubKey, contextHash.data());
|
||||
|
||||
if (result != 1)
|
||||
return tecBAD_PROOF;
|
||||
@@ -318,8 +283,8 @@ verifyElGamalEncryption(
|
||||
if (!makeEcPair(ciphertext, c1, c2))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
int result = secp256k1_elgamal_verify_encryption(
|
||||
secp256k1Context(), &c1, &c2, &pubKey, amount, blindingFactor.data());
|
||||
int result =
|
||||
secp256k1_elgamal_verify_encryption(secp256k1Context(), &c1, &c2, &pubKey, amount, blindingFactor.data());
|
||||
|
||||
if (result != 1)
|
||||
{
|
||||
@@ -337,15 +302,13 @@ verifyRevealedAmount(
|
||||
ConfidentialRecipient const& issuer,
|
||||
std::optional<ConfidentialRecipient> 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;
|
||||
@@ -353,11 +316,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;
|
||||
@@ -409,14 +369,7 @@ verifyMultiCiphertextEqualityProof(
|
||||
}
|
||||
|
||||
int const result = secp256k1_mpt_verify_same_plaintext_multi(
|
||||
secp256k1Context(),
|
||||
proof.data(),
|
||||
proof.size(),
|
||||
nRecipients,
|
||||
r.data(),
|
||||
s.data(),
|
||||
pk.data(),
|
||||
contextHash.data());
|
||||
secp256k1Context(), proof.data(), proof.size(), nRecipients, r.data(), s.data(), pk.data(), contextHash.data());
|
||||
|
||||
if (result != 1)
|
||||
return tecBAD_PROOF;
|
||||
@@ -440,13 +393,7 @@ verifyClawbackEqualityProof(
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
if (secp256k1_equality_plaintext_verify(
|
||||
secp256k1Context(),
|
||||
proof.data(),
|
||||
&pubKey,
|
||||
&c2,
|
||||
&c1,
|
||||
amount,
|
||||
contextHash.data()) != 1)
|
||||
secp256k1Context(), proof.data(), &pubKey, &c2, &c1, amount, contextHash.data()) != 1)
|
||||
{
|
||||
return tecBAD_PROOF;
|
||||
}
|
||||
@@ -457,19 +404,15 @@ verifyClawbackEqualityProof(
|
||||
NotTEC
|
||||
checkEncryptedAmountFormat(STObject const& object)
|
||||
{
|
||||
if (object[sfHolderEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength ||
|
||||
if (object[sfHolderEncryptedAmount].length() != ecGamalEncryptedTotalLength ||
|
||||
object[sfIssuerEncryptedAmount].length() != ecGamalEncryptedTotalLength)
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
bool const hasAuditor = object.isFieldPresent(sfAuditorEncryptedAmount);
|
||||
if (hasAuditor &&
|
||||
object[sfAuditorEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength)
|
||||
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]))
|
||||
@@ -505,13 +448,7 @@ verifyAmountPcmLinkage(
|
||||
std::memcpy(pcm.data, pcmSlice.data(), ecPedersenCommitmentLength);
|
||||
|
||||
if (secp256k1_elgamal_pedersen_link_verify(
|
||||
secp256k1Context(),
|
||||
proof.data(),
|
||||
&c1,
|
||||
&c2,
|
||||
&pubKey,
|
||||
&pcm,
|
||||
contextHash.data()) != 1)
|
||||
secp256k1Context(), proof.data(), &c1, &c2, &pubKey, &pcm, contextHash.data()) != 1)
|
||||
{
|
||||
return tecBAD_PROOF;
|
||||
}
|
||||
@@ -548,13 +485,7 @@ verifyBalancePcmLinkage(
|
||||
std::memcpy(pcm.data, pcmSlice.data(), ecPubKeyLength);
|
||||
|
||||
if (secp256k1_elgamal_pedersen_link_verify(
|
||||
secp256k1Context(),
|
||||
proof.data(),
|
||||
&pubKey,
|
||||
&c2,
|
||||
&c1,
|
||||
&pcm,
|
||||
contextHash.data()) != 1)
|
||||
secp256k1Context(), proof.data(), &pubKey, &c2, &c1, &pcm, contextHash.data()) != 1)
|
||||
{
|
||||
return tecBAD_PROOF;
|
||||
}
|
||||
@@ -565,10 +496,7 @@ verifyBalancePcmLinkage(
|
||||
// The following functions belong to the mpt-crypto library,
|
||||
// they will be finally removed and we will use conan2 to manage the dependency.
|
||||
int
|
||||
secp256k1_elgamal_generate_keypair(
|
||||
secp256k1_context const* ctx,
|
||||
unsigned char* privkey,
|
||||
secp256k1_pubkey* pubkey)
|
||||
secp256k1_elgamal_generate_keypair(secp256k1_context const* ctx, unsigned char* privkey, secp256k1_pubkey* pubkey)
|
||||
{
|
||||
// 1. Generate 32 random bytes for the private key
|
||||
do
|
||||
@@ -681,12 +609,10 @@ secp256k1_elgamal_decrypt(
|
||||
|
||||
// 2. Check for amount = 0 by comparing serialized points
|
||||
len = sizeof(c2_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx, c2_bytes, &len, c2, SECP256K1_EC_COMPRESSED) != 1)
|
||||
if (secp256k1_ec_pubkey_serialize(ctx, c2_bytes, &len, c2, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
len = sizeof(s_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx, s_bytes, &len, &S, SECP256K1_EC_COMPRESSED) != 1)
|
||||
if (secp256k1_ec_pubkey_serialize(ctx, s_bytes, &len, &S, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
if (memcmp(c2_bytes, s_bytes, sizeof(c2_bytes)) == 0)
|
||||
{
|
||||
@@ -706,8 +632,7 @@ secp256k1_elgamal_decrypt(
|
||||
|
||||
// 4. Serialize M once for comparison in the loop
|
||||
len = sizeof(m_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx, m_bytes, &len, &M, SECP256K1_EC_COMPRESSED) != 1)
|
||||
if (secp256k1_ec_pubkey_serialize(ctx, m_bytes, &len, &M, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
|
||||
// 5. Brute-force search loop
|
||||
@@ -718,12 +643,7 @@ secp256k1_elgamal_decrypt(
|
||||
for (i = 1; i <= 1000000; ++i)
|
||||
{
|
||||
len = sizeof(current_m_bytes);
|
||||
if (secp256k1_ec_pubkey_serialize(
|
||||
ctx,
|
||||
current_m_bytes,
|
||||
&len,
|
||||
¤t_M,
|
||||
SECP256K1_EC_COMPRESSED) != 1)
|
||||
if (secp256k1_ec_pubkey_serialize(ctx, current_m_bytes, &len, ¤t_M, SECP256K1_EC_COMPRESSED) != 1)
|
||||
return 0;
|
||||
if (memcmp(m_bytes, current_m_bytes, sizeof(m_bytes)) == 0)
|
||||
{
|
||||
@@ -781,8 +701,7 @@ secp256k1_elgamal_subtract(
|
||||
secp256k1_pubkey neg_b_c2 = *b_c2;
|
||||
|
||||
// Negate the copies
|
||||
if (secp256k1_ec_pubkey_negate(ctx, &neg_b_c1) != 1 ||
|
||||
secp256k1_ec_pubkey_negate(ctx, &neg_b_c2) != 1)
|
||||
if (secp256k1_ec_pubkey_negate(ctx, &neg_b_c1) != 1 || secp256k1_ec_pubkey_negate(ctx, &neg_b_c2) != 1)
|
||||
{
|
||||
return 0; // Negation failed
|
||||
}
|
||||
@@ -844,8 +763,7 @@ generate_canonical_encrypted_zero(
|
||||
unsigned char hash_input[51]; // Size calculated above
|
||||
|
||||
/* 1. Create the input buffer for hashing */
|
||||
build_hash_input(
|
||||
hash_input, sizeof(hash_input), account_id, mpt_issuance_id);
|
||||
build_hash_input(hash_input, sizeof(hash_input), account_id, mpt_issuance_id);
|
||||
|
||||
/* 2. Hash the buffer to create the deterministic scalar 'r' */
|
||||
do
|
||||
@@ -869,9 +787,7 @@ generate_canonical_encrypted_zero(
|
||||
}
|
||||
|
||||
int
|
||||
generate_random_scalar(
|
||||
secp256k1_context const* ctx,
|
||||
unsigned char* scalar_bytes)
|
||||
generate_random_scalar(secp256k1_context const* ctx, unsigned char* scalar_bytes)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -884,10 +800,7 @@ generate_random_scalar(
|
||||
}
|
||||
|
||||
int
|
||||
compute_amount_point(
|
||||
secp256k1_context const* ctx,
|
||||
secp256k1_pubkey* mG,
|
||||
uint64_t amount)
|
||||
compute_amount_point(secp256k1_context const* ctx, secp256k1_pubkey* mG, uint64_t amount)
|
||||
{
|
||||
unsigned char amount_scalar[32] = {0};
|
||||
/* This function assumes amount != 0 */
|
||||
@@ -915,35 +828,28 @@ build_challenge_hash_input_nonzero(
|
||||
char const* domain_sep = "MPT_POK_PLAINTEXT_PROOF"; // 23 bytes
|
||||
size_t offset = 0;
|
||||
size_t len;
|
||||
secp256k1_context* ser_ctx =
|
||||
secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
secp256k1_context* ser_ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
|
||||
memcpy(hash_input + offset, domain_sep, strlen(domain_sep));
|
||||
offset += strlen(domain_sep);
|
||||
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, c1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, c1, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, c2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, c2, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, pk, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, pk, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, mG, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, mG, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, T1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, T1, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, T2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, T2, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
|
||||
memcpy(hash_input + offset, tx_context_id, 32);
|
||||
@@ -966,31 +872,25 @@ build_challenge_hash_input_zero(
|
||||
char const* domain_sep = "MPT_POK_PLAINTEXT_PROOF"; // 23 bytes
|
||||
size_t offset = 0;
|
||||
size_t len;
|
||||
secp256k1_context* ser_ctx =
|
||||
secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
secp256k1_context* ser_ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
|
||||
memcpy(hash_input + offset, domain_sep, strlen(domain_sep));
|
||||
offset += strlen(domain_sep);
|
||||
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, c1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, c1, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, c2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, c2, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, pk, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, pk, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, T1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, T1, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, hash_input + offset, &len, T2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, hash_input + offset, &len, T2, SECP256K1_EC_COMPRESSED);
|
||||
offset += len;
|
||||
|
||||
memcpy(hash_input + offset, tx_context_id, 32);
|
||||
@@ -1042,8 +942,7 @@ secp256k1_equality_plaintext_prove(
|
||||
if (amount == 0)
|
||||
{
|
||||
unsigned char hash_input[220];
|
||||
build_challenge_hash_input_zero(
|
||||
hash_input, c1, c2, pk_recipient, &T1, &T2, tx_context_id);
|
||||
build_challenge_hash_input_zero(hash_input, c1, c2, pk_recipient, &T1, &T2, tx_context_id);
|
||||
SHA256(hash_input, sizeof(hash_input), e_scalar);
|
||||
}
|
||||
else
|
||||
@@ -1055,8 +954,7 @@ secp256k1_equality_plaintext_prove(
|
||||
memset(t_scalar, 0, 32);
|
||||
return 0;
|
||||
}
|
||||
build_challenge_hash_input_nonzero(
|
||||
hash_input, c1, c2, pk_recipient, &mG, &T1, &T2, tx_context_id);
|
||||
build_challenge_hash_input_nonzero(hash_input, c1, c2, pk_recipient, &mG, &T1, &T2, tx_context_id);
|
||||
SHA256(hash_input, sizeof(hash_input), e_scalar);
|
||||
}
|
||||
|
||||
@@ -1083,11 +981,9 @@ secp256k1_equality_plaintext_prove(
|
||||
|
||||
/* 5. Format the proof = T1(33) || T2(33) || s(32) */
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof, &len, &T1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof, &len, &T1, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof + 33, &len, &T2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof + 33, &len, &T2, SECP256K1_EC_COMPRESSED);
|
||||
memcpy(proof + 66, s_scalar, 32);
|
||||
|
||||
/* 6. Clear secret data */
|
||||
@@ -1133,8 +1029,7 @@ secp256k1_equality_plaintext_verify(
|
||||
if (amount == 0)
|
||||
{
|
||||
unsigned char hash_input[220];
|
||||
build_challenge_hash_input_zero(
|
||||
hash_input, c1, c2, pk_recipient, &T1, &T2, tx_context_id);
|
||||
build_challenge_hash_input_zero(hash_input, c1, c2, pk_recipient, &T1, &T2, tx_context_id);
|
||||
SHA256(hash_input, sizeof(hash_input), e_scalar);
|
||||
}
|
||||
else
|
||||
@@ -1143,8 +1038,7 @@ secp256k1_equality_plaintext_verify(
|
||||
unsigned char hash_input[253];
|
||||
if (!compute_amount_point(ctx, &mG, amount))
|
||||
return 0;
|
||||
build_challenge_hash_input_nonzero(
|
||||
hash_input, c1, c2, pk_recipient, &mG, &T1, &T2, tx_context_id);
|
||||
build_challenge_hash_input_nonzero(hash_input, c1, c2, pk_recipient, &mG, &T1, &T2, tx_context_id);
|
||||
SHA256(hash_input, sizeof(hash_input), e_scalar);
|
||||
}
|
||||
if (!secp256k1_ec_seckey_verify(ctx, e_scalar))
|
||||
@@ -1162,11 +1056,9 @@ secp256k1_equality_plaintext_verify(
|
||||
return 0;
|
||||
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, lhs_bytes, &len, &lhs_eq1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, lhs_bytes, &len, &lhs_eq1, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, rhs_bytes, &len, &rhs_eq1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, rhs_bytes, &len, &rhs_eq1, SECP256K1_EC_COMPRESSED);
|
||||
if (memcmp(lhs_bytes, rhs_bytes, 33) != 0)
|
||||
return 0; // Eq 1 failed
|
||||
|
||||
@@ -1189,8 +1081,7 @@ secp256k1_equality_plaintext_verify(
|
||||
return 0;
|
||||
points_to_add[0] = c2;
|
||||
points_to_add[1] = &mG;
|
||||
if (!secp256k1_ec_pubkey_combine(
|
||||
ctx, &rhs_eq2_term2_base, points_to_add, 2))
|
||||
if (!secp256k1_ec_pubkey_combine(ctx, &rhs_eq2_term2_base, points_to_add, 2))
|
||||
return 0; // Y = C2 - mG
|
||||
}
|
||||
|
||||
@@ -1205,11 +1096,9 @@ secp256k1_equality_plaintext_verify(
|
||||
|
||||
/* 4e. Compare LHS == RHS */
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, lhs_bytes, &len, &lhs_eq2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, lhs_bytes, &len, &lhs_eq2, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, rhs_bytes, &len, &rhs_eq2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, rhs_bytes, &len, &rhs_eq2, SECP256K1_EC_COMPRESSED);
|
||||
if (memcmp(lhs_bytes, rhs_bytes, 33) != 0)
|
||||
return 0; // Eq 2 failed
|
||||
|
||||
@@ -1276,8 +1165,7 @@ secp256k1_mpt_pok_sk_prove(
|
||||
|
||||
// 4. Serialize Proof: T (33 bytes) || s (32 bytes)
|
||||
size_t clen = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof, &clen, &T, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof, &clen, &T, SECP256K1_EC_COMPRESSED);
|
||||
memcpy(proof + 33, s, 32);
|
||||
|
||||
return 1;
|
||||
@@ -1318,11 +1206,9 @@ secp256k1_mpt_pok_sk_verify(
|
||||
// 4. Compare serialized points
|
||||
unsigned char ser_lhs[33], ser_rhs[33];
|
||||
size_t clen = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, ser_lhs, &clen, &lhs, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, ser_lhs, &clen, &lhs, SECP256K1_EC_COMPRESSED);
|
||||
clen = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, ser_rhs, &clen, &rhs, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, ser_rhs, &clen, &rhs, SECP256K1_EC_COMPRESSED);
|
||||
|
||||
return memcmp(ser_lhs, ser_rhs, 33) == 0;
|
||||
}
|
||||
@@ -1348,8 +1234,7 @@ secp256k1_elgamal_verify_encryption(
|
||||
|
||||
secp256k1_ec_pubkey_serialize(ctx, ser1, &len, c1, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, ser2, &len, &expected_c1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, ser2, &len, &expected_c1, SECP256K1_EC_COMPRESSED);
|
||||
if (memcmp(ser1, ser2, 33) != 0)
|
||||
return 0;
|
||||
|
||||
@@ -1381,8 +1266,7 @@ secp256k1_elgamal_verify_encryption(
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(ctx, ser1, &len, c2, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, ser2, &len, &expected_c2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, ser2, &len, &expected_c2, SECP256K1_EC_COMPRESSED);
|
||||
if (memcmp(ser1, ser2, 33) != 0)
|
||||
return 0;
|
||||
|
||||
@@ -1423,8 +1307,7 @@ build_link_challenge_hash(
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, hash_input + offset, &len, points[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, hash_input + offset, &len, points[i], SECP256K1_EC_COMPRESSED);
|
||||
offset += 33;
|
||||
}
|
||||
memcpy(hash_input + offset, context_id, 32);
|
||||
@@ -1443,13 +1326,11 @@ secp256k1_elgamal_pedersen_link_prove(
|
||||
unsigned char const* rho,
|
||||
unsigned char const* context_id)
|
||||
{
|
||||
unsigned char km[32], kr[32], krho[32], e[32], sm[32], sr[32], srho[32],
|
||||
m_sc[32] = {0};
|
||||
unsigned char km[32], kr[32], krho[32], e[32], sm[32], sr[32], srho[32], m_sc[32] = {0};
|
||||
secp256k1_pubkey T1, T2, T3, H, mG, rPk, rhoH;
|
||||
size_t len = 33;
|
||||
|
||||
if (!generate_random_scalar(ctx, km) || !generate_random_scalar(ctx, kr) ||
|
||||
!generate_random_scalar(ctx, krho))
|
||||
if (!generate_random_scalar(ctx, km) || !generate_random_scalar(ctx, kr) || !generate_random_scalar(ctx, krho))
|
||||
return 0;
|
||||
if (!secp256k1_ec_pubkey_create(ctx, &T1, kr))
|
||||
return 0;
|
||||
@@ -1470,8 +1351,7 @@ secp256k1_elgamal_pedersen_link_prove(
|
||||
return 0;
|
||||
|
||||
unsigned char hash_input[290];
|
||||
build_link_challenge_hash(
|
||||
ctx, hash_input, c1, c2, pk, pcm, &T1, &T2, &T3, context_id);
|
||||
build_link_challenge_hash(ctx, hash_input, c1, c2, pk, pcm, &T1, &T2, &T3, context_id);
|
||||
SHA256(hash_input, 290, e);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
@@ -1494,14 +1374,11 @@ secp256k1_elgamal_pedersen_link_prove(
|
||||
return 0;
|
||||
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof, &len, &T1, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof, &len, &T1, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof + 33, &len, &T2, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof + 33, &len, &T2, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof + 66, &len, &T3, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof + 66, &len, &T3, SECP256K1_EC_COMPRESSED);
|
||||
memcpy(proof + 99, sm, 32);
|
||||
memcpy(proof + 131, sr, 32);
|
||||
memcpy(proof + 163, srho, 32);
|
||||
@@ -1543,8 +1420,7 @@ secp256k1_elgamal_pedersen_link_verify(
|
||||
if (secp256k1_ec_seckey_verify(ctx, srho) != 1)
|
||||
return 0;
|
||||
|
||||
build_link_challenge_hash(
|
||||
ctx, hash_input, c1, c2, pk, pcm, &T1_p, &T2_p, &T3_p, context_id);
|
||||
build_link_challenge_hash(ctx, hash_input, c1, c2, pk, pcm, &T1_p, &T2_p, &T3_p, context_id);
|
||||
SHA256(hash_input, sizeof(hash_input), e);
|
||||
if (secp256k1_ec_seckey_verify(ctx, e) != 1)
|
||||
return 0;
|
||||
@@ -1563,20 +1439,18 @@ secp256k1_elgamal_pedersen_link_verify(
|
||||
(out) = _sum; \
|
||||
} while (0)
|
||||
|
||||
#define EQ_PUBKEY(A, B) \
|
||||
do \
|
||||
{ \
|
||||
unsigned char _a[33], _b[33]; \
|
||||
size_t _l = 33; \
|
||||
if (!secp256k1_ec_pubkey_serialize( \
|
||||
ctx, _a, &_l, (A), SECP256K1_EC_COMPRESSED)) \
|
||||
return 0; \
|
||||
_l = 33; \
|
||||
if (!secp256k1_ec_pubkey_serialize( \
|
||||
ctx, _b, &_l, (B), SECP256K1_EC_COMPRESSED)) \
|
||||
return 0; \
|
||||
if (memcmp(_a, _b, 33) != 0) \
|
||||
return 0; \
|
||||
#define EQ_PUBKEY(A, B) \
|
||||
do \
|
||||
{ \
|
||||
unsigned char _a[33], _b[33]; \
|
||||
size_t _l = 33; \
|
||||
if (!secp256k1_ec_pubkey_serialize(ctx, _a, &_l, (A), SECP256K1_EC_COMPRESSED)) \
|
||||
return 0; \
|
||||
_l = 33; \
|
||||
if (!secp256k1_ec_pubkey_serialize(ctx, _b, &_l, (B), SECP256K1_EC_COMPRESSED)) \
|
||||
return 0; \
|
||||
if (memcmp(_a, _b, 33) != 0) \
|
||||
return 0; \
|
||||
} while (0)
|
||||
|
||||
/* Eq 1 */
|
||||
@@ -1677,8 +1551,7 @@ build_hash_input(
|
||||
unsigned char buf[33];
|
||||
size_t len = 33;
|
||||
size_t i;
|
||||
secp256k1_context* ser_ctx =
|
||||
secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
secp256k1_context* ser_ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, domain, strlen(domain));
|
||||
@@ -1686,29 +1559,23 @@ build_hash_input(
|
||||
// Public Inputs (R, S, Pk for each ciphertext)
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, buf, &len, &R[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, buf, &len, &R[i], SECP256K1_EC_COMPRESSED);
|
||||
SHA256_Update(&sha_ctx, buf, 33);
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, buf, &len, &S[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, buf, &len, &S[i], SECP256K1_EC_COMPRESSED);
|
||||
SHA256_Update(&sha_ctx, buf, 33);
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, buf, &len, &Pk[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, buf, &len, &Pk[i], SECP256K1_EC_COMPRESSED);
|
||||
SHA256_Update(&sha_ctx, buf, 33);
|
||||
}
|
||||
|
||||
// Commitments
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, buf, &len, T_m, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, buf, &len, T_m, SECP256K1_EC_COMPRESSED);
|
||||
SHA256_Update(&sha_ctx, buf, 33);
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, buf, &len, &T_rG[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, buf, &len, &T_rG[i], SECP256K1_EC_COMPRESSED);
|
||||
SHA256_Update(&sha_ctx, buf, 33);
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ser_ctx, buf, &len, &T_rP[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ser_ctx, buf, &len, &T_rP[i], SECP256K1_EC_COMPRESSED);
|
||||
SHA256_Update(&sha_ctx, buf, 33);
|
||||
}
|
||||
|
||||
@@ -1816,19 +1683,16 @@ secp256k1_mpt_prove_same_plaintext_multi(
|
||||
size_t len = 33;
|
||||
|
||||
// Points
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof_out + offset, &len, &T_m, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof_out + offset, &len, &T_m, SECP256K1_EC_COMPRESSED);
|
||||
offset += 33;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof_out + offset, &len, &T_rG[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof_out + offset, &len, &T_rG[i], SECP256K1_EC_COMPRESSED);
|
||||
offset += 33;
|
||||
}
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, proof_out + offset, &len, &T_rP[i], SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, proof_out + offset, &len, &T_rP[i], SECP256K1_EC_COMPRESSED);
|
||||
offset += 33;
|
||||
}
|
||||
|
||||
@@ -1920,11 +1784,9 @@ secp256k1_mpt_verify_same_plaintext_multi(
|
||||
return 0;
|
||||
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, b1, &len, &lhs, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, b1, &len, &lhs, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, b2, &len, &rhs, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, b2, &len, &rhs, SECP256K1_EC_COMPRESSED);
|
||||
if (memcmp(b1, b2, 33) != 0)
|
||||
return 0;
|
||||
|
||||
@@ -1949,11 +1811,9 @@ secp256k1_mpt_verify_same_plaintext_multi(
|
||||
return 0;
|
||||
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, b1, &len, &lhs, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, b1, &len, &lhs, SECP256K1_EC_COMPRESSED);
|
||||
len = 33;
|
||||
secp256k1_ec_pubkey_serialize(
|
||||
ctx, b2, &len, &rhs, SECP256K1_EC_COMPRESSED);
|
||||
secp256k1_ec_pubkey_serialize(ctx, b2, &len, &rhs, SECP256K1_EC_COMPRESSED);
|
||||
if (memcmp(b1, b2, 33) != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -507,8 +507,7 @@ class MPToken_test : public beast::unit_test::suite
|
||||
// (2)
|
||||
mptAlice.set({.account = alice, .flags = 0x00000008, .err = temINVALID_FLAG});
|
||||
|
||||
if (!features[featureSingleAssetVault] &&
|
||||
!features[featureDynamicMPT] &&
|
||||
if (!features[featureSingleAssetVault] && !features[featureDynamicMPT] &&
|
||||
!features[featureConfidentialTransfer])
|
||||
{
|
||||
// test invalid flags - nothing is being changed
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -332,8 +332,7 @@ public:
|
||||
convertBack(MPTConvertBack const& arg = MPTConvertBack{});
|
||||
|
||||
void
|
||||
confidentialClaw(
|
||||
MPTConfidentialClawback const& arg = MPTConfidentialClawback{});
|
||||
confidentialClaw(MPTConfidentialClawback const& arg = MPTConfidentialClawback{});
|
||||
|
||||
[[nodiscard]] bool
|
||||
checkDomainID(std::optional<uint256> expected) const;
|
||||
@@ -348,9 +347,7 @@ public:
|
||||
checkIssuanceConfidentialBalance(std::int64_t expectedAmount) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
checkFlags(
|
||||
uint32_t const expectedFlags,
|
||||
std::optional<Account> const& holder = std::nullopt) const;
|
||||
checkFlags(uint32_t const expectedFlags, std::optional<Account> const& holder = std::nullopt) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
checkMetadata(std::string const& metadata) const;
|
||||
@@ -401,9 +398,7 @@ public:
|
||||
getIssuanceConfidentialBalance() const;
|
||||
|
||||
std::optional<Buffer>
|
||||
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;
|
||||
@@ -426,28 +421,20 @@ public:
|
||||
getPrivKey(Account const& account) const;
|
||||
|
||||
Buffer
|
||||
encryptAmount(
|
||||
Account const& account,
|
||||
uint64_t const amt,
|
||||
Buffer const& blindingFactor) const;
|
||||
encryptAmount(Account const& account, uint64_t const amt, Buffer const& blindingFactor) const;
|
||||
|
||||
std::optional<uint64_t>
|
||||
decryptAmount(Account const& account, Buffer const& amt) const;
|
||||
|
||||
std::optional<uint64_t>
|
||||
getDecryptedBalance(
|
||||
Account const& account,
|
||||
EncryptedBalanceType balanceType) const;
|
||||
getDecryptedBalance(Account const& account, EncryptedBalanceType balanceType) const;
|
||||
|
||||
std::int64_t
|
||||
getIssuanceOutstandingBalance() const;
|
||||
|
||||
std::optional<Buffer>
|
||||
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<Buffer>
|
||||
getSchnorrProof(Account const& account, uint256 const& ctxHash) const;
|
||||
@@ -492,9 +479,7 @@ public:
|
||||
PedersenProofParams const& params) const;
|
||||
|
||||
Buffer
|
||||
getPedersenCommitment(
|
||||
std::uint64_t const amount,
|
||||
Buffer const& pedersenBlindingFactor);
|
||||
getPedersenCommitment(std::uint64_t const amount, Buffer const& pedersenBlindingFactor);
|
||||
|
||||
private:
|
||||
using SLEP = SLE::const_pointer;
|
||||
|
||||
@@ -70,8 +70,7 @@ ConfidentialClawback::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// Check holder's MPToken
|
||||
auto const sleHolderMPToken =
|
||||
ctx.view.read(keylet::mptoken(mptIssuanceID, holder));
|
||||
auto const sleHolderMPToken = ctx.view.read(keylet::mptoken(mptIssuanceID, holder));
|
||||
if (!sleHolderMPToken)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
@@ -84,8 +83,7 @@ ConfidentialClawback::preclaim(PreclaimContext const& ctx)
|
||||
if (amount > (*sleIssuance)[~sfConfidentialOutstandingAmount].value_or(0))
|
||||
return tecINSUFFICIENT_FUNDS;
|
||||
|
||||
auto const contextHash = getClawbackContextHash(
|
||||
account, ctx.tx[sfSequence], mptIssuanceID, amount, holder);
|
||||
auto const contextHash = getClawbackContextHash(account, ctx.tx[sfSequence], mptIssuanceID, amount, holder);
|
||||
|
||||
// Verify the revealed confidential amount by the issuer matches the exact
|
||||
// confidential balance of the holder.
|
||||
@@ -115,13 +113,11 @@ ConfidentialClawback::doApply()
|
||||
Slice const issuerPubKey = (*sleIssuance)[sfIssuerElGamalPublicKey];
|
||||
|
||||
// After clawback, the balance should be encrypted zero.
|
||||
auto const encZeroForHolder =
|
||||
encryptCanonicalZeroAmount(holderPubKey, holder, mptIssuanceID);
|
||||
auto const encZeroForHolder = encryptCanonicalZeroAmount(holderPubKey, holder, mptIssuanceID);
|
||||
if (!encZeroForHolder)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const encZeroForIssuer =
|
||||
encryptCanonicalZeroAmount(issuerPubKey, holder, mptIssuanceID);
|
||||
auto const encZeroForIssuer = encryptCanonicalZeroAmount(issuerPubKey, holder, mptIssuanceID);
|
||||
if (!encZeroForIssuer)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -140,8 +136,7 @@ ConfidentialClawback::doApply()
|
||||
|
||||
Slice const auditorPubKey = (*sleIssuance)[sfAuditorElGamalPublicKey];
|
||||
|
||||
auto const encZeroForAuditor =
|
||||
encryptCanonicalZeroAmount(auditorPubKey, holder, mptIssuanceID);
|
||||
auto const encZeroForAuditor = encryptCanonicalZeroAmount(auditorPubKey, holder, mptIssuanceID);
|
||||
|
||||
if (!encZeroForAuditor)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -80,8 +80,7 @@ ConfidentialConvert::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
bool const hasAuditor = ctx.tx.isFieldPresent(sfAuditorEncryptedAmount);
|
||||
bool const requiresAuditor =
|
||||
sleIssuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
bool const requiresAuditor = sleIssuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
|
||||
// tx must include auditor ciphertext if the issuance has enabled
|
||||
// auditing, and must not include it if auditing is not enabled
|
||||
@@ -93,8 +92,7 @@ ConfidentialConvert::preclaim(PreclaimContext const& ctx)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
auto const mptIssue = MPTIssue{issuanceID};
|
||||
STAmount const mptAmount = STAmount(
|
||||
MPTAmount{static_cast<MPTAmount::value_type>(amount)}, mptIssue);
|
||||
STAmount const mptAmount = STAmount(MPTAmount{static_cast<MPTAmount::value_type>(amount)}, mptIssue);
|
||||
if (accountHolds(
|
||||
ctx.view,
|
||||
account,
|
||||
@@ -106,10 +104,8 @@ ConfidentialConvert::preclaim(PreclaimContext const& ctx)
|
||||
return tecINSUFFICIENT_FUNDS;
|
||||
}
|
||||
|
||||
auto const hasHolderKeyOnLedger =
|
||||
sleMptoken->isFieldPresent(sfHolderElGamalPublicKey);
|
||||
auto const hasHolderKeyInTx =
|
||||
ctx.tx.isFieldPresent(sfHolderElGamalPublicKey);
|
||||
auto const hasHolderKeyOnLedger = sleMptoken->isFieldPresent(sfHolderElGamalPublicKey);
|
||||
auto const hasHolderKeyInTx = ctx.tx.isFieldPresent(sfHolderElGamalPublicKey);
|
||||
|
||||
// must have pk to convert
|
||||
if (!hasHolderKeyOnLedger && !hasHolderKeyInTx)
|
||||
@@ -124,12 +120,10 @@ ConfidentialConvert::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
holderPubKey = ctx.tx[sfHolderElGamalPublicKey];
|
||||
|
||||
auto const contextHash = getConvertContextHash(
|
||||
account, ctx.tx[sfSequence], issuanceID, amount);
|
||||
auto const contextHash = getConvertContextHash(account, ctx.tx[sfSequence], issuanceID, amount);
|
||||
|
||||
// when register new pk, verify through schnorr proof
|
||||
if (!isTesSuccess(verifySchnorrProof(
|
||||
holderPubKey, ctx.tx[sfZKProof], contextHash)))
|
||||
if (!isTesSuccess(verifySchnorrProof(holderPubKey, ctx.tx[sfZKProof], contextHash)))
|
||||
{
|
||||
return tecBAD_PROOF;
|
||||
}
|
||||
@@ -142,17 +136,15 @@ ConfidentialConvert::preclaim(PreclaimContext const& ctx)
|
||||
std::optional<ConfidentialRecipient> auditor;
|
||||
if (hasAuditor)
|
||||
{
|
||||
auditor.emplace(ConfidentialRecipient{
|
||||
(*sleIssuance)[sfAuditorElGamalPublicKey],
|
||||
ctx.tx[sfAuditorEncryptedAmount]});
|
||||
auditor.emplace(
|
||||
ConfidentialRecipient{(*sleIssuance)[sfAuditorElGamalPublicKey], ctx.tx[sfAuditorEncryptedAmount]});
|
||||
}
|
||||
|
||||
return verifyRevealedAmount(
|
||||
amount,
|
||||
ctx.tx[sfBlindingFactor],
|
||||
{holderPubKey, ctx.tx[sfHolderEncryptedAmount]},
|
||||
{(*sleIssuance)[sfIssuerElGamalPublicKey],
|
||||
ctx.tx[sfIssuerEncryptedAmount]},
|
||||
{(*sleIssuance)[sfIssuerElGamalPublicKey], ctx.tx[sfIssuerEncryptedAmount]},
|
||||
auditor);
|
||||
}
|
||||
|
||||
@@ -173,13 +165,11 @@ ConfidentialConvert::doApply()
|
||||
auto const amt = (*sleMptoken)[~sfMPTAmount].value_or(0);
|
||||
|
||||
if (ctx_.tx.isFieldPresent(sfHolderElGamalPublicKey))
|
||||
(*sleMptoken)[sfHolderElGamalPublicKey] =
|
||||
ctx_.tx[sfHolderElGamalPublicKey];
|
||||
(*sleMptoken)[sfHolderElGamalPublicKey] = ctx_.tx[sfHolderElGamalPublicKey];
|
||||
|
||||
(*sleMptoken)[sfMPTAmount] = amt - amtToConvert;
|
||||
(*sleIssuance)[sfConfidentialOutstandingAmount] =
|
||||
(*sleIssuance)[~sfConfidentialOutstandingAmount].value_or(0) +
|
||||
amtToConvert;
|
||||
(*sleIssuance)[~sfConfidentialOutstandingAmount].value_or(0) + amtToConvert;
|
||||
|
||||
Slice const holderEc = ctx_.tx[sfHolderEncryptedAmount];
|
||||
Slice const issuerEc = ctx_.tx[sfIssuerEncryptedAmount];
|
||||
@@ -195,8 +185,7 @@ ConfidentialConvert::doApply()
|
||||
// homomorphically add holder's encrypted balance
|
||||
{
|
||||
Buffer sum(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicAdd(
|
||||
holderEc, (*sleMptoken)[sfConfidentialBalanceInbox], sum);
|
||||
if (TER const ter = homomorphicAdd(holderEc, (*sleMptoken)[sfConfidentialBalanceInbox], sum);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
@@ -206,8 +195,7 @@ ConfidentialConvert::doApply()
|
||||
// homomorphically add issuer's encrypted balance
|
||||
{
|
||||
Buffer sum(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicAdd(
|
||||
issuerEc, (*sleMptoken)[sfIssuerEncryptedBalance], sum);
|
||||
if (TER const ter = homomorphicAdd(issuerEc, (*sleMptoken)[sfIssuerEncryptedBalance], sum);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
@@ -218,8 +206,7 @@ ConfidentialConvert::doApply()
|
||||
if (auditorEc)
|
||||
{
|
||||
Buffer sum(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicAdd(
|
||||
*auditorEc, (*sleMptoken)[sfAuditorEncryptedBalance], sum);
|
||||
if (TER const ter = homomorphicAdd(*auditorEc, (*sleMptoken)[sfAuditorEncryptedBalance], sum);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
@@ -239,8 +226,8 @@ ConfidentialConvert::doApply()
|
||||
(*sleMptoken)[sfAuditorEncryptedBalance] = *auditorEc;
|
||||
|
||||
// encrypt sfConfidentialBalanceSpending with zero balance
|
||||
auto const zeroBalance = encryptCanonicalZeroAmount(
|
||||
(*sleMptoken)[sfHolderElGamalPublicKey], account_, mptIssuanceID);
|
||||
auto const zeroBalance =
|
||||
encryptCanonicalZeroAmount((*sleMptoken)[sfHolderElGamalPublicKey], account_, mptIssuanceID);
|
||||
|
||||
if (!zeroBalance)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -40,10 +40,7 @@ ConfidentialConvertBack::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
TER
|
||||
verifyProofs(
|
||||
STTx const& tx,
|
||||
std::shared_ptr<SLE const> const& issuance,
|
||||
std::shared_ptr<SLE const> const& mptoken)
|
||||
verifyProofs(STTx const& tx, std::shared_ptr<SLE const> const& issuance, std::shared_ptr<SLE const> const& mptoken)
|
||||
{
|
||||
if (!mptoken->isFieldPresent(sfHolderElGamalPublicKey))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
@@ -55,28 +52,21 @@ verifyProofs(
|
||||
auto const holderPubKey = (*mptoken)[sfHolderElGamalPublicKey];
|
||||
|
||||
auto const contextHash = getConvertBackContextHash(
|
||||
account,
|
||||
tx[sfSequence],
|
||||
mptIssuanceID,
|
||||
amount,
|
||||
(*mptoken)[~sfConfidentialBalanceVersion].value_or(0));
|
||||
account, tx[sfSequence], mptIssuanceID, amount, (*mptoken)[~sfConfidentialBalanceVersion].value_or(0));
|
||||
|
||||
// Prepare Auditor Info
|
||||
std::optional<ConfidentialRecipient> auditor;
|
||||
bool const hasAuditor = issuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
if (hasAuditor)
|
||||
{
|
||||
auditor.emplace(ConfidentialRecipient{
|
||||
(*issuance)[sfAuditorElGamalPublicKey],
|
||||
tx[sfAuditorEncryptedAmount]});
|
||||
auditor.emplace(ConfidentialRecipient{(*issuance)[sfAuditorElGamalPublicKey], tx[sfAuditorEncryptedAmount]});
|
||||
}
|
||||
|
||||
if (auto const ter = verifyRevealedAmount(
|
||||
amount,
|
||||
blindingFactor,
|
||||
{holderPubKey, tx[sfHolderEncryptedAmount]},
|
||||
{(*issuance)[sfIssuerElGamalPublicKey],
|
||||
tx[sfIssuerEncryptedAmount]},
|
||||
{(*issuance)[sfIssuerElGamalPublicKey], tx[sfIssuerEncryptedAmount]},
|
||||
auditor);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
@@ -124,8 +114,7 @@ ConfidentialConvertBack::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
bool const hasAuditor = ctx.tx.isFieldPresent(sfAuditorEncryptedAmount);
|
||||
bool const requiresAuditor =
|
||||
sleIssuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
bool const requiresAuditor = sleIssuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
|
||||
// tx must include auditor ciphertext if the issuance has enabled
|
||||
// auditing
|
||||
@@ -142,8 +131,7 @@ ConfidentialConvertBack::preclaim(PreclaimContext const& ctx)
|
||||
if (sleIssuance->getAccountID(sfIssuer) == account)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sleMptoken =
|
||||
ctx.view.read(keylet::mptoken(mptIssuanceID, account));
|
||||
auto const sleMptoken = ctx.view.read(keylet::mptoken(mptIssuanceID, account));
|
||||
if (!sleMptoken)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
@@ -163,17 +151,14 @@ ConfidentialConvertBack::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Check lock
|
||||
MPTIssue const mptIssue(mptIssuanceID);
|
||||
if (auto const ter = checkFrozen(ctx.view, account, mptIssue);
|
||||
!isTesSuccess(ter))
|
||||
if (auto const ter = checkFrozen(ctx.view, account, mptIssue); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
// Check auth
|
||||
if (auto const ter = requireAuth(ctx.view, mptIssue, account);
|
||||
!isTesSuccess(ter))
|
||||
if (auto const ter = requireAuth(ctx.view, mptIssue, account); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (TER const res = verifyProofs(ctx.tx, sleIssuance, sleMptoken);
|
||||
!isTesSuccess(res))
|
||||
if (TER const res = verifyProofs(ctx.tx, sleIssuance, sleMptoken); !isTesSuccess(res))
|
||||
return res;
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -205,9 +190,7 @@ ConfidentialConvertBack::doApply()
|
||||
{
|
||||
Buffer res(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicSubtract(
|
||||
(*sleMptoken)[sfConfidentialBalanceSpending],
|
||||
ctx_.tx[sfHolderEncryptedAmount],
|
||||
res);
|
||||
(*sleMptoken)[sfConfidentialBalanceSpending], ctx_.tx[sfHolderEncryptedAmount], res);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
@@ -217,10 +200,8 @@ ConfidentialConvertBack::doApply()
|
||||
// homomorphically subtract issuer's encrypted balance
|
||||
{
|
||||
Buffer res(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicSubtract(
|
||||
(*sleMptoken)[sfIssuerEncryptedBalance],
|
||||
ctx_.tx[sfIssuerEncryptedAmount],
|
||||
res);
|
||||
if (TER const ter =
|
||||
homomorphicSubtract((*sleMptoken)[sfIssuerEncryptedBalance], ctx_.tx[sfIssuerEncryptedAmount], res);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
@@ -230,10 +211,8 @@ ConfidentialConvertBack::doApply()
|
||||
if (auditorEc)
|
||||
{
|
||||
Buffer res(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicSubtract(
|
||||
(*sleMptoken)[sfAuditorEncryptedBalance],
|
||||
ctx_.tx[sfAuditorEncryptedAmount],
|
||||
res);
|
||||
if (TER const ter =
|
||||
homomorphicSubtract((*sleMptoken)[sfAuditorEncryptedBalance], ctx_.tx[sfAuditorEncryptedAmount], res);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ ConfidentialMergeInbox::preflight(PreflightContext const& ctx)
|
||||
TER
|
||||
ConfidentialMergeInbox::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const sleIssuance =
|
||||
ctx.view.read(keylet::mptIssuance(ctx.tx[sfMPTokenIssuanceID]));
|
||||
auto const sleIssuance = ctx.view.read(keylet::mptIssuance(ctx.tx[sfMPTokenIssuanceID]));
|
||||
if (!sleIssuance)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
@@ -38,8 +37,7 @@ ConfidentialMergeInbox::preclaim(PreclaimContext const& ctx)
|
||||
if (sleIssuance->getAccountID(sfIssuer) == ctx.tx[sfAccount])
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sleMptoken = ctx.view.read(
|
||||
keylet::mptoken(ctx.tx[sfMPTokenIssuanceID], ctx.tx[sfAccount]));
|
||||
auto const sleMptoken = ctx.view.read(keylet::mptoken(ctx.tx[sfMPTokenIssuanceID], ctx.tx[sfAccount]));
|
||||
if (!sleMptoken)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
@@ -70,16 +68,14 @@ ConfidentialMergeInbox::doApply()
|
||||
// homomorphically add holder's encrypted balance
|
||||
Buffer sum(ecGamalEncryptedTotalLength);
|
||||
if (TER const ter = homomorphicAdd(
|
||||
(*sleMptoken)[sfConfidentialBalanceSpending],
|
||||
(*sleMptoken)[sfConfidentialBalanceInbox],
|
||||
sum);
|
||||
(*sleMptoken)[sfConfidentialBalanceSpending], (*sleMptoken)[sfConfidentialBalanceInbox], sum);
|
||||
!isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleMptoken)[sfConfidentialBalanceSpending] = sum;
|
||||
|
||||
auto const zeroEncryption = encryptCanonicalZeroAmount(
|
||||
(*sleMptoken)[sfHolderElGamalPublicKey], account_, mptIssuanceID);
|
||||
auto const zeroEncryption =
|
||||
encryptCanonicalZeroAmount((*sleMptoken)[sfHolderElGamalPublicKey], account_, mptIssuanceID);
|
||||
|
||||
if (!zeroEncryption)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
@@ -87,8 +83,7 @@ ConfidentialMergeInbox::doApply()
|
||||
(*sleMptoken)[sfConfidentialBalanceInbox] = *zeroEncryption;
|
||||
|
||||
// it's fine if it reaches max uint32, it just resets to 0
|
||||
(*sleMptoken)[sfConfidentialBalanceVersion] =
|
||||
(*sleMptoken)[~sfConfidentialBalanceVersion].value_or(0u) + 1u;
|
||||
(*sleMptoken)[sfConfidentialBalanceVersion] = (*sleMptoken)[~sfConfidentialBalanceVersion].value_or(0u) + 1u;
|
||||
|
||||
view().update(sleMptoken);
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -30,23 +30,18 @@ ConfidentialSend::preflight(PreflightContext const& ctx)
|
||||
return temMALFORMED;
|
||||
|
||||
// Check the length of the encrypted amounts
|
||||
if (ctx.tx[sfSenderEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength ||
|
||||
ctx.tx[sfDestinationEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength ||
|
||||
if (ctx.tx[sfSenderEncryptedAmount].length() != ecGamalEncryptedTotalLength ||
|
||||
ctx.tx[sfDestinationEncryptedAmount].length() != ecGamalEncryptedTotalLength ||
|
||||
ctx.tx[sfIssuerEncryptedAmount].length() != ecGamalEncryptedTotalLength)
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
bool const hasAuditor = ctx.tx.isFieldPresent(sfAuditorEncryptedAmount);
|
||||
if (hasAuditor &&
|
||||
ctx.tx[sfAuditorEncryptedAmount].length() !=
|
||||
ecGamalEncryptedTotalLength)
|
||||
if (hasAuditor && ctx.tx[sfAuditorEncryptedAmount].length() != ecGamalEncryptedTotalLength)
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
// Check the length of the ZKProof
|
||||
auto const recipientCount = getConfidentialRecipientCount(hasAuditor);
|
||||
auto const sizeEquality =
|
||||
getMultiCiphertextEqualityProofSize(recipientCount);
|
||||
auto const sizeEquality = getMultiCiphertextEqualityProofSize(recipientCount);
|
||||
auto const sizePedersenLinkage = 2 * ecPedersenProofLength;
|
||||
|
||||
if (ctx.tx[sfZKProof].length() != sizeEquality + sizePedersenLinkage)
|
||||
@@ -60,8 +55,7 @@ ConfidentialSend::preflight(PreflightContext const& ctx)
|
||||
// Check the encrypted amount formats, this is more expensive so put it at
|
||||
// the end
|
||||
if (!isValidCiphertext(ctx.tx[sfSenderEncryptedAmount]) ||
|
||||
!isValidCiphertext(ctx.tx[sfDestinationEncryptedAmount]) ||
|
||||
!isValidCiphertext(ctx.tx[sfIssuerEncryptedAmount]))
|
||||
!isValidCiphertext(ctx.tx[sfDestinationEncryptedAmount]) || !isValidCiphertext(ctx.tx[sfIssuerEncryptedAmount]))
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
if (hasAuditor && !isValidCiphertext(ctx.tx[sfAuditorEncryptedAmount]))
|
||||
@@ -88,8 +82,7 @@ verifySendProofs(
|
||||
size_t currentOffset = 0;
|
||||
|
||||
// Extract equality proof
|
||||
auto const sizeEquality =
|
||||
getMultiCiphertextEqualityProofSize(recipientCount);
|
||||
auto const sizeEquality = getMultiCiphertextEqualityProofSize(recipientCount);
|
||||
if (remainingLength < sizeEquality)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -101,8 +94,7 @@ verifySendProofs(
|
||||
if (remainingLength < ecPedersenProofLength)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const amountLinkageProof =
|
||||
proof.substr(currentOffset, ecPedersenProofLength);
|
||||
auto const amountLinkageProof = proof.substr(currentOffset, ecPedersenProofLength);
|
||||
currentOffset += ecPedersenProofLength;
|
||||
remainingLength -= ecPedersenProofLength;
|
||||
|
||||
@@ -110,8 +102,7 @@ verifySendProofs(
|
||||
if (remainingLength < ecPedersenProofLength)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const balanceLinkageProof =
|
||||
proof.substr(currentOffset, ecPedersenProofLength);
|
||||
auto const balanceLinkageProof = proof.substr(currentOffset, ecPedersenProofLength);
|
||||
currentOffset += ecPedersenProofLength;
|
||||
remainingLength -= ecPedersenProofLength;
|
||||
|
||||
@@ -123,23 +114,15 @@ verifySendProofs(
|
||||
std::vector<ConfidentialRecipient> recipients;
|
||||
recipients.reserve(recipientCount);
|
||||
|
||||
recipients.push_back(
|
||||
{(*sleSenderMPToken)[sfHolderElGamalPublicKey],
|
||||
ctx.tx[sfSenderEncryptedAmount]});
|
||||
recipients.push_back({(*sleSenderMPToken)[sfHolderElGamalPublicKey], ctx.tx[sfSenderEncryptedAmount]});
|
||||
|
||||
recipients.push_back(
|
||||
{(*sleDestinationMPToken)[sfHolderElGamalPublicKey],
|
||||
ctx.tx[sfDestinationEncryptedAmount]});
|
||||
recipients.push_back({(*sleDestinationMPToken)[sfHolderElGamalPublicKey], ctx.tx[sfDestinationEncryptedAmount]});
|
||||
|
||||
recipients.push_back(
|
||||
{(*sleIssuance)[sfIssuerElGamalPublicKey],
|
||||
ctx.tx[sfIssuerEncryptedAmount]});
|
||||
recipients.push_back({(*sleIssuance)[sfIssuerElGamalPublicKey], ctx.tx[sfIssuerEncryptedAmount]});
|
||||
|
||||
if (hasAuditor)
|
||||
{
|
||||
recipients.push_back(
|
||||
{(*sleIssuance)[sfAuditorElGamalPublicKey],
|
||||
ctx.tx[sfAuditorEncryptedAmount]});
|
||||
recipients.push_back({(*sleIssuance)[sfAuditorElGamalPublicKey], ctx.tx[sfAuditorEncryptedAmount]});
|
||||
}
|
||||
|
||||
// Prepare the context hash
|
||||
@@ -151,8 +134,7 @@ verifySendProofs(
|
||||
(*sleSenderMPToken)[~sfConfidentialBalanceVersion].value_or(0));
|
||||
|
||||
// Verify the multi-ciphertext equality proof
|
||||
if (auto const ter = verifyMultiCiphertextEqualityProof(
|
||||
equalityProof, recipients, recipientCount, contextHash);
|
||||
if (auto const ter = verifyMultiCiphertextEqualityProof(equalityProof, recipients, recipientCount, contextHash);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "ConfidentialSend: Equality proof failed.";
|
||||
@@ -181,8 +163,7 @@ verifySendProofs(
|
||||
contextHash);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "ConfidentialSend: Balance linkage proof failed.";
|
||||
JLOG(ctx.j.trace()) << "ConfidentialSend: Balance linkage proof failed.";
|
||||
return ter;
|
||||
}
|
||||
|
||||
@@ -221,8 +202,7 @@ ConfidentialSend::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
bool const hasAuditor = ctx.tx.isFieldPresent(sfAuditorEncryptedAmount);
|
||||
bool const requiresAuditor =
|
||||
sleIssuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
bool const requiresAuditor = sleIssuance->isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
|
||||
// Tx must include auditor ciphertext if the issuance has enabled
|
||||
// auditing, and must not include it if auditing is not enabled
|
||||
@@ -234,8 +214,7 @@ ConfidentialSend::preclaim(PreclaimContext const& ctx)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Check sender's MPToken existence
|
||||
auto const sleSenderMPToken =
|
||||
ctx.view.read(keylet::mptoken(mptIssuanceID, account));
|
||||
auto const sleSenderMPToken = ctx.view.read(keylet::mptoken(mptIssuanceID, account));
|
||||
if (!sleSenderMPToken)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
@@ -247,13 +226,11 @@ ConfidentialSend::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Sanity check: MPToken's auditor field must be present if auditing is
|
||||
// enabled
|
||||
if (requiresAuditor &&
|
||||
!sleSenderMPToken->isFieldPresent(sfAuditorEncryptedBalance))
|
||||
if (requiresAuditor && !sleSenderMPToken->isFieldPresent(sfAuditorEncryptedBalance))
|
||||
return tefINTERNAL;
|
||||
|
||||
// Check destination's MPToken existence
|
||||
auto const sleDestinationMPToken =
|
||||
ctx.view.read(keylet::mptoken(mptIssuanceID, destination));
|
||||
auto const sleDestinationMPToken = ctx.view.read(keylet::mptoken(mptIssuanceID, destination));
|
||||
if (!sleDestinationMPToken)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
@@ -265,25 +242,20 @@ ConfidentialSend::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Check lock
|
||||
MPTIssue const mptIssue(mptIssuanceID);
|
||||
if (auto const ter = checkFrozen(ctx.view, account, mptIssue);
|
||||
!isTesSuccess(ter))
|
||||
if (auto const ter = checkFrozen(ctx.view, account, mptIssue); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (auto const ter = checkFrozen(ctx.view, destination, mptIssue);
|
||||
!isTesSuccess(ter))
|
||||
if (auto const ter = checkFrozen(ctx.view, destination, mptIssue); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
// Check auth
|
||||
if (auto const ter = requireAuth(ctx.view, mptIssue, account);
|
||||
!isTesSuccess(ter))
|
||||
if (auto const ter = requireAuth(ctx.view, mptIssue, account); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (auto const ter = requireAuth(ctx.view, mptIssue, destination);
|
||||
!isTesSuccess(ter))
|
||||
if (auto const ter = requireAuth(ctx.view, mptIssue, destination); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
return verifySendProofs(
|
||||
ctx, sleSenderMPToken, sleDestinationMPToken, sleIssuance);
|
||||
return verifySendProofs(ctx, sleSenderMPToken, sleDestinationMPToken, sleIssuance);
|
||||
}
|
||||
|
||||
TER
|
||||
@@ -292,23 +264,15 @@ ConfidentialSend::doApply()
|
||||
auto const mptIssuanceID = ctx_.tx[sfMPTokenIssuanceID];
|
||||
auto const destination = ctx_.tx[sfDestination];
|
||||
|
||||
auto sleSenderMPToken =
|
||||
view().peek(keylet::mptoken(mptIssuanceID, account_));
|
||||
auto sleDestinationMPToken =
|
||||
view().peek(keylet::mptoken(mptIssuanceID, destination));
|
||||
auto sleSenderMPToken = view().peek(keylet::mptoken(mptIssuanceID, account_));
|
||||
auto sleDestinationMPToken = view().peek(keylet::mptoken(mptIssuanceID, destination));
|
||||
|
||||
auto sleDestAcct = view().peek(keylet::account(destination));
|
||||
|
||||
if (!sleSenderMPToken || !sleDestinationMPToken || !sleDestAcct)
|
||||
return tecINTERNAL;
|
||||
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
account_,
|
||||
destination,
|
||||
sleDestAcct,
|
||||
ctx_.journal);
|
||||
if (auto err = verifyDepositPreauth(ctx_.tx, ctx_.view(), account_, destination, sleDestAcct, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -320,13 +284,10 @@ ConfidentialSend::doApply()
|
||||
|
||||
// Subtract from sender's spending balance
|
||||
{
|
||||
Slice const curSpending =
|
||||
(*sleSenderMPToken)[sfConfidentialBalanceSpending];
|
||||
Slice const curSpending = (*sleSenderMPToken)[sfConfidentialBalanceSpending];
|
||||
Buffer newSpending(ecGamalEncryptedTotalLength);
|
||||
|
||||
if (TER const ter =
|
||||
homomorphicSubtract(curSpending, senderEc, newSpending);
|
||||
!isTesSuccess(ter))
|
||||
if (TER const ter = homomorphicSubtract(curSpending, senderEc, newSpending); !isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleSenderMPToken)[sfConfidentialBalanceSpending] = newSpending;
|
||||
@@ -334,13 +295,10 @@ ConfidentialSend::doApply()
|
||||
|
||||
// Subtract from issuer's balance
|
||||
{
|
||||
Slice const curIssuerEnc =
|
||||
(*sleSenderMPToken)[sfIssuerEncryptedBalance];
|
||||
Slice const curIssuerEnc = (*sleSenderMPToken)[sfIssuerEncryptedBalance];
|
||||
Buffer newIssuerEnc(ecGamalEncryptedTotalLength);
|
||||
|
||||
if (TER const ter =
|
||||
homomorphicSubtract(curIssuerEnc, issuerEc, newIssuerEnc);
|
||||
!isTesSuccess(ter))
|
||||
if (TER const ter = homomorphicSubtract(curIssuerEnc, issuerEc, newIssuerEnc); !isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleSenderMPToken)[sfIssuerEncryptedBalance] = newIssuerEnc;
|
||||
@@ -349,13 +307,10 @@ ConfidentialSend::doApply()
|
||||
// Subtract from auditor's balance if present
|
||||
if (auditorEc)
|
||||
{
|
||||
Slice const curAuditorEnc =
|
||||
(*sleSenderMPToken)[sfAuditorEncryptedBalance];
|
||||
Slice const curAuditorEnc = (*sleSenderMPToken)[sfAuditorEncryptedBalance];
|
||||
Buffer newAuditorEnc(ecGamalEncryptedTotalLength);
|
||||
|
||||
if (TER const ter =
|
||||
homomorphicSubtract(curAuditorEnc, *auditorEc, newAuditorEnc);
|
||||
!isTesSuccess(ter))
|
||||
if (TER const ter = homomorphicSubtract(curAuditorEnc, *auditorEc, newAuditorEnc); !isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleSenderMPToken)[sfAuditorEncryptedBalance] = newAuditorEnc;
|
||||
@@ -363,12 +318,10 @@ ConfidentialSend::doApply()
|
||||
|
||||
// Add to destination's inbox balance
|
||||
{
|
||||
Slice const curInbox =
|
||||
(*sleDestinationMPToken)[sfConfidentialBalanceInbox];
|
||||
Slice const curInbox = (*sleDestinationMPToken)[sfConfidentialBalanceInbox];
|
||||
Buffer newInbox(ecGamalEncryptedTotalLength);
|
||||
|
||||
if (TER const ter = homomorphicAdd(curInbox, destEc, newInbox);
|
||||
!isTesSuccess(ter))
|
||||
if (TER const ter = homomorphicAdd(curInbox, destEc, newInbox); !isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleDestinationMPToken)[sfConfidentialBalanceInbox] = newInbox;
|
||||
@@ -376,13 +329,10 @@ ConfidentialSend::doApply()
|
||||
|
||||
// Add to issuer's balance
|
||||
{
|
||||
Slice const curIssuerEnc =
|
||||
(*sleDestinationMPToken)[sfIssuerEncryptedBalance];
|
||||
Slice const curIssuerEnc = (*sleDestinationMPToken)[sfIssuerEncryptedBalance];
|
||||
Buffer newIssuerEnc(ecGamalEncryptedTotalLength);
|
||||
|
||||
if (TER const ter =
|
||||
homomorphicAdd(curIssuerEnc, issuerEc, newIssuerEnc);
|
||||
!isTesSuccess(ter))
|
||||
if (TER const ter = homomorphicAdd(curIssuerEnc, issuerEc, newIssuerEnc); !isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleDestinationMPToken)[sfIssuerEncryptedBalance] = newIssuerEnc;
|
||||
@@ -391,13 +341,10 @@ ConfidentialSend::doApply()
|
||||
// Add to auditor's balance if present
|
||||
if (auditorEc)
|
||||
{
|
||||
Slice const curAuditorEnc =
|
||||
(*sleDestinationMPToken)[sfAuditorEncryptedBalance];
|
||||
Slice const curAuditorEnc = (*sleDestinationMPToken)[sfAuditorEncryptedBalance];
|
||||
Buffer newAuditorEnc(ecGamalEncryptedTotalLength);
|
||||
|
||||
if (TER const ter =
|
||||
homomorphicAdd(curAuditorEnc, *auditorEc, newAuditorEnc);
|
||||
!isTesSuccess(ter))
|
||||
if (TER const ter = homomorphicAdd(curAuditorEnc, *auditorEc, newAuditorEnc); !isTesSuccess(ter))
|
||||
return tecINTERNAL;
|
||||
|
||||
(*sleDestinationMPToken)[sfAuditorEncryptedBalance] = newAuditorEnc;
|
||||
|
||||
@@ -72,14 +72,11 @@ 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
|
||||
|
||||
@@ -16,14 +16,12 @@ MPTokenIssuanceCreate::checkExtraFeatures(PreflightContext const& ctx)
|
||||
if (ctx.tx.isFieldPresent(sfMutableFlags) && !ctx.rules.enabled(featureDynamicMPT))
|
||||
return false;
|
||||
|
||||
if (ctx.tx.isFlag(tfMPTCanPrivacy) &&
|
||||
!ctx.rules.enabled(featureConfidentialTransfer))
|
||||
if (ctx.tx.isFlag(tfMPTCanPrivacy) && !ctx.rules.enabled(featureConfidentialTransfer))
|
||||
return false;
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -33,35 +33,13 @@ struct MPTMutabilityFlags
|
||||
};
|
||||
|
||||
static constexpr std::array<MPTMutabilityFlags, 7> mptMutabilityFlags = {
|
||||
{{tmfMPTSetCanLock,
|
||||
tmfMPTClearCanLock,
|
||||
lsmfMPTCanMutateCanLock,
|
||||
lsfMPTCanLock},
|
||||
{tmfMPTSetRequireAuth,
|
||||
tmfMPTClearRequireAuth,
|
||||
lsmfMPTCanMutateRequireAuth,
|
||||
lsfMPTRequireAuth},
|
||||
{tmfMPTSetCanEscrow,
|
||||
tmfMPTClearCanEscrow,
|
||||
lsmfMPTCanMutateCanEscrow,
|
||||
lsfMPTCanEscrow},
|
||||
{tmfMPTSetCanTrade,
|
||||
tmfMPTClearCanTrade,
|
||||
lsmfMPTCanMutateCanTrade,
|
||||
lsfMPTCanTrade},
|
||||
{tmfMPTSetCanTransfer,
|
||||
tmfMPTClearCanTransfer,
|
||||
lsmfMPTCanMutateCanTransfer,
|
||||
lsfMPTCanTransfer},
|
||||
{tmfMPTSetCanClawback,
|
||||
tmfMPTClearCanClawback,
|
||||
lsmfMPTCanMutateCanClawback,
|
||||
lsfMPTCanClawback},
|
||||
{tmfMPTSetPrivacy,
|
||||
tmfMPTClearPrivacy,
|
||||
lsmfMPTCannotMutatePrivacy,
|
||||
lsfMPTCanPrivacy,
|
||||
true}}};
|
||||
{{tmfMPTSetCanLock, tmfMPTClearCanLock, lsmfMPTCanMutateCanLock, lsfMPTCanLock},
|
||||
{tmfMPTSetRequireAuth, tmfMPTClearRequireAuth, lsmfMPTCanMutateRequireAuth, lsfMPTRequireAuth},
|
||||
{tmfMPTSetCanEscrow, tmfMPTClearCanEscrow, lsmfMPTCanMutateCanEscrow, lsfMPTCanEscrow},
|
||||
{tmfMPTSetCanTrade, tmfMPTClearCanTrade, lsmfMPTCanMutateCanTrade, lsfMPTCanTrade},
|
||||
{tmfMPTSetCanTransfer, tmfMPTClearCanTransfer, lsmfMPTCanMutateCanTransfer, lsfMPTCanTransfer},
|
||||
{tmfMPTSetCanClawback, tmfMPTClearCanClawback, lsmfMPTCanMutateCanClawback, lsfMPTCanClawback},
|
||||
{tmfMPTSetPrivacy, tmfMPTClearPrivacy, lsmfMPTCannotMutatePrivacy, lsfMPTCanPrivacy, true}}};
|
||||
|
||||
NotTEC
|
||||
MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
|
||||
@@ -70,14 +48,11 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
|
||||
auto const metadata = ctx.tx[~sfMPTokenMetadata];
|
||||
auto const transferFee = ctx.tx[~sfTransferFee];
|
||||
auto const isMutate = mutableFlags || metadata || transferFee;
|
||||
auto const hasIssuerElGamalKey =
|
||||
ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey);
|
||||
auto const hasAuditorElGamalKey =
|
||||
ctx.tx.isFieldPresent(sfAuditorElGamalPublicKey);
|
||||
auto const hasIssuerElGamalKey = ctx.tx.isFieldPresent(sfIssuerElGamalPublicKey);
|
||||
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);
|
||||
@@ -104,13 +79,11 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
|
||||
if (holderID && accountID == holderID)
|
||||
return temMALFORMED;
|
||||
|
||||
if (ctx.rules.enabled(featureSingleAssetVault) ||
|
||||
ctx.rules.enabled(featureDynamicMPT) ||
|
||||
if (ctx.rules.enabled(featureSingleAssetVault) || ctx.rules.enabled(featureDynamicMPT) ||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -154,12 +127,10 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
|
||||
if (hasAuditorElGamalKey && !hasIssuerElGamalKey)
|
||||
return temMALFORMED;
|
||||
|
||||
if (hasIssuerElGamalKey &&
|
||||
ctx.tx[sfIssuerElGamalPublicKey].length() != ecPubKeyLength)
|
||||
if (hasIssuerElGamalKey && ctx.tx[sfIssuerElGamalPublicKey].length() != ecPubKeyLength)
|
||||
return temMALFORMED;
|
||||
|
||||
if (hasAuditorElGamalKey &&
|
||||
ctx.tx[sfAuditorElGamalPublicKey].length() != ecPubKeyLength)
|
||||
if (hasAuditorElGamalKey && ctx.tx[sfAuditorElGamalPublicKey].length() != ecPubKeyLength)
|
||||
return temMALFORMED;
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -255,22 +226,16 @@ 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);
|
||||
return canMutate &&
|
||||
(*mutableFlags & (f.setFlag | f.clearFlag));
|
||||
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))
|
||||
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
|
||||
@@ -296,34 +261,29 @@ 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
|
||||
@@ -417,9 +377,7 @@ 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);
|
||||
}
|
||||
@@ -427,9 +385,7 @@ 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user