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,
|
||||
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
|
||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out);
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ enum TEMcodes : TERUnderlyingType {
|
||||
temARRAY_TOO_LARGE,
|
||||
temBAD_TRANSFER_FEE,
|
||||
temINVALID_INNER_BATCH,
|
||||
temBAD_CIPHERTEXT,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -371,6 +371,18 @@ serializeEcPair(
|
||||
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
|
||||
homomorphicAdd(Slice const& a, Slice const& b, Buffer& out)
|
||||
{
|
||||
@@ -516,12 +528,6 @@ encryptCanonicalZeroAmount(
|
||||
|
||||
// Allocate ciphertext placeholders
|
||||
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;
|
||||
|
||||
std::memcpy(pubKey.data, pubKeySlice.data(), ecPubKeyLength);
|
||||
|
||||
@@ -221,6 +221,7 @@ transResults()
|
||||
MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."),
|
||||
MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."),
|
||||
MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."),
|
||||
MAKE_ERROR(temBAD_CIPHERTEXT, "Malformed: Invalid ciphertext."),
|
||||
|
||||
MAKE_ERROR(terRETRY, "Retry transaction."),
|
||||
MAKE_ERROR(terFUNDS_SPENT, "DEPRECATED."),
|
||||
|
||||
@@ -153,6 +153,33 @@ class ConfidentialTransfer_test : public beast::unit_test::suite
|
||||
.holderPubKey = mptAlice.getPubKey(bob),
|
||||
.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
|
||||
// mptAlice.convert(
|
||||
// {.account = bob,
|
||||
|
||||
@@ -47,6 +47,10 @@ ConfidentialConvert::preflight(PreflightContext const& ctx)
|
||||
if (ctx.tx[sfMPTAmount] > maxMPTokenAmount)
|
||||
return temMALFORMED;
|
||||
|
||||
if (!isValidCiphertext(ctx.tx[sfHolderEncryptedAmount]) ||
|
||||
!isValidCiphertext(ctx.tx[sfIssuerEncryptedAmount]))
|
||||
return temBAD_CIPHERTEXT;
|
||||
|
||||
// if (ctx.tx[sfZKProof].length() != ecEqualityProofLength)
|
||||
// return temMALFORMED;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user