heir icon indicating copy to clipboard operation
heir copied to clipboard

lwe-to-polynomial: migrate encrypt/decrypt lowering to support RNS

Open ZenithalHourlyRate opened this issue 1 year ago • 9 comments

PR #1190 migrated most of the types to NewLWEType, however, for lwe-to-polynomial, there are some non-trivial changes that needs to be done.

This also relates to #882

NewLWEPlaintext now has a PlaintextSpace.Ring (for example Z_65537 / (X^N + 1)), which is different from NewCiphertext's CiphertextSpace.Ring (typically RNS)

  • lowering should convert plaintext ring to rns ring
  • lowering should properly handle modulus switching from Z_65537 to Z_qi (ciphertext rns modulus), which needs mod_arith dialect support, and it is non-trivial.
  • lowering should handle scaling factor for CKKS scheme.

ZenithalHourlyRate avatar Dec 16 '24 13:12 ZenithalHourlyRate

IIUC @asraa is working on this, and note it's a blocker for https://github.com/google/heir/pull/2013/files

j2kun avatar Jul 18 '25 22:07 j2kun

The remaining part of this (that https://github.com/google/heir/pull/2036 pushes) is that RNS types are not supported in polynomial-to-mod-arith now. Since poly coeff types can be RNS, poly operations are still operating on the RNS polynomial types. A further pass, e.g. polynomial-to-mod-arith should decompose the RNS polynomials into the individual limbs.

asraa avatar Jul 22 '25 14:07 asraa

A further pass, e.g. polynomial-to-mod-arith should decompose the RNS polynomials into the individual limbs.

It seems reasonable to define mod_arith ops to work on rns types as if they were vector types... Then maybe we could get away with inserting an "rns-unroll" type pass before mod-arith-to-arith. Thoughts?

j2kun avatar Jul 22 '25 14:07 j2kun

A further pass, e.g. polynomial-to-mod-arith should decompose the RNS polynomials into the individual limbs.

It seems reasonable to define mod_arith ops to work on rns types as if they were vector types... Then maybe we could get away with inserting an "rns-unroll" type pass before mod-arith-to-arith. Thoughts?

Yep, something like LimbwiseMappable would be great :)

AlexanderViand avatar Jul 22 '25 15:07 AlexanderViand

Oooh I like this!

I'm just curious - does hardware natively support a vector of different modular operations? Or do they break them down into individual single mod Z_p operations?

asraa avatar Jul 22 '25 15:07 asraa

I'm just curious - does hardware natively support a vector of different modular operations? Or do they break them down into individual single mod Z_p operations?

This might differ from vendor to vendor, but I think for HERACLES, we eventually want to re-order things to be grouped by RNS limb, but I think LimbwiseMappable would actually make that easy - instead of lowering each op to a loop over the limbs, we could just take a chunk of LimbwiseMappable operations and lower them to a combined loop over the limbs.

AlexanderViand avatar Jul 22 '25 15:07 AlexanderViand

It seems reasonable to define mod_arith ops to work on rns types as if they were vector types... Then maybe we could get away with inserting an "rns-unroll" type pass before mod-arith-to-arith. Thoughts?

mod_arith ops (add/sub/mul) already support rns types (#1744), though it does not have a lowering for it; for mod_arith mod_switch op, it supports rns lowering, though not in a rns-unroll style (#1928)

ZenithalHourlyRate avatar Jul 23 '25 02:07 ZenithalHourlyRate

Ah right, yes. mod_arith ops take RNS types too. I think then maybe an RNS-unroll transform pass at the mod_arith level is what this should be

asraa avatar Jul 23 '25 14:07 asraa