@crisp-e3/contracts 0.0.1-test → 0.1.0-test
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/CRISPProgram.sol +57 -27
- package/contracts/CRISPVerifier.sol +107 -76
- package/contracts/Mocks/MockEnclave.sol +39 -0
- package/package.json +6 -3
|
@@ -10,6 +10,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
|
10
10
|
import {IE3Program} from "@enclave-e3/contracts/contracts/interfaces/IE3Program.sol";
|
|
11
11
|
import {IInputValidator} from "@enclave-e3/contracts/contracts/interfaces/IInputValidator.sol";
|
|
12
12
|
import {IEnclave} from "@enclave-e3/contracts/contracts/interfaces/IEnclave.sol";
|
|
13
|
+
import {E3} from "@enclave-e3/contracts/contracts/interfaces/IE3.sol";
|
|
13
14
|
import {CRISPInputValidatorFactory} from "./CRISPInputValidatorFactory.sol";
|
|
14
15
|
import {HonkVerifier} from "./CRISPVerifier.sol";
|
|
15
16
|
|
|
@@ -24,6 +25,10 @@ contract CRISPProgram is IE3Program, Ownable {
|
|
|
24
25
|
HonkVerifier private immutable HONK_VERIFIER;
|
|
25
26
|
bytes32 public imageId;
|
|
26
27
|
|
|
28
|
+
/// @notice Half of the largest minimum degree used to fit votes
|
|
29
|
+
/// inside the plaintext polynomial
|
|
30
|
+
uint256 public constant HALF_LARGEST_MINIMUM_DEGREE = 28;
|
|
31
|
+
|
|
27
32
|
// Mappings
|
|
28
33
|
mapping(address => bool) public authorizedContracts;
|
|
29
34
|
mapping(uint256 e3Id => bytes32 paramsHash) public paramsHashes;
|
|
@@ -55,10 +60,7 @@ contract CRISPProgram is IE3Program, Ownable {
|
|
|
55
60
|
) Ownable(msg.sender) {
|
|
56
61
|
require(address(_enclave) != address(0), EnclaveAddressZero());
|
|
57
62
|
require(address(_verifier) != address(0), VerifierAddressZero());
|
|
58
|
-
require(
|
|
59
|
-
address(_inputValidatorFactory) != address(0),
|
|
60
|
-
InvalidInputValidatorFactory()
|
|
61
|
-
);
|
|
63
|
+
require(address(_inputValidatorFactory) != address(0), InvalidInputValidatorFactory());
|
|
62
64
|
require(address(_honkVerifier) != address(0), InvalidHonkVerifier());
|
|
63
65
|
|
|
64
66
|
enclave = _enclave;
|
|
@@ -91,36 +93,68 @@ contract CRISPProgram is IE3Program, Ownable {
|
|
|
91
93
|
/// @notice Validate the E3 program parameters
|
|
92
94
|
/// @param e3Id The E3 program ID
|
|
93
95
|
/// @param e3ProgramParams The E3 program parameters
|
|
94
|
-
function validate(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
) external returns (bytes32, IInputValidator inputValidator) {
|
|
100
|
-
require(
|
|
101
|
-
authorizedContracts[msg.sender] || msg.sender == owner(),
|
|
102
|
-
CallerNotAuthorized()
|
|
103
|
-
);
|
|
96
|
+
function validate(uint256 e3Id, uint256, bytes calldata e3ProgramParams, bytes calldata)
|
|
97
|
+
external
|
|
98
|
+
returns (bytes32, IInputValidator inputValidator)
|
|
99
|
+
{
|
|
100
|
+
require(authorizedContracts[msg.sender] || msg.sender == owner(), CallerNotAuthorized());
|
|
104
101
|
require(paramsHashes[e3Id] == bytes32(0), E3AlreadyInitialized());
|
|
105
102
|
paramsHashes[e3Id] = keccak256(e3ProgramParams);
|
|
106
103
|
|
|
107
104
|
// Deploy a new input validator
|
|
108
|
-
inputValidator = IInputValidator(
|
|
109
|
-
INPUT_VALIDATOR_FACTORY.deploy(address(HONK_VERIFIER), owner())
|
|
110
|
-
);
|
|
105
|
+
inputValidator = IInputValidator(INPUT_VALIDATOR_FACTORY.deploy(address(HONK_VERIFIER), owner()));
|
|
111
106
|
|
|
112
107
|
return (ENCRYPTION_SCHEME_ID, inputValidator);
|
|
113
108
|
}
|
|
114
109
|
|
|
110
|
+
/// @notice Decode the tally from the plaintext output
|
|
111
|
+
/// @param e3Id The E3 program ID
|
|
112
|
+
/// @return yes The number of yes votes
|
|
113
|
+
/// @return no The number of no votes
|
|
114
|
+
function decodeTally(uint256 e3Id) public view returns (uint256 yes, uint256 no) {
|
|
115
|
+
// fetch from enclave
|
|
116
|
+
E3 memory e3 = enclave.getE3(e3Id);
|
|
117
|
+
|
|
118
|
+
// abi decode it into an array of uint256
|
|
119
|
+
uint256[] memory tally = abi.decode(e3.plaintextOutput, (uint256[]));
|
|
120
|
+
|
|
121
|
+
/// @notice We want to completely ignore anything outside of the coefficients
|
|
122
|
+
/// we agreed to store out votes on.
|
|
123
|
+
uint256 halfD = tally.length / 2;
|
|
124
|
+
uint256 START_INDEX_Y = halfD - HALF_LARGEST_MINIMUM_DEGREE;
|
|
125
|
+
uint256 START_INDEX_N = tally.length - HALF_LARGEST_MINIMUM_DEGREE;
|
|
126
|
+
|
|
127
|
+
// first weight (we are converting back from bits to integer)
|
|
128
|
+
uint256 weight = 2 ** (HALF_LARGEST_MINIMUM_DEGREE - 1);
|
|
129
|
+
|
|
130
|
+
// Convert yes votes
|
|
131
|
+
for (uint256 i = START_INDEX_Y; i < halfD; i++) {
|
|
132
|
+
yes += tally[i] * weight;
|
|
133
|
+
weight /= 2; // Right shift equivalent
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Reset weight for no votes
|
|
137
|
+
weight = 2 ** (HALF_LARGEST_MINIMUM_DEGREE - 1);
|
|
138
|
+
|
|
139
|
+
// Convert no votes
|
|
140
|
+
for (uint256 i = START_INDEX_N; i < tally.length; i++) {
|
|
141
|
+
no += tally[i] * weight;
|
|
142
|
+
weight /= 2;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return (yes, no);
|
|
146
|
+
}
|
|
147
|
+
|
|
115
148
|
/// @notice Verify the proof
|
|
116
149
|
/// @param e3Id The E3 program ID
|
|
117
150
|
/// @param ciphertextOutputHash The hash of the ciphertext output
|
|
118
151
|
/// @param proof The proof to verify
|
|
119
|
-
function verify(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
152
|
+
function verify(uint256 e3Id, bytes32 ciphertextOutputHash, bytes memory proof)
|
|
153
|
+
external
|
|
154
|
+
view
|
|
155
|
+
override
|
|
156
|
+
returns (bool)
|
|
157
|
+
{
|
|
124
158
|
require(paramsHashes[e3Id] != bytes32(0), E3DoesNotExist());
|
|
125
159
|
bytes32 inputRoot = bytes32(enclave.getInputRoot(e3Id));
|
|
126
160
|
bytes memory journal = new bytes(396); // (32 + 1) * 4 * 3
|
|
@@ -137,11 +171,7 @@ contract CRISPProgram is IE3Program, Ownable {
|
|
|
137
171
|
/// @param journal The journal to encode into
|
|
138
172
|
/// @param startIndex The start index in the journal
|
|
139
173
|
/// @param hashVal The hash value to encode
|
|
140
|
-
function encodeLengthPrefixAndHash(
|
|
141
|
-
bytes memory journal,
|
|
142
|
-
uint256 startIndex,
|
|
143
|
-
bytes32 hashVal
|
|
144
|
-
) internal pure {
|
|
174
|
+
function encodeLengthPrefixAndHash(bytes memory journal, uint256 startIndex, bytes32 hashVal) internal pure {
|
|
145
175
|
journal[startIndex] = 0x20;
|
|
146
176
|
startIndex += 4;
|
|
147
177
|
for (uint256 i = 0; i < 32; i++) {
|
|
@@ -5,122 +5,122 @@
|
|
|
5
5
|
// or FITNESS FOR A PARTICULAR PURPOSE.
|
|
6
6
|
pragma solidity >=0.8.21;
|
|
7
7
|
|
|
8
|
-
uint256 constant N =
|
|
9
|
-
uint256 constant LOG_N =
|
|
10
|
-
uint256 constant NUMBER_OF_PUBLIC_INPUTS =
|
|
8
|
+
uint256 constant N = 524288;
|
|
9
|
+
uint256 constant LOG_N = 19;
|
|
10
|
+
uint256 constant NUMBER_OF_PUBLIC_INPUTS = 16;
|
|
11
11
|
library HonkVerificationKey {
|
|
12
12
|
function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {
|
|
13
13
|
Honk.VerificationKey memory vk = Honk.VerificationKey({
|
|
14
|
-
circuitSize: uint256(
|
|
15
|
-
logCircuitSize: uint256(
|
|
16
|
-
publicInputsSize: uint256(
|
|
14
|
+
circuitSize: uint256(524288),
|
|
15
|
+
logCircuitSize: uint256(19),
|
|
16
|
+
publicInputsSize: uint256(16),
|
|
17
17
|
ql: Honk.G1Point({
|
|
18
|
-
x: uint256(
|
|
19
|
-
y: uint256(
|
|
18
|
+
x: uint256(0x13ab223ff59cd43e0728277b3e37bce97e3d2faac23f2b3311d8a30a44e25963),
|
|
19
|
+
y: uint256(0x16f019597ce96b3e75f6ba1c88a2ca4d229090e158eb668690748f9dbe53d557)
|
|
20
20
|
}),
|
|
21
21
|
qr: Honk.G1Point({
|
|
22
|
-
x: uint256(
|
|
23
|
-
y: uint256(
|
|
22
|
+
x: uint256(0x0efc1c7316fb670707e58edc7b3b27311d1885a1c991a07b33867c684a9a863c),
|
|
23
|
+
y: uint256(0x174f93332ed828e0bef2437d6db802d5126ebab2c3702e8974c6a4ae0646c0c2)
|
|
24
24
|
}),
|
|
25
25
|
qo: Honk.G1Point({
|
|
26
|
-
x: uint256(
|
|
27
|
-
y: uint256(
|
|
26
|
+
x: uint256(0x208152ab37453ed055b7108a1424e41ac9e878722aa8ef880c6c012d21eef3d5),
|
|
27
|
+
y: uint256(0x1f7dcf9351580536e0fff33cb7b13fb3b0609f0f38c309935a6324959ef64338)
|
|
28
28
|
}),
|
|
29
29
|
q4: Honk.G1Point({
|
|
30
|
-
x: uint256(
|
|
31
|
-
y: uint256(
|
|
30
|
+
x: uint256(0x0963ddfd632aedb1ebae9f7f3ae7ef217ff9bdf5d5dee30d1f0425d7e5d598b1),
|
|
31
|
+
y: uint256(0x220a29354f7f15a3a56faea2719c51fd96b0bc9bb5be5278cc18e4a70b73daec)
|
|
32
32
|
}),
|
|
33
33
|
qm: Honk.G1Point({
|
|
34
|
-
x: uint256(
|
|
35
|
-
y: uint256(
|
|
34
|
+
x: uint256(0x13c6f463efbfdbb1f61e4d88750781b6739363c7892f9833226d65c0ccd9033e),
|
|
35
|
+
y: uint256(0x1a46391907c3fb9562fa563bab195d093cc843ede63f936b25344901919d90db)
|
|
36
36
|
}),
|
|
37
37
|
qc: Honk.G1Point({
|
|
38
|
-
x: uint256(
|
|
39
|
-
y: uint256(
|
|
38
|
+
x: uint256(0x1bb538b0a6019118e246dce49852f4bdbcd60fb4150833dafc064b1a8a73e8e5),
|
|
39
|
+
y: uint256(0x2969a444b671dd94a764dbd631698886cc3b2e64750c2c4143c6736fa7c56845)
|
|
40
40
|
}),
|
|
41
41
|
qArith: Honk.G1Point({
|
|
42
|
-
x: uint256(
|
|
43
|
-
y: uint256(
|
|
42
|
+
x: uint256(0x1928e8e9fee021507d02bcd30412ce506a543e67a85bee951d8af25432cf1e2d),
|
|
43
|
+
y: uint256(0x258bf8ef04faf434cc77fe4edaffcc94e6013df01f85ca64260d5d7099280381)
|
|
44
44
|
}),
|
|
45
45
|
qDeltaRange: Honk.G1Point({
|
|
46
|
-
x: uint256(
|
|
47
|
-
y: uint256(
|
|
46
|
+
x: uint256(0x01dbbbd0cd1b7aa0b578c58d34b271245b64061ef676ef15e092b3089a54cb24),
|
|
47
|
+
y: uint256(0x1f1bfae9f9c59de7326795e9f089c7bbbdb1925f439b29206c58b90f624ff057)
|
|
48
48
|
}),
|
|
49
49
|
qElliptic: Honk.G1Point({
|
|
50
|
-
x: uint256(
|
|
51
|
-
y: uint256(
|
|
50
|
+
x: uint256(0x0daade853bee6788e93755b59e0da87732527349b02c44a04c71c0facc512df0),
|
|
51
|
+
y: uint256(0x08d2431b4246dde4c512fef36fd2057f756fa86df9437b82499788521accab1e)
|
|
52
52
|
}),
|
|
53
53
|
qAux: Honk.G1Point({
|
|
54
|
-
x: uint256(
|
|
55
|
-
y: uint256(
|
|
54
|
+
x: uint256(0x091d75c333a546baa162025fc5413bd6a15b73b744bff710a75299a9b1cbb11e),
|
|
55
|
+
y: uint256(0x160cd0464b1e360218bb120bf522b2f4c51564750d5acce626d87dadd594ca5e)
|
|
56
56
|
}),
|
|
57
57
|
qLookup: Honk.G1Point({
|
|
58
|
-
x: uint256(
|
|
59
|
-
y: uint256(
|
|
58
|
+
x: uint256(0x0d8127977a1a35c9a0d79cb984e7c146cf55d0dcfffed4fe47ba792d80630a57),
|
|
59
|
+
y: uint256(0x29a459a12da1ff349a61bc22f74ccf21003c6023d6c2eacfff820f034ca4c4d0)
|
|
60
60
|
}),
|
|
61
61
|
qPoseidon2External: Honk.G1Point({
|
|
62
|
-
x: uint256(
|
|
63
|
-
y: uint256(
|
|
62
|
+
x: uint256(0x2e7849b38119f1afb8aefdac89a181e566c5be05150575534bb783802819ae88),
|
|
63
|
+
y: uint256(0x039cda5b4478a254bcd6b192d1c67b3ac2143bac86b241b08dc50e0a8d23ceca)
|
|
64
64
|
}),
|
|
65
65
|
qPoseidon2Internal: Honk.G1Point({
|
|
66
|
-
x: uint256(
|
|
67
|
-
y: uint256(
|
|
66
|
+
x: uint256(0x11bca67681de3ea476550a63f2b35b177d7c0fc83eeaf5534832e05e67d1477f),
|
|
67
|
+
y: uint256(0x258998c74d0c585178ed727548943a4497be15d53bb82603a365a8fa859cbb2c)
|
|
68
68
|
}),
|
|
69
69
|
s1: Honk.G1Point({
|
|
70
|
-
x: uint256(
|
|
71
|
-
y: uint256(
|
|
70
|
+
x: uint256(0x183047a917ca53516ae710d178cdb35c17b58d4cf6bebe73ab84edc260969dac),
|
|
71
|
+
y: uint256(0x16fa136788614a8d2a8bbb8a40742a2ec88200a7557899dc22eebb9917f39e79)
|
|
72
72
|
}),
|
|
73
73
|
s2: Honk.G1Point({
|
|
74
|
-
x: uint256(
|
|
75
|
-
y: uint256(
|
|
74
|
+
x: uint256(0x2337ae7661f0d0a9cc43523f73e3ccca7f2e98e6de8eff0caef5a2e38bac8050),
|
|
75
|
+
y: uint256(0x2dbdd39e65dccf475c00f58e0eb06a9be49797a86404bc850eb56fc27a4ca8eb)
|
|
76
76
|
}),
|
|
77
77
|
s3: Honk.G1Point({
|
|
78
|
-
x: uint256(
|
|
79
|
-
y: uint256(
|
|
78
|
+
x: uint256(0x15569d9f85dc5d0f5d1e8f18ae7eea3b909c7e68626c609b33e7959bb9918648),
|
|
79
|
+
y: uint256(0x2d6729e1c9a15ba58ba3cbe46e8c97880014e3f126b17a1b300715cd449be8b1)
|
|
80
80
|
}),
|
|
81
81
|
s4: Honk.G1Point({
|
|
82
|
-
x: uint256(
|
|
83
|
-
y: uint256(
|
|
82
|
+
x: uint256(0x062d199e2a3abdc6bd9c51c9e304859f1c52c29a07449cb515a36ad7ec377240),
|
|
83
|
+
y: uint256(0x28000e3b5fe7da7621520bab4c69e5141c6d6d4dc542a8333748d76a07df71b2)
|
|
84
84
|
}),
|
|
85
85
|
t1: Honk.G1Point({
|
|
86
|
-
x: uint256(
|
|
87
|
-
y: uint256(
|
|
86
|
+
x: uint256(0x0d64abbea744f03212f1bf39e9d9c693424fa71ab2235b3f501ac3bc615e8577),
|
|
87
|
+
y: uint256(0x03abf1a9c83fe43033856e016b6940b2cde1a7438d4150d5f6343e54e692544d)
|
|
88
88
|
}),
|
|
89
89
|
t2: Honk.G1Point({
|
|
90
|
-
x: uint256(
|
|
91
|
-
y: uint256(
|
|
90
|
+
x: uint256(0x112dfebe6cfb2e00aeee241e82c6091f7706a596da1ed976801260f85fced62b),
|
|
91
|
+
y: uint256(0x0cf123627a5260072ece8c03020a378094ef14d4ecd6fa7787cb92b0ff41e16f)
|
|
92
92
|
}),
|
|
93
93
|
t3: Honk.G1Point({
|
|
94
|
-
x: uint256(
|
|
95
|
-
y: uint256(
|
|
94
|
+
x: uint256(0x0a7a39e50057960052581f511cb596259f1e1588666bc96a9795c0194676c2a3),
|
|
95
|
+
y: uint256(0x18d60133c86a16d9192eaffc8a6ac18ccaf3a7ef9f7a2c2a8c0e04df810193a2)
|
|
96
96
|
}),
|
|
97
97
|
t4: Honk.G1Point({
|
|
98
|
-
x: uint256(
|
|
99
|
-
y: uint256(
|
|
98
|
+
x: uint256(0x2ced4be26f6936520870ea5f91a46f746098f71fbd39136e72e816fd1ccf3fcb),
|
|
99
|
+
y: uint256(0x05e4f50caa7b245e81355a0f8966474c9669792cf09f6b4d807a6604ef93cfba)
|
|
100
100
|
}),
|
|
101
101
|
id1: Honk.G1Point({
|
|
102
|
-
x: uint256(
|
|
103
|
-
y: uint256(
|
|
102
|
+
x: uint256(0x1b4b9477e130161cd3a4dab7b5a107cf6eff7794a4dadef3bc0cdf65ec6aa7e5),
|
|
103
|
+
y: uint256(0x1abd71747ef723da70730a348cc041dc13da45be7318091d98b6b9d74c79f399)
|
|
104
104
|
}),
|
|
105
105
|
id2: Honk.G1Point({
|
|
106
|
-
x: uint256(
|
|
107
|
-
y: uint256(
|
|
106
|
+
x: uint256(0x12fab07a701a5614890650c7bb37dade42de520bc6933812670c802fcd5c1a69),
|
|
107
|
+
y: uint256(0x29a07f1b4b391180ec8bf71f361f2b1ce53959dbbfdada7bd2578ed270e20b82)
|
|
108
108
|
}),
|
|
109
109
|
id3: Honk.G1Point({
|
|
110
|
-
x: uint256(
|
|
111
|
-
y: uint256(
|
|
110
|
+
x: uint256(0x125c6b504f1acc65b0fb6e30eced8baff778514e407bf588dd108153fbeda5af),
|
|
111
|
+
y: uint256(0x15f46d027b762ec2aa4a7d59511d5e17e1e13d4df10eb2a5e9748599045d131b)
|
|
112
112
|
}),
|
|
113
113
|
id4: Honk.G1Point({
|
|
114
|
-
x: uint256(
|
|
115
|
-
y: uint256(
|
|
114
|
+
x: uint256(0x0bbc2d69742f95edbeffe3f80527c6e11e9644918540121093c5244ac6d67737),
|
|
115
|
+
y: uint256(0x05780b6e9938c0ff75721918d5a4039840c7b9e2827a02e74845a0b51049794f)
|
|
116
116
|
}),
|
|
117
117
|
lagrangeFirst: Honk.G1Point({
|
|
118
118
|
x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),
|
|
119
119
|
y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)
|
|
120
120
|
}),
|
|
121
121
|
lagrangeLast: Honk.G1Point({
|
|
122
|
-
x: uint256(
|
|
123
|
-
y: uint256(
|
|
122
|
+
x: uint256(0x2616fcd041a9cf147f53b259e2110fc80de4cf4382c39a7f6b75109300489dbd),
|
|
123
|
+
y: uint256(0x1329a5245299bcd004a3ba9f7b72bcd050d16cbb6c437cb690343e131697fed8)
|
|
124
124
|
})
|
|
125
125
|
});
|
|
126
126
|
return vk;
|
|
@@ -272,6 +272,7 @@ uint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;
|
|
|
272
272
|
uint256 constant NUMBER_OF_ENTITIES = 40;
|
|
273
273
|
uint256 constant NUMBER_UNSHIFTED = 35;
|
|
274
274
|
uint256 constant NUMBER_TO_BE_SHIFTED = 5;
|
|
275
|
+
uint256 constant PAIRING_POINTS_SIZE = 16;
|
|
275
276
|
|
|
276
277
|
// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1
|
|
277
278
|
uint256 constant NUMBER_OF_ALPHAS = 25;
|
|
@@ -389,6 +390,8 @@ library Honk {
|
|
|
389
390
|
|
|
390
391
|
|
|
391
392
|
struct Proof {
|
|
393
|
+
// Pairing point object
|
|
394
|
+
Fr[PAIRING_POINTS_SIZE] pairingPointObject;
|
|
392
395
|
// Free wires
|
|
393
396
|
Honk.G1ProofPoint w1;
|
|
394
397
|
Honk.G1ProofPoint w2;
|
|
@@ -486,9 +489,13 @@ library TranscriptLib {
|
|
|
486
489
|
round0[0] = bytes32(circuitSize);
|
|
487
490
|
round0[1] = bytes32(publicInputsSize);
|
|
488
491
|
round0[2] = bytes32(pubInputsOffset);
|
|
489
|
-
|
|
492
|
+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1331): Consider making publicInputsSize not include pairing point object.
|
|
493
|
+
for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {
|
|
490
494
|
round0[3 + i] = bytes32(publicInputs[i]);
|
|
491
495
|
}
|
|
496
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
497
|
+
round0[3 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);
|
|
498
|
+
}
|
|
492
499
|
|
|
493
500
|
// Create the first challenge
|
|
494
501
|
// Note: w4 is added to the challenge later on
|
|
@@ -673,19 +680,33 @@ library TranscriptLib {
|
|
|
673
680
|
}
|
|
674
681
|
|
|
675
682
|
function loadProof(bytes calldata proof) internal pure returns (Honk.Proof memory p) {
|
|
676
|
-
//
|
|
677
|
-
|
|
683
|
+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1332): Optimize this away when we finalize.
|
|
684
|
+
uint256 boundary = 0x0;
|
|
678
685
|
|
|
679
|
-
|
|
680
|
-
|
|
686
|
+
// Pairing point object
|
|
687
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
688
|
+
p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + 0x20]);
|
|
689
|
+
boundary += 0x20;
|
|
690
|
+
}
|
|
691
|
+
// Commitments
|
|
692
|
+
p.w1 = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
693
|
+
boundary += 0x80;
|
|
694
|
+
p.w2 = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
695
|
+
boundary += 0x80;
|
|
696
|
+
p.w3 = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
697
|
+
boundary += 0x80;
|
|
681
698
|
|
|
682
699
|
// Lookup / Permutation Helper Commitments
|
|
683
|
-
p.lookupReadCounts = bytesToG1ProofPoint(proof[
|
|
684
|
-
|
|
685
|
-
p.
|
|
686
|
-
|
|
687
|
-
p.
|
|
688
|
-
|
|
700
|
+
p.lookupReadCounts = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
701
|
+
boundary += 0x80;
|
|
702
|
+
p.lookupReadTags = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
703
|
+
boundary += 0x80;
|
|
704
|
+
p.w4 = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
705
|
+
boundary += 0x80;
|
|
706
|
+
p.lookupInverses = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
707
|
+
boundary += 0x80;
|
|
708
|
+
p.zPerm = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
709
|
+
boundary += 0x80;
|
|
689
710
|
|
|
690
711
|
// Sumcheck univariates
|
|
691
712
|
for (uint256 i = 0; i < CONST_PROOF_SIZE_LOG_N; i++) {
|
|
@@ -715,7 +736,7 @@ library TranscriptLib {
|
|
|
715
736
|
|
|
716
737
|
// Shplonk
|
|
717
738
|
p.shplonkQ = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
718
|
-
boundary
|
|
739
|
+
boundary += 0x80;
|
|
719
740
|
// KZG
|
|
720
741
|
p.kzgQuotient = bytesToG1ProofPoint(proof[boundary:boundary + 0x80]);
|
|
721
742
|
}
|
|
@@ -1542,7 +1563,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1542
1563
|
error ShpleminiFailed();
|
|
1543
1564
|
|
|
1544
1565
|
// Number of field elements in a ultra honk zero knowledge proof
|
|
1545
|
-
uint256 constant PROOF_SIZE =
|
|
1566
|
+
uint256 constant PROOF_SIZE = 456;
|
|
1546
1567
|
|
|
1547
1568
|
function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);
|
|
1548
1569
|
|
|
@@ -1555,7 +1576,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1555
1576
|
Honk.VerificationKey memory vk = loadVerificationKey();
|
|
1556
1577
|
Honk.Proof memory p = TranscriptLib.loadProof(proof);
|
|
1557
1578
|
|
|
1558
|
-
if (publicInputs.length != vk.publicInputsSize) {
|
|
1579
|
+
if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {
|
|
1559
1580
|
revert PublicInputsLengthWrong();
|
|
1560
1581
|
}
|
|
1561
1582
|
|
|
@@ -1566,7 +1587,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1566
1587
|
// Derive public input delta
|
|
1567
1588
|
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1281): Add pubInputsOffset to VK or remove entirely.
|
|
1568
1589
|
t.relationParameters.publicInputsDelta = computePublicInputDelta(
|
|
1569
|
-
publicInputs, t.relationParameters.beta, t.relationParameters.gamma, /*pubInputsOffset=*/1
|
|
1590
|
+
publicInputs, p.pairingPointObject, t.relationParameters.beta, t.relationParameters.gamma, /*pubInputsOffset=*/1
|
|
1570
1591
|
);
|
|
1571
1592
|
|
|
1572
1593
|
// Sumcheck
|
|
@@ -1579,7 +1600,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1579
1600
|
return sumcheckVerified && shpleminiVerified; // Boolean condition not required - nice for vanity :)
|
|
1580
1601
|
}
|
|
1581
1602
|
|
|
1582
|
-
function computePublicInputDelta(bytes32[] memory publicInputs, Fr beta, Fr gamma, uint256 offset)
|
|
1603
|
+
function computePublicInputDelta(bytes32[] memory publicInputs, Fr[PAIRING_POINTS_SIZE] memory pairingPointObject, Fr beta, Fr gamma, uint256 offset)
|
|
1583
1604
|
internal
|
|
1584
1605
|
view
|
|
1585
1606
|
returns (Fr publicInputDelta)
|
|
@@ -1591,7 +1612,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1591
1612
|
Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));
|
|
1592
1613
|
|
|
1593
1614
|
{
|
|
1594
|
-
for (uint256 i = 0; i < numPublicInputs; i++) {
|
|
1615
|
+
for (uint256 i = 0; i < numPublicInputs - PAIRING_POINTS_SIZE; i++) {
|
|
1595
1616
|
Fr pubInput = FrLib.fromBytes32(publicInputs[i]);
|
|
1596
1617
|
|
|
1597
1618
|
numerator = numerator * (numeratorAcc + pubInput);
|
|
@@ -1600,6 +1621,16 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1600
1621
|
numeratorAcc = numeratorAcc + beta;
|
|
1601
1622
|
denominatorAcc = denominatorAcc - beta;
|
|
1602
1623
|
}
|
|
1624
|
+
|
|
1625
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
1626
|
+
Fr pubInput = pairingPointObject[i];
|
|
1627
|
+
|
|
1628
|
+
numerator = numerator * (numeratorAcc + pubInput);
|
|
1629
|
+
denominator = denominator * (denominatorAcc + pubInput);
|
|
1630
|
+
|
|
1631
|
+
numeratorAcc = numeratorAcc + beta;
|
|
1632
|
+
denominatorAcc = denominatorAcc - beta;
|
|
1633
|
+
}
|
|
1603
1634
|
}
|
|
1604
1635
|
|
|
1605
1636
|
// Fr delta = numerator / denominator; // TOOO: batch invert later?
|
|
@@ -1883,4 +1914,4 @@ contract HonkVerifier is BaseHonkVerifier(N, LOG_N, NUMBER_OF_PUBLIC_INPUTS) {
|
|
|
1883
1914
|
function loadVerificationKey() internal pure override returns (Honk.VerificationKey memory) {
|
|
1884
1915
|
return HonkVerificationKey.loadVerificationKey();
|
|
1885
1916
|
}
|
|
1886
|
-
}
|
|
1917
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
//
|
|
3
|
+
// This file is provided WITHOUT ANY WARRANTY;
|
|
4
|
+
// without even the implied warranty of MERCHANTABILITY
|
|
5
|
+
// or FITNESS FOR A PARTICULAR PURPOSE.
|
|
6
|
+
pragma solidity >=0.8.27;
|
|
7
|
+
|
|
8
|
+
import {E3} from "@enclave-e3/contracts/contracts/interfaces/IE3.sol";
|
|
9
|
+
import {IE3Program} from "@enclave-e3/contracts/contracts/interfaces/IE3Program.sol";
|
|
10
|
+
import {IInputValidator} from "@enclave-e3/contracts/contracts/interfaces/IInputValidator.sol";
|
|
11
|
+
import {IDecryptionVerifier} from "@enclave-e3/contracts/contracts/interfaces/IDecryptionVerifier.sol";
|
|
12
|
+
|
|
13
|
+
contract MockEnclave {
|
|
14
|
+
bytes public plaintextOutput;
|
|
15
|
+
|
|
16
|
+
function setPlaintextOutput(uint256[] memory plaintext) external {
|
|
17
|
+
plaintextOutput = abi.encode(plaintext);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getE3(uint256 e3Id) external view returns (E3 memory) {
|
|
21
|
+
return E3({
|
|
22
|
+
seed: 0,
|
|
23
|
+
threshold: [uint32(1), uint32(2)],
|
|
24
|
+
requestBlock: 0,
|
|
25
|
+
startWindow: [uint256(0), uint256(0)],
|
|
26
|
+
duration: 0,
|
|
27
|
+
expiration: 0,
|
|
28
|
+
encryptionSchemeId: bytes32(0),
|
|
29
|
+
e3Program: IE3Program(address(0)),
|
|
30
|
+
e3ProgramParams: bytes(""),
|
|
31
|
+
customParams: bytes(""),
|
|
32
|
+
inputValidator: IInputValidator(address(0)),
|
|
33
|
+
decryptionVerifier: IDecryptionVerifier(address(0)),
|
|
34
|
+
committeePublicKey: bytes32(0),
|
|
35
|
+
ciphertextOutput: bytes32(0),
|
|
36
|
+
plaintextOutput: plaintextOutput
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crisp-e3/contracts",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0-test",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"contracts",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"@types/chai": "^4.2.0",
|
|
48
48
|
"@types/mocha": ">=9.1.0",
|
|
49
49
|
"@types/node": "^22.18.0",
|
|
50
|
+
"chai": "^6.2.0",
|
|
50
51
|
"dotenv": "^16.4.5",
|
|
51
52
|
"ethers": "^6.15.0",
|
|
52
53
|
"forge-std": "github:foundry-rs/forge-std#v1.9.4",
|
|
@@ -57,7 +58,9 @@
|
|
|
57
58
|
"ts-node": "^10.9.2",
|
|
58
59
|
"typechain": "^8.3.0",
|
|
59
60
|
"typescript": "5.8.3",
|
|
60
|
-
"viem": "2.30.6"
|
|
61
|
+
"viem": "2.30.6",
|
|
62
|
+
"@crisp-e3/sdk": "^0.1.0-test",
|
|
63
|
+
"@crisp-e3/zk-inputs": "^0.1.0-test"
|
|
61
64
|
},
|
|
62
65
|
"scripts": {
|
|
63
66
|
"compile": "hardhat compile",
|
|
@@ -66,7 +69,7 @@
|
|
|
66
69
|
"deploy:contracts": "hardhat run deploy/deploy.ts",
|
|
67
70
|
"deploy:contracts:full": "export DEPLOY_ENCLAVE=true && pnpm deploy:contracts",
|
|
68
71
|
"deploy:contracts:full:mock": "export DEPLOY_ENCLAVE=true && export USE_MOCK_VERIFIER=true && export USE_MOCK_INPUT_VALIDATOR=true && pnpm deploy:contracts",
|
|
69
|
-
"test": "hardhat test
|
|
72
|
+
"test": "hardhat test mocha",
|
|
70
73
|
"verify": "hardhat run deploy/verify.ts"
|
|
71
74
|
}
|
|
72
75
|
}
|