Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add casting #50

Merged
merged 2 commits into from
Jun 22, 2023
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
44 changes: 43 additions & 1 deletion codegen/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
uint256 public constant Multiply = 72;
uint256 public constant LessThan = 73;
uint256 public constant OptimisticRequire = 75;
uint256 public constant Cast = 76;
uint256 public constant TrivialEncrypt = 77;
}
"""
Expand Down Expand Up @@ -299,7 +300,7 @@
bytes32[1] memory output;
uint256 outputLen = 32;

// Call the cast precompile.
// Call the verify precompile.
uint256 precompile = Precompiles.Verify;
assembly {
// jump over the 32-bit `size` field of the `bytes` data structure of the `input` to read actual bytes
Expand All @@ -310,6 +311,36 @@
result = uint256(output[0]);
}

function cast(
uint256 ciphertext,
uint8 toType
) internal view returns (uint256 result) {
bytes memory input = bytes.concat(bytes32(ciphertext), bytes1(toType));
uint256 inputLen = input.length;

bytes32[1] memory output;
uint256 outputLen = 32;

// Call the cast precompile.
uint256 precompile = Precompiles.Cast;
assembly {
// jump over the 32-bit `size` field of the `bytes` data structure of the `input` to read actual bytes
if iszero(
staticcall(
gas(),
precompile,
add(input, 32),
inputLen,
output,
outputLen
)
) {
revert(0, 0)
}
}
result = uint256(output[0]);
}

function trivialEncrypt(
uint256 value,
uint8 toType
Expand Down Expand Up @@ -402,6 +433,17 @@
if i == j: # TODO: remove this line when casting is implemented
f.write(to_print.format(i=i, j=j, k=i if i>j else j))

to_print="""
function asEuint{i}(euint{j} ciphertext) internal view returns (euint{i}) {{
return euint{i}.wrap(Impl.cast(euint{j}.unwrap(ciphertext), Common.euint{i}_t));
}}
"""

for i in (2**p for p in range(3, 6)):
for j in (2**p for p in range(3, 6)):
if i != j:
f.write(to_print.format(i=i, j=j))

to_print="""
function asEuint{i}(bytes memory ciphertext) internal view returns (euint{i}) {{
return euint{i}.wrap(Impl.verify(ciphertext, Common.euint{i}_t));
Expand Down
32 changes: 31 additions & 1 deletion lib/Impl.sol
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ library Impl {
bytes32[1] memory output;
uint256 outputLen = 32;

// Call the cast precompile.
// Call the verify precompile.
uint256 precompile = Precompiles.Verify;
assembly {
// jump over the 32-bit `size` field of the `bytes` data structure of the `input` to read actual bytes
Expand All @@ -357,6 +357,36 @@ library Impl {
result = uint256(output[0]);
}

function cast(
uint256 ciphertext,
uint8 toType
) internal view returns (uint256 result) {
bytes memory input = bytes.concat(bytes32(ciphertext), bytes1(toType));
uint256 inputLen = input.length;

bytes32[1] memory output;
uint256 outputLen = 32;

// Call the cast precompile.
uint256 precompile = Precompiles.Cast;
assembly {
// jump over the 32-bit `size` field of the `bytes` data structure of the `input` to read actual bytes
if iszero(
staticcall(
gas(),
precompile,
add(input, 32),
inputLen,
output,
outputLen
)
) {
revert(0, 0)
}
}
result = uint256(output[0]);
}

function trivialEncrypt(
uint256 value,
uint8 toType
Expand Down
1 change: 1 addition & 0 deletions lib/Precompiles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ library Precompiles {
uint256 public constant Multiply = 72;
uint256 public constant LessThan = 73;
uint256 public constant OptimisticRequire = 75;
uint256 public constant Cast = 76;
uint256 public constant TrivialEncrypt = 77;
}
38 changes: 38 additions & 0 deletions lib/TFHE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,44 @@ library TFHE {
);
}

function asEuint8(euint16 ciphertext) internal view returns (euint8) {
return
euint8.wrap(Impl.cast(euint16.unwrap(ciphertext), Common.euint8_t));
}

function asEuint8(euint32 ciphertext) internal view returns (euint8) {
return
euint8.wrap(Impl.cast(euint32.unwrap(ciphertext), Common.euint8_t));
}

function asEuint16(euint8 ciphertext) internal view returns (euint16) {
return
euint16.wrap(
Impl.cast(euint8.unwrap(ciphertext), Common.euint16_t)
);
}

function asEuint16(euint32 ciphertext) internal view returns (euint16) {
return
euint16.wrap(
Impl.cast(euint32.unwrap(ciphertext), Common.euint16_t)
);
}

function asEuint32(euint8 ciphertext) internal view returns (euint32) {
return
euint32.wrap(
Impl.cast(euint8.unwrap(ciphertext), Common.euint32_t)
);
}

function asEuint32(euint16 ciphertext) internal view returns (euint32) {
return
euint32.wrap(
Impl.cast(euint16.unwrap(ciphertext), Common.euint32_t)
);
}

function asEuint8(bytes memory ciphertext) internal view returns (euint8) {
return euint8.wrap(Impl.verify(ciphertext, Common.euint8_t));
}
Expand Down