mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add ciphertext check (#5930)
This commit is contained in:
@@ -130,6 +130,14 @@ serializeEcPair(
|
|||||||
secp256k1_pubkey const& in2,
|
secp256k1_pubkey const& in2,
|
||||||
Buffer& buffer);
|
Buffer& buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Verifies that a buffer contains two valid, parsable EC public keys.
|
||||||
|
* @param buffer The input buffer containing two concatenated components.
|
||||||
|
* @return true if both components can be parsed successfully, false otherwise.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
isValidCiphertext(Slice const& buffer);
|
||||||
|
|
||||||
TER
|
TER
|
||||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out);
|
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out);
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ enum TEMcodes : TERUnderlyingType {
|
|||||||
temARRAY_TOO_LARGE,
|
temARRAY_TOO_LARGE,
|
||||||
temBAD_TRANSFER_FEE,
|
temBAD_TRANSFER_FEE,
|
||||||
temINVALID_INNER_BATCH,
|
temINVALID_INNER_BATCH,
|
||||||
|
temBAD_CIPHERTEXT,
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -371,6 +371,18 @@ serializeEcPair(
|
|||||||
return res1 && res2;
|
return res1 && res2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isValidCiphertext(Slice const& buffer)
|
||||||
|
{
|
||||||
|
// Local/temporary variables to pass to makeEcPair.
|
||||||
|
// Their contents will be discarded when the function returns.
|
||||||
|
secp256k1_pubkey key1;
|
||||||
|
secp256k1_pubkey key2;
|
||||||
|
|
||||||
|
// Call makeEcPair and return its result.
|
||||||
|
return makeEcPair(buffer, key1, key2);
|
||||||
|
}
|
||||||
|
|
||||||
TER
|
TER
|
||||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
||||||
{
|
{
|
||||||
@@ -516,12 +528,6 @@ encryptCanonicalZeroAmount(
|
|||||||
|
|
||||||
// Allocate ciphertext placeholders
|
// Allocate ciphertext placeholders
|
||||||
secp256k1_pubkey c1, c2;
|
secp256k1_pubkey c1, c2;
|
||||||
|
|
||||||
// Prepare a random blinding factor
|
|
||||||
unsigned char blinding_factor[32];
|
|
||||||
if (RAND_bytes(blinding_factor, 32) != 1)
|
|
||||||
Throw<std::runtime_error>("Failed to generate random number");
|
|
||||||
|
|
||||||
secp256k1_pubkey pubKey;
|
secp256k1_pubkey pubKey;
|
||||||
|
|
||||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ transResults()
|
|||||||
MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."),
|
MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."),
|
||||||
MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."),
|
MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."),
|
||||||
MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."),
|
MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."),
|
||||||
|
MAKE_ERROR(temBAD_CIPHERTEXT, "Malformed: Invalid ciphertext."),
|
||||||
|
|
||||||
MAKE_ERROR(terRETRY, "Retry transaction."),
|
MAKE_ERROR(terRETRY, "Retry transaction."),
|
||||||
MAKE_ERROR(terFUNDS_SPENT, "DEPRECATED."),
|
MAKE_ERROR(terFUNDS_SPENT, "DEPRECATED."),
|
||||||
|
|||||||
@@ -153,6 +153,33 @@ class ConfidentialTransfer_test : public beast::unit_test::suite
|
|||||||
.holderPubKey = mptAlice.getPubKey(bob),
|
.holderPubKey = mptAlice.getPubKey(bob),
|
||||||
.err = temMALFORMED});
|
.err = temMALFORMED});
|
||||||
|
|
||||||
|
// A 66-byte array of random unsigned char values
|
||||||
|
unsigned char badCiphertext[ecGamalEncryptedTotalLength] = {
|
||||||
|
0x3E, 0x9A, 0x0F, 0x7C, 0x51, 0xD8, 0x22, 0x8B, 0x6E, 0x14, 0xC9,
|
||||||
|
0xF5, 0x4D, 0x6A, 0x03, 0x81, 0x77, 0x2B, 0xEE, 0x9F, 0x10, 0xC2,
|
||||||
|
0x57, 0x3D, 0x88, 0x65, 0x0C, 0xAB, 0xF1, 0x4E, 0x19, 0x96, 0x2A,
|
||||||
|
0x73, 0xDC, 0x44, 0xB8, 0x5F, 0x01, 0xEA, 0x87, 0x36, 0x60, 0xCE,
|
||||||
|
0x92, 0x25, 0x7D, 0x5B, 0xC0, 0x1E, 0x48, 0xF9, 0x84, 0x33, 0x67,
|
||||||
|
0xAD, 0x0B, 0xE3, 0x91, 0x50, 0xDA, 0x2F, 0x75, 0xC6, 0xBD, 0x42};
|
||||||
|
|
||||||
|
mptAlice.convert(
|
||||||
|
{.account = bob,
|
||||||
|
.amt = 1,
|
||||||
|
.proof = "123",
|
||||||
|
.holderPubKey = mptAlice.getPubKey(bob),
|
||||||
|
.holderEncryptedAmt =
|
||||||
|
Buffer{badCiphertext, ecGamalEncryptedTotalLength},
|
||||||
|
.err = temBAD_CIPHERTEXT});
|
||||||
|
|
||||||
|
mptAlice.convert(
|
||||||
|
{.account = bob,
|
||||||
|
.amt = 1,
|
||||||
|
.proof = "123",
|
||||||
|
.holderPubKey = mptAlice.getPubKey(bob),
|
||||||
|
.issuerEncryptedAmt =
|
||||||
|
Buffer{badCiphertext, ecGamalEncryptedTotalLength},
|
||||||
|
.err = temBAD_CIPHERTEXT});
|
||||||
|
|
||||||
// todo: change to to check proof size
|
// todo: change to to check proof size
|
||||||
// mptAlice.convert(
|
// mptAlice.convert(
|
||||||
// {.account = bob,
|
// {.account = bob,
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ ConfidentialConvert::preflight(PreflightContext const& ctx)
|
|||||||
if (ctx.tx[sfMPTAmount] > maxMPTokenAmount)
|
if (ctx.tx[sfMPTAmount] > maxMPTokenAmount)
|
||||||
return temMALFORMED;
|
return temMALFORMED;
|
||||||
|
|
||||||
|
if (!isValidCiphertext(ctx.tx[sfHolderEncryptedAmount]) ||
|
||||||
|
!isValidCiphertext(ctx.tx[sfIssuerEncryptedAmount]))
|
||||||
|
return temBAD_CIPHERTEXT;
|
||||||
|
|
||||||
// if (ctx.tx[sfZKProof].length() != ecEqualityProofLength)
|
// if (ctx.tx[sfZKProof].length() != ecEqualityProofLength)
|
||||||
// return temMALFORMED;
|
// return temMALFORMED;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user