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

Remove TFHE.req #121

Merged
merged 2 commits into from
Sep 6, 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
1 change: 0 additions & 1 deletion codegen/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export const ALL_PRECOMPILES: Precompile[] = [
{ name: 'Verify', code: 66 },
{ name: 'Reencrypt', code: 67 },
{ name: 'FhePubKey', code: 68 },
{ name: 'Require', code: 69 },
{ name: 'LessThanOrEqual', code: 70 },
{ name: 'Subtract', code: 71 },
{ name: 'Multiply', code: 72 },
Expand Down
29 changes: 5 additions & 24 deletions codegen/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,6 @@ function unaryOperatorImpl(op: Operator): string {

function tfheCustomMethods(): string {
return `
// Require that the encrypted bool 'b' is true.
// Involves decrypting 'b'.
function req(ebool b) internal view {
Impl.req(ebool.unwrap(b));
}

// Optimistically require that 'b' is true.
//
// This function does not evaluate 'b' at the time of the call.
Expand All @@ -461,10 +455,11 @@ function tfheCustomMethods(): string {
// gas cost, as if all optimistic requires were true. Yet, the transaction will be
// reverted at the end if any of the optimisic requires were false.
//
// Exceptions to above rule are encrypted requires via TFHE.req() and decryption via
// TFHE.decrypt(). If either of them are encountered and if optimistic requires have been
// used before in the txn, the optimisic requires will be immediately evaluated. Rationale is
// that we want to avoid decrypting a non-optimistic require or a value if the txn is about
// Exceptions to above rule are reencryptions and decryptions via
// TFHE.reencrypt() and TFHE.decrypt(), respectively. If either of them
// are encountered and if optimistic requires have been used before in the
// txn, the optimisic requires will be immediately evaluated. Rationale is
// that we want to avoid decrypting or reencrypting a value if the txn is about
// to fail and be reverted anyway at the end. Checking immediately and reverting on the spot
// would avoid unnecessary decryptions.
//
Expand Down Expand Up @@ -692,20 +687,6 @@ function implCustomMethods(): string {
result = uint256(output[0]);
}

function req(uint256 ciphertext) internal view {
bytes32[1] memory input;
input[0] = bytes32(ciphertext);
uint256 inputLen = 32;

// Call the require precompile.
uint256 precompile = Precompiles.Require;
assembly {
if iszero(staticcall(gas(), precompile, input, inputLen, 0, 0)) {
revert(0, 0)
}
}
}

function decrypt(uint256 ciphertext) internal view returns(uint256 result) {
bytes32[1] memory input;
input[0] = bytes32(ciphertext);
Expand Down
4 changes: 2 additions & 2 deletions contracts/BlindAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ contract BlindAuction is EIP712WithModifier {
// Claim the object. Succeeds only if the caller has the highest bid.
function claim() public onlyAfterEnd {
require(!objectClaimed);
TFHE.req(TFHE.le(highestBid, bids[msg.sender]));
require(TFHE.decrypt(TFHE.le(highestBid, bids[msg.sender])));

objectClaimed = true;
bids[msg.sender] = TFHE.NIL32;
Expand All @@ -137,7 +137,7 @@ contract BlindAuction is EIP712WithModifier {
function withdraw() public onlyAfterEnd {
euint32 bidValue = bids[msg.sender];
if (!objectClaimed) {
TFHE.req(TFHE.lt(bidValue, highestBid));
require(TFHE.decrypt(TFHE.lt(bidValue, highestBid)));
}
tokenContract.transfer(msg.sender, bidValue);
bids[msg.sender] = TFHE.NIL32;
Expand Down
4 changes: 2 additions & 2 deletions contracts/EncryptedERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ contract EncryptedERC20 is EIP712WithModifier {

function _updateAllowance(address owner, address spender, euint32 amount) internal {
euint32 currentAllowance = _allowance(owner, spender);
TFHE.req(TFHE.le(amount, currentAllowance));
require(TFHE.decrypt(TFHE.le(amount, currentAllowance)));
_approve(owner, spender, TFHE.sub(currentAllowance, amount));
}

// Transfers an encrypted amount.
function _transfer(address from, address to, euint32 amount) internal {
// Make sure the sender has enough tokens.
TFHE.req(TFHE.le(amount, balances[from]));
require(TFHE.decrypt(TFHE.le(amount, balances[from])));

// Add to the balance of `to` and subract from the balance of `from`.
balances[to] = TFHE.add(balances[to], amount);
Expand Down
4 changes: 2 additions & 2 deletions contracts/OptimisticRequire.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ contract OptimisticRequire {
// Charge less than full gas, because the non-optimistic ciphertext require aborts early.
function reqFalse() public {
// True.
TFHE.req(TFHE.le(ct1, ct2));
require(TFHE.decrypt(TFHE.le(ct1, ct2)));

// False.
TFHE.req(TFHE.lt(ct1, ct2));
require(TFHE.decrypt(TFHE.lt(ct1, ct2)));

// Try to mutate state to pay for gas - we won't reach that point due to the false require.
doWorkToPayGas();
Expand Down
14 changes: 0 additions & 14 deletions lib/Impl.sol
Original file line number Diff line number Diff line change
Expand Up @@ -580,20 +580,6 @@ library Impl {
result = uint256(output[0]);
}

function req(uint256 ciphertext) internal view {
bytes32[1] memory input;
input[0] = bytes32(ciphertext);
uint256 inputLen = 32;

// Call the require precompile.
uint256 precompile = Precompiles.Require;
assembly {
if iszero(staticcall(gas(), precompile, input, inputLen, 0, 0)) {
revert(0, 0)
}
}
}

function decrypt(uint256 ciphertext) internal view returns (uint256 result) {
bytes32[1] memory input;
input[0] = bytes32(ciphertext);
Expand Down
1 change: 0 additions & 1 deletion lib/Precompiles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ library Precompiles {
uint256 public constant Verify = 66;
uint256 public constant Reencrypt = 67;
uint256 public constant FhePubKey = 68;
uint256 public constant Require = 69;
uint256 public constant LessThanOrEqual = 70;
uint256 public constant Subtract = 71;
uint256 public constant Multiply = 72;
Expand Down
10 changes: 2 additions & 8 deletions lib/TFHE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2483,12 +2483,6 @@ library TFHE {
return euint32.wrap(Impl.not(euint32.unwrap(value)));
}

// Require that the encrypted bool 'b' is true.
// Involves decrypting 'b'.
function req(ebool b) internal view {
Impl.req(ebool.unwrap(b));
}

// Optimistically require that 'b' is true.
//
// This function does not evaluate 'b' at the time of the call.
Expand All @@ -2498,10 +2492,10 @@ library TFHE {
// gas cost, as if all optimistic requires were true. Yet, the transaction will be
// reverted at the end if any of the optimisic requires were false.
//
// Exceptions to above rule are encrypted requires via TFHE.req() and decryption via
// Exceptions to above rule are reencryptions and decryptions via
// TFHE.decrypt(). If either of them are encountered and if optimistic requires have been
// used before in the txn, the optimisic requires will be immediately evaluated. Rationale is
// that we want to avoid decrypting a non-optimistic require or a value if the txn is about
// that we want to avoid decrypting or reencrypting a value if the txn is about
// to fail and be reverted anyway at the end. Checking immediately and reverting on the spot
// would avoid unnecessary decryptions.
//
Expand Down