Skip to content

Commit

Permalink
Merge pull request #106 from gnosisguild:move-decryption-verifiers
Browse files Browse the repository at this point in the history
feat: moves `IDecryptionVerifier` out of `E3Program` / `IComputeProvider`
  • Loading branch information
auryn-macmillan authored Sep 20, 2024
2 parents 021c84c + 3c1a0b9 commit 513ec36
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 85 deletions.
57 changes: 27 additions & 30 deletions packages/evm/contracts/Enclave.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ contract Enclave is IEnclave, OwnableUpgradeable {
mapping(uint256 e3Id => uint256 inputCount) public inputCounts;

// Mapping of enabled encryption schemes.
mapping(bytes32 encryptionSchemeId => bool enabled)
public encryptionSchemes;
mapping(bytes32 encryptionSchemeId => IDecryptionVerifier decryptionVerifier)
public decryptionVerifiers;

////////////////////////////////////////////////////////////
// //
Expand All @@ -62,10 +62,7 @@ contract Enclave is IEnclave, OwnableUpgradeable {
error InvalidEncryptionScheme(bytes32 encryptionSchemeId);
error InputDeadlinePassed(uint256 e3Id, uint256 expiration);
error InputDeadlineNotPassed(uint256 e3Id, uint256 expiration);
error InvalidComputationRequest(
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
);
error InvalidComputationRequest(IInputValidator inputValidator);
error InvalidCiphernodeRegistry(ICiphernodeRegistry ciphernodeRegistry);
error InvalidInput();
error InvalidDuration(uint256 duration);
Expand Down Expand Up @@ -145,24 +142,19 @@ contract Enclave is IEnclave, OwnableUpgradeable {
nexte3Id++;
uint256 seed = uint256(keccak256(abi.encode(block.prevrandao, e3Id)));

(
bytes32 encryptionSchemeId,
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
) = e3Program.validate(
e3Id,
seed,
e3ProgramParams,
computeProviderParams
);
(bytes32 encryptionSchemeId, IInputValidator inputValidator) = e3Program
.validate(e3Id, seed, e3ProgramParams, computeProviderParams);
IDecryptionVerifier decryptionVerifier = decryptionVerifiers[
encryptionSchemeId
];
require(
encryptionSchemes[encryptionSchemeId],
decryptionVerifiers[encryptionSchemeId] !=
IDecryptionVerifier(address(0)),
InvalidEncryptionScheme(encryptionSchemeId)
);
require(
address(inputValidator) != address(0) &&
address(decryptionVerifier) != address(0),
InvalidComputationRequest(inputValidator, decryptionVerifier)
address(inputValidator) != address(0),
InvalidComputationRequest(inputValidator)
);

e3 = E3({
Expand Down Expand Up @@ -339,14 +331,16 @@ contract Enclave is IEnclave, OwnableUpgradeable {
emit E3ProgramDisabled(e3Program);
}

function enableEncryptionScheme(
bytes32 encryptionSchemeId
function setDecryptionVerifier(
bytes32 encryptionSchemeId,
IDecryptionVerifier decryptionVerifier
) public onlyOwner returns (bool success) {
require(
!encryptionSchemes[encryptionSchemeId],
decryptionVerifier != IDecryptionVerifier(address(0)) &&
decryptionVerifiers[encryptionSchemeId] != decryptionVerifier,
InvalidEncryptionScheme(encryptionSchemeId)
);
encryptionSchemes[encryptionSchemeId] = true;
decryptionVerifiers[encryptionSchemeId] = decryptionVerifier;
success = true;
emit EncryptionSchemeEnabled(encryptionSchemeId);
}
Expand All @@ -355,11 +349,14 @@ contract Enclave is IEnclave, OwnableUpgradeable {
bytes32 encryptionSchemeId
) public onlyOwner returns (bool success) {
require(
encryptionSchemes[encryptionSchemeId],
decryptionVerifiers[encryptionSchemeId] !=
IDecryptionVerifier(address(0)),
InvalidEncryptionScheme(encryptionSchemeId)
);
encryptionSchemes[encryptionSchemeId] = false;
success = false;
decryptionVerifiers[encryptionSchemeId] = IDecryptionVerifier(
address(0)
);
success = true;
emit EncryptionSchemeDisabled(encryptionSchemeId);
}

Expand All @@ -382,9 +379,9 @@ contract Enclave is IEnclave, OwnableUpgradeable {
return InternalLeanIMT._root(inputs[e3Id]);
}

function isEncryptionSchemeEnabled(
function getDecryptionVerifier(
bytes32 encryptionSchemeId
) public view returns (bool) {
return encryptionSchemes[encryptionSchemeId];
) public view returns (IDecryptionVerifier) {
return decryptionVerifiers[encryptionSchemeId];
}
}
8 changes: 1 addition & 7 deletions packages/evm/contracts/interfaces/IE3Program.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity >=0.8.27;

import { IInputValidator } from "./IInputValidator.sol";
import { IDecryptionVerifier } from "./IDecryptionVerifier.sol";

interface IE3Program {
/// @notice This function should be called by the Enclave contract to validate the computation parameters.
Expand All @@ -12,19 +11,14 @@ interface IE3Program {
/// @param computeProviderParams ABI encoded compute provider parameters.
/// @return encryptionSchemeId ID of the encryption scheme to be used for the computation.
/// @return inputValidator The input validator to be used for the computation.
/// @return decryptionVerifier The decryption verifier to be used for the computation.
function validate(
uint256 e3Id,
uint256 seed,
bytes calldata e3ProgramParams,
bytes calldata computeProviderParams
)
external
returns (
bytes32 encryptionSchemeId,
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
);
returns (bytes32 encryptionSchemeId, IInputValidator inputValidator);

/// @notice This function should be called by the Enclave contract to verify the decrypted output of an E3.
/// @param e3Id ID of the E3.
Expand Down
13 changes: 2 additions & 11 deletions packages/evm/contracts/test/MockE3Program.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.27;

import {
IE3Program,
IInputValidator,
IDecryptionVerifier
} from "../interfaces/IE3Program.sol";
import { IE3Program, IInputValidator } from "../interfaces/IE3Program.sol";

contract MockE3Program is IE3Program {
error invalidParams(bytes e3ProgramParams, bytes computeProviderParams);
Expand All @@ -18,11 +14,7 @@ contract MockE3Program is IE3Program {
)
external
pure
returns (
bytes32 encryptionSchemeId,
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
)
returns (bytes32 encryptionSchemeId, IInputValidator inputValidator)
{
require(
e3ProgramParams.length == 32 && computeProviderParams.length == 32,
Expand All @@ -31,7 +23,6 @@ contract MockE3Program is IE3Program {
// solhint-disable no-inline-assembly
assembly {
inputValidator := mload(add(e3ProgramParams, 32))
decryptionVerifier := mload(add(computeProviderParams, 32))
}
encryptionSchemeId = 0x0000000000000000000000000000000000000000000000000000000000000001;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@gnosis-guild/enclave",
"description": "Enclave is an open-source protocol for Encrypted Execution Environments (E3).",
"version": "0.0.2",
"version": "0.0.3",
"license": "LGPL-3.0-only",
"author": {
"name": "gnosisguild",
Expand Down
100 changes: 64 additions & 36 deletions packages/evm/test/Enclave.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ describe("Enclave", function () {
await poseidon.getAddress(),
);

await enclave.enableEncryptionScheme(encryptionSchemeId);
await enclave.setDecryptionVerifier(
encryptionSchemeId,
await decryptionVerifier.getAddress(),
);
await enclave.enableE3Program(await e3Program.getAddress());

return {
Expand Down Expand Up @@ -217,47 +220,79 @@ describe("Enclave", function () {
});
});

describe("isEncryptionSchemeEnabled()", function () {
describe("getDecryptionVerifier()", function () {
it("returns true if encryption scheme is enabled", async function () {
const { enclave } = await loadFixture(setup);
expect(await enclave.isEncryptionSchemeEnabled(encryptionSchemeId)).to.be
.true;
const { enclave, mocks } = await loadFixture(setup);
expect(await enclave.getDecryptionVerifier(encryptionSchemeId)).to.equal(
await mocks.decryptionVerifier.getAddress(),
);
});
it("returns false if encryption scheme is not enabled", async function () {
const { enclave } = await loadFixture(setup);
expect(await enclave.isEncryptionSchemeEnabled(newEncryptionSchemeId)).to
.be.false;
expect(
await enclave.getDecryptionVerifier(newEncryptionSchemeId),
).to.equal(ethers.ZeroAddress);
});
});

describe("enableEncryptionScheme()", function () {
describe("setDecryptionVerifier()", function () {
it("reverts if caller is not owner", async function () {
const { enclave, notTheOwner } = await loadFixture(setup);
const { enclave, notTheOwner, mocks } = await loadFixture(setup);

await expect(
enclave.connect(notTheOwner).enableEncryptionScheme(encryptionSchemeId),
enclave
.connect(notTheOwner)
.setDecryptionVerifier(
encryptionSchemeId,
await mocks.decryptionVerifier.getAddress(),
),
)
.to.be.revertedWithCustomError(enclave, "OwnableUnauthorizedAccount")
.withArgs(notTheOwner);
});
it("reverts if encryption scheme is already enabled", async function () {
const { enclave } = await loadFixture(setup);
const { enclave, mocks } = await loadFixture(setup);

await expect(enclave.enableEncryptionScheme(encryptionSchemeId))
await expect(
enclave.setDecryptionVerifier(
encryptionSchemeId,
await mocks.decryptionVerifier.getAddress(),
),
)
.to.be.revertedWithCustomError(enclave, "InvalidEncryptionScheme")
.withArgs(encryptionSchemeId);
});
it("enabled encryption scheme", async function () {
const { enclave } = await loadFixture(setup);
it("enabled decryption verifier", async function () {
const { enclave, mocks } = await loadFixture(setup);

expect(await enclave.enableEncryptionScheme(newEncryptionSchemeId));
expect(await enclave.isEncryptionSchemeEnabled(newEncryptionSchemeId)).to
.be.true;
expect(
await enclave.setDecryptionVerifier(
newEncryptionSchemeId,
await mocks.decryptionVerifier.getAddress(),
),
);
expect(
await enclave.getDecryptionVerifier(newEncryptionSchemeId),
).to.equal(await mocks.decryptionVerifier.getAddress());
});
it("returns true if decryption verifier is enabled successfully", async function () {
const { enclave, mocks } = await loadFixture(setup);

const result = await enclave.setDecryptionVerifier.staticCall(
newEncryptionSchemeId,
await mocks.decryptionVerifier.getAddress(),
);
expect(result).to.be.true;
});
it("emits EncryptionSchemeEnabled", async function () {
const { enclave } = await loadFixture(setup);
const { enclave, mocks } = await loadFixture(setup);

await expect(await enclave.enableEncryptionScheme(newEncryptionSchemeId))
await expect(
await enclave.setDecryptionVerifier(
newEncryptionSchemeId,
await mocks.decryptionVerifier.getAddress(),
),
)
.to.emit(enclave, "EncryptionSchemeEnabled")
.withArgs(newEncryptionSchemeId);
});
Expand Down Expand Up @@ -286,8 +321,16 @@ describe("Enclave", function () {
const { enclave } = await loadFixture(setup);

expect(await enclave.disableEncryptionScheme(encryptionSchemeId));
expect(await enclave.isEncryptionSchemeEnabled(encryptionSchemeId)).to.be
.false;
expect(await enclave.getDecryptionVerifier(encryptionSchemeId)).to.equal(
ethers.ZeroAddress,
);
});
it("returns true if encryption scheme is disabled successfully", async function () {
const { enclave } = await loadFixture(setup);

const result =
await enclave.disableEncryptionScheme.staticCall(encryptionSchemeId);
expect(result).to.be.true;
});
it("emits EncryptionSchemeDisabled", async function () {
const { enclave } = await loadFixture(setup);
Expand Down Expand Up @@ -514,21 +557,6 @@ describe("Enclave", function () {
),
).to.be.revertedWithCustomError(enclave, "InvalidComputationRequest");
});
it("reverts if given compute provider does not return output verifier address", async function () {
const { enclave, request } = await loadFixture(setup);
await expect(
enclave.request(
request.filter,
request.threshold,
request.startTime,
request.duration,
request.e3Program,
request.e3ProgramParams,
ZeroHash,
{ value: 10 },
),
).to.be.revertedWithCustomError(enclave, "InvalidComputationRequest");
});
it("reverts if committee selection fails", async function () {
const { enclave, request } = await loadFixture(setup);
await expect(
Expand Down

0 comments on commit 513ec36

Please sign in to comment.