Skip to content

Commit

Permalink
fix(compiler): Allow uncompressed ciphertext in compressed gate to fi…
Browse files Browse the repository at this point in the history
…x composition + compression
  • Loading branch information
BourgerieQuentin committed Jun 4, 2024
1 parent 226ee27 commit db2c755
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 3 deletions.
54 changes: 51 additions & 3 deletions compilers/concrete-compiler/compiler/lib/Common/Transformers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,51 @@ Result<TransportValueVerifier> getObliviousTransportValueVerifier() {
};
}

Result<TransportValueVerifier>
getTransportValueVerifier(const Message<concreteprotocol::GateInfo> &gateInfo) {
Message<concreteprotocol::GateInfo>
updateGateInfoAccordingValue(Message<concreteprotocol::GateInfo> &gate,
const TransportValue &value) {

auto gateReader = gate.asReader();
auto gateTypeInfo = gateReader.getTypeInfo();
if (!gateTypeInfo.hasLweCiphertext()) {
return gate;
}
auto gateCiphertext = gateTypeInfo.getLweCiphertext();
auto gateCompression = gateCiphertext.getCompression();
if (gateCompression == concreteprotocol::Compression::SEED) {
auto valueReader = value.asReader();
auto valueTypeInfo = valueReader.getTypeInfo();
if (!valueTypeInfo.hasLweCiphertext()) {
return gate;
}
auto valueCiphertext = valueTypeInfo.getLweCiphertext();
auto valueCompression = valueCiphertext.getCompression();
if (valueCompression == concreteprotocol::Compression::NONE) {
// If the compression of transportValue is none and the gateInfo have
// compression we update the gateInfo to allow uncompressed transportValue
auto gateBuilder = gate.asBuilder();
gateBuilder.getTypeInfo().getLweCiphertext().setCompression(
concreteprotocol::Compression::NONE);
auto gateDimensions = gateBuilder.getRawInfo().getShape().getDimensions();
auto lweSize = gateCiphertext.getEncryption().getLweDimension() + 1;
gateDimensions.set(gateDimensions.size() - 1, lweSize);
auto concreteShapeDimensions = gateBuilder.getTypeInfo()
.getLweCiphertext()
.getConcreteShape()
.getDimensions();
concreteShapeDimensions.set(concreteShapeDimensions.size() - 1, lweSize);
return gateBuilder.asReader();
}
}
return gate;
}

Result<TransportValueVerifier> getTransportValueVerifier(
Message<concreteprotocol::GateInfo> &originalGateInfo) {
return [=](const TransportValue &transportVal) -> Result<void> {
auto copyGateInfo = originalGateInfo;
auto gateInfo = updateGateInfoAccordingValue(copyGateInfo, transportVal);

if (!transportVal.asReader().hasPayload()) {
return StringError(
"Tried to transform a transport value without payload.");
Expand Down Expand Up @@ -893,7 +935,13 @@ Result<ArgTransformer> TransformerFactory::getLweCiphertextArgTransformer(

return [=](TransportValue transportVal) -> Result<Value> {
OUTCOME_TRYV(verify(transportVal));
return decompressionTransformer(Value::fromRawTransportValue(transportVal));
auto value = Value::fromRawTransportValue(transportVal);
if (transportVal.asReader()
.getTypeInfo()
.getLweCiphertext()
.getCompression() == concreteprotocol::Compression::NONE)
return value;
return decompressionTransformer(value);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
Tests composition + compression
"""

import numpy as np

from concrete import fhe


def test_composable_with_input_compression(helpers):
"""
Test that the composable circuit and compression works together
"""

conf = helpers.configuration()
if conf.parameter_selection_strategy != fhe.ParameterSelectionStrategy.MULTI:
# Composability is for now only valid with multi
return

@fhe.compiler({"x": "encrypted"})
def f(x):
return (x**2) % 2**3

conf.composable = True
conf.compress_input_ciphertexts = True
circuit = f.compile(fhe.inputset(fhe.uint3), conf)
result = circuit.run(circuit.run(circuit.encrypt(2)))
assert circuit.decrypt(result) == f(f(2))

0 comments on commit db2c755

Please sign in to comment.