Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/Dialect/LWE/IR/LWEOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ def LWE_RLWEEncodeOp : LWE_Op<"rlwe_encode", [
let arguments = (ins
SignlessIntegerOrFloatLike:$input,
AnyPlaintextEncodingAttr:$encoding,
Polynomial_RingAttr:$ring
Polynomial_RingAttr:$ring,
OptionalAttr<I64Attr>:$level,
OptionalAttr<I64Attr>:$scale
);

let results = (outs LWEPlaintextLike:$output);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ func::FuncOp getOrCreateEncryptionOfZerosFunc(func::FuncOp parentFunc,
auto plaintextSpace = plaintextType.getPlaintextSpace();
auto encodeOp = RLWEEncodeOp::create(
builder, plaintextType, constantOp.getResult(),
plaintextSpace.getEncoding(), plaintextSpace.getRing());
plaintextSpace.getEncoding(), plaintextSpace.getRing(),
/*level=*/nullptr, /*scale=*/nullptr);
auto encrypted = RLWEEncryptOp::create(
builder, ciphertextType, encodeOp.getResult(), encFuncOp.getArgument(0));
encrypted->setAttrs(originalOp->getAttrs());
Expand Down
27 changes: 22 additions & 5 deletions lib/Dialect/Secret/Conversions/Patterns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,18 @@ LogicalResult ConvertClientConceal::lowerToTrivialEncryption(

// Intentionally use op.getCleartext() because we don't want to type-convert
// the input to a ciphertext.
IntegerAttr levelAttr;
IntegerAttr scaleAttr;
if (auto mc = ctTy.getModulusChain()) {
levelAttr = rewriter.getI64IntegerAttr(mc.getCurrent());
scaleAttr =
rewriter.getI64IntegerAttr(lwe::getScalingFactorFromEncodingAttr(
ctTy.getPlaintextSpace().getEncoding()));
}
auto encoded = lwe::RLWEEncodeOp::create(
rewriter, op.getLoc(), encodeOpResultTy, op.getCleartext(),
ctTy.getPlaintextSpace().getEncoding(),
ctTy.getPlaintextSpace().getRing());
ctTy.getPlaintextSpace().getRing(), levelAttr, scaleAttr);
auto newOp =
lwe::TrivialEncryptOp::create(rewriter, op.getLoc(), resultTy, encoded);
newOp->setAttrs(op->getAttrs());
Expand Down Expand Up @@ -145,11 +153,20 @@ LogicalResult ConvertClientConceal::matchAndRewrite(
auto plaintextTy = lwe::LWEPlaintextType::get(op.getContext(),
resultCtTy.getPlaintextSpace());

IntegerAttr encLevelAttr;
IntegerAttr encScaleAttr;
if (auto mc = resultCtTy.getModulusChain()) {
encLevelAttr = rewriter.getI64IntegerAttr(mc.getCurrent());
encScaleAttr =
rewriter.getI64IntegerAttr(lwe::getScalingFactorFromEncodingAttr(
resultCtTy.getPlaintextSpace().getEncoding()));
}

auto encryptFn = [&](Value cleartext) -> lwe::RLWEEncryptOp {
auto encoded =
lwe::RLWEEncodeOp::create(rewriter, op.getLoc(), plaintextTy, cleartext,
resultCtTy.getPlaintextSpace().getEncoding(),
resultCtTy.getPlaintextSpace().getRing());
auto encoded = lwe::RLWEEncodeOp::create(
rewriter, op.getLoc(), plaintextTy, cleartext,
resultCtTy.getPlaintextSpace().getEncoding(),
resultCtTy.getPlaintextSpace().getRing(), encLevelAttr, encScaleAttr);
auto encryptOp = lwe::RLWEEncryptOp::create(
rewriter, op.getLoc(), resultCtTy, encoded.getResult(), keyBlockArg);
// Copy attributes from the original op to preserve any mgmt attrs needed by
Expand Down
28 changes: 18 additions & 10 deletions lib/Utils/ContextAwareConversionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,31 @@ FailureOr<Value> encodeCleartextAsPlaintext(
return failure();
}

// TODO(#1643): inherit level information to plaintext type from init-op
// mgmt attr. This actually needs to make LWEPlaintextType RNS aware.
// TODO(#1643): LWEPlaintextType should carry RNS ring info. For now,
// the level and scale are passed as attributes on the encode op.
auto plaintextTy = lwe::LWEPlaintextType::get(
ctx, lwe::PlaintextSpaceAttr::get(ctx, plaintextSpace.getRing(),
plaintextEncoding));

IntegerAttr levelAttr;
IntegerAttr scaleAttr;
if (auto mc = ciphertextElementType.getModulusChain()) {
levelAttr = builder.getI64IntegerAttr(mc.getCurrent());
scaleAttr = builder.getI64IntegerAttr(
lwe::getScalingFactorFromEncodingAttr(plaintextEncoding));
}

// cleartext is a ciphertext-semantic tensor, so it
// could be a tensor<Nxty>, tensor<k x N x ty>, (where k=1 is possible).
// For rank 1, it's a single ciphertext and can be encoded directly.
auto cleartextTensorTy = cast<RankedTensorType>(cleartext.getType());
int64_t numSlots =
cleartextTensorTy.getDimSize(cleartextTensorTy.getRank() - 1);
if (cleartextTensorTy.getRank() == 1) {
Value encodeOp =
lwe::RLWEEncodeOp::create(builder, plaintextTy, cleartext,
plaintextEncoding, plaintextSpace.getRing())
.getResult();
Value encodeOp = lwe::RLWEEncodeOp::create(
builder, plaintextTy, cleartext, plaintextEncoding,
plaintextSpace.getRing(), levelAttr, scaleAttr)
.getResult();
return encodeOp;
}

Expand All @@ -87,10 +95,10 @@ FailureOr<Value> encodeCleartextAsPlaintext(
SmallVector<OpFoldResult> strides(2, builder.getIndexAttr(1));
auto slice = tensor::ExtractSliceOp::create(builder, sliceTy, cleartext,
offsets, sizes, strides);
Value encodedSlice =
lwe::RLWEEncodeOp::create(builder, plaintextTy, slice,
plaintextEncoding, plaintextSpace.getRing())
.getResult();
Value encodedSlice = lwe::RLWEEncodeOp::create(
builder, plaintextTy, slice, plaintextEncoding,
plaintextSpace.getRing(), levelAttr, scaleAttr)
.getResult();
encodedSlices.push_back(encodedSlice);
}

Expand Down
Loading