How to create a Plaintext from a raw DCRTPoly for decoding?

I am implementing a custom multi-key CKKS protocol using OpenFHE’s low-level components (like DCRTPoly and the ring operators).

My custom aggregation function successfully produces a final DCRTPoly which represents the decrypted sum of the initial messages. I would now like to decode this raw polynomial back into a std::vector<double> using the convenient, built-in GetRealPackedValue() function.

The challenge is that GetRealPackedValue() is a method of the Plaintext object, and I cannot find a public API function to wrap my raw DCRTPoly result into a Plaintext object.

My Goal (in pseudo-code):

`C++// My custom protocol correctly produces this raw polynomial result.
// It is in COEFFICIENT format.
DCRTPoly finalPoly = MyCustomAggregate(…);

// I need a way to do this:
Plaintext resultPtxt = some_function_to_wrap(finalPoly);
// …or some other factory/constructor method.

// So that I can ultimately call this:
std::vector finalValues = resultPtxt->GetRealPackedValue();`

My understanding from previous research is that this might be an intentional API design, as summarized below:

The library’s design is a “one-way street”: you can easily get a low-level DCRTPoly from a high-level Plaintext, but the reverse is intentionally not allowed. This is a crucial safety feature that prevents metadata corruption… to guarantee correctness, the library enforces that Plaintext objects can only be created by its trusted encoders.

Is this understanding correct? Is there a recommended way for a low-level implementation to wrap a final DCRTPoly into a Plaintext for decoding, or is manual decoding (using CRTInterpolate and scaling) the only intended path in this scenario?

Thank you for your guidance!

@dsuponitskiy-duality Any idea?

What you are asking about is already implemented for threshold FHE. The decryption in threshold FHE (for additive secret key shares) is done the same way as in multi-key FHE. A DCRTPoly is computed (embedded in a Ciphertext object) and then decrypted. I suggest searching the code for MultipartyDecryptFusion (especially cryptocontext.cpp).

CRTInterpolate is called when multiple limbs are used when performing decryption (i.e., the message and flooding noise do not fit in one RNS limb). You can examine the logic in MultipartyDecryptFusion for more details.

1 Like