Skip to content

Commit 125ae9a

Browse files
committed
update RStarM compiling
1 parent 52358bc commit 125ae9a

File tree

4 files changed

+116
-259
lines changed

4 files changed

+116
-259
lines changed

protocol-units/dispute/src/Dispute.sol

+100-14
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,31 @@ import {Output, OutputLib, Receipt, ReceiptClaim, ReceiptClaimLib, IRiscZeroVeri
55
import {Groth16Verifier} from "./groth16/Groth16Verifier.sol";
66
import {SafeCast} from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol";
77

8-
contract Dispute is IRiscZeroVerifier, Groth16Verifier {
8+
/// @notice A Groth16 seal over the claimed receipt claim.
9+
struct Seal {
10+
uint256[2] a;
11+
uint256[2][2] b;
12+
uint256[2] c;
13+
}
14+
15+
contract RStarM is IRiscZeroVerifier, Groth16Verifier {
16+
using ReceiptClaimLib for ReceiptClaim;
17+
using OutputLib for Output;
18+
using SafeCast for uint256;
19+
920
struct Validator {
1021
bool isRegistered;
1122
uint256 stake;
1223
}
1324

1425
struct OptimisticCommitment {
15-
bytes blockHash;
26+
bytes32 blockHash;
1627
bytes stateCommitment; // The state commitment associated with the block
1728
uint256 validatorCount; // Number of validators who have submitted this commitment
1829
}
1930

2031
struct Dispute {
21-
bytes blockHash;
32+
bytes32 blockHash;
2233
uint256 timestamp;
2334
DisputeState state;
2435
}
@@ -45,17 +56,27 @@ contract Dispute is IRiscZeroVerifier, Groth16Verifier {
4556
uint256 public p; // Time to run the zero-knowledge proof
4657
uint256 public m; // Minimum number of validators required to accept a block
4758

59+
/// @notice Control ID hash for the identity_p254 predicate decomposed by `splitDigest`.
60+
/// @dev This value controls what set of recursion programs, and therefore what version of the
61+
/// zkVM circuit, will be accepted by this contract. Each instance of this verifier contract
62+
/// will accept a single release of the RISC Zero circuits.
63+
///
64+
/// New releases of RISC Zero's zkVM require updating these values. These values can be
65+
/// obtained by running `cargo run --bin bonsai-ethereum-contracts -F control-id`
66+
uint256 public immutable CONTROL_ID_0;
67+
uint256 public immutable CONTROL_ID_1;
68+
4869
mapping(address => Validator) public validators;
49-
mapping(bytes => Dispute) public disputes;
70+
mapping(bytes32 => Dispute) public disputes;
5071
mapping(bytes32 => Proof) public verifiedProofs; // Maps blockHash to Proof
5172
mapping(bytes32 => OptimisticCommitment) public optimisticCommitments; // Maps blockHash to OptimisticCommitment
5273

5374
IRiscZeroVerifier public verifier;
5475

5576
event ValidatorRegistered(address indexed validator, uint256 stake);
5677
event ValidatorDeregistered(address indexed validator);
57-
event DisputeSubmitted(bytes indexed disputeHash, bytes blockHash, address indexed submitter);
58-
event DisputeResolved(bytes indexed disputeHash, DisputeState state);
78+
event DisputeSubmitted(bytes32 indexed disputeHash, bytes32 blockHash, address indexed submitter);
79+
event DisputeResolved(bytes32 indexed disputeHash, DisputeState state);
5980
event ProofSubmitted(bytes32 indexed blockHash, bool isValid);
6081
event ProofVerified(bytes32 indexed blockHash, bool isValid);
6182
event BlockAccepted(bytes32 indexed blockHash);
@@ -86,14 +107,16 @@ contract Dispute is IRiscZeroVerifier, Groth16Verifier {
86107
emit ValidatorDeregistered(msg.sender);
87108
}
88109

89-
function submitDispute(bytes calldata blockHash) external {
90-
bytes memory disputeHash = abi.encodePacked(blockHash, msg.sender, block.timestamp);
110+
// We probably want to use bytes calldata here to reduce gas but going with bytes32 for now as we
111+
// need it elsewhere.
112+
function submitDispute(bytes32 blockHash) external {
113+
bytes32 disputeHash = keccak256(abi.encodePacked(blockHash, msg.sender, block.timestamp));
91114
require(disputes[disputeHash].timestamp == 0, "Dispute already submitted");
92115
disputes[disputeHash] = Dispute(blockHash, block.timestamp, DisputeState.SUBMITTED);
93116
emit DisputeSubmitted(disputeHash, blockHash, msg.sender);
94117
}
95118

96-
function resolveDispute(bytes calldata disputeHash, DisputeState state) external {
119+
function resolveDispute(bytes32 disputeHash, DisputeState state) external {
97120
require(state > DisputeState.SUBMITTED && state <= DisputeState.UNVERIFIABLE, "Invalid state transition");
98121
Dispute storage dispute = disputes[disputeHash];
99122
require(dispute.timestamp != 0, "Dispute not found");
@@ -102,17 +125,53 @@ contract Dispute is IRiscZeroVerifier, Groth16Verifier {
102125
emit DisputeResolved(disputeHash, state);
103126
}
104127

105-
function submitProof(bytes32 blockHash, Receipt calldata receipt, bytes32[] calldata publicInputs) external {
128+
// removed publicInputs from the function signature as I don't think we need it.
129+
function submitProof(bytes32 blockHash, Receipt calldata receipt) external {
106130
require(!verifiedProofs[blockHash].exists, "Proof already submitted for this block");
107131
bool isValid = verifier.verify_integrity(receipt);
108132
verifiedProofs[blockHash] = Proof(blockHash, isValid, true);
109133
emit ProofSubmitted(blockHash, isValid);
110134
}
111135

112-
// Additional checks or logic could be implemented here based on the application's needs
113-
function verifyProof(bytes32 blockHash) external view returns (bool isValid, bool exists) {
114-
require(verifiedProofs[blockHash].exists, "Proof not found");
115-
return (verifiedProofs[blockHash].isValid, verifiedProofs[blockHash].exists);
136+
/// @notice splits a digest into two 128-bit words to use as public signal inputs.
137+
/// @dev RISC Zero's Circom verifier circuit takes each of two hash digests in two 128-bit
138+
/// chunks. These values can be derived from the digest by splitting the digest in half and
139+
/// then reversing the bytes of each.
140+
function splitDigest(bytes32 digest) internal pure returns (uint256, uint256) {
141+
uint256 reversed = reverseByteOrderUint256(uint256(digest));
142+
return (uint256(uint128(uint256(reversed))), uint256(reversed >> 128));
143+
}
144+
145+
function verify(bytes calldata seal, bytes32 imageId, bytes32 postStateDigest, bytes32 journalDigest)
146+
public
147+
view
148+
returns (bool)
149+
{
150+
//require(verifiedProofs[blockHash].exists, "Proof not found");
151+
Receipt memory receipt = Receipt(
152+
seal,
153+
ReceiptClaim(
154+
imageId,
155+
postStateDigest,
156+
ExitCode(SystemExitCode.Halted, 0),
157+
bytes32(0),
158+
Output(journalDigest, bytes32(0)).digest()
159+
)
160+
);
161+
return grothVerify(receipt);
162+
}
163+
164+
function grothVerify(Receipt memory receipt) public view returns (bool) {
165+
(uint256 claim0, uint256 claim1) = splitDigest(receipt.claim.digest());
166+
Seal memory seal = abi.decode(receipt.seal, (Seal));
167+
return this.verifyProof(seal.a, seal.b, seal.c, [CONTROL_ID_0, CONTROL_ID_1, claim0, claim1]);
168+
}
169+
170+
// The camel case here is not standard solidity practice. But we use it because its the implemntation of the interface.
171+
function verify_integrity(Receipt memory receipt) public view returns (bool) {
172+
(uint256 claim0, uint256 claim1) = splitDigest(receipt.claim.digest());
173+
Seal memory seal = abi.decode(receipt.seal, (Seal));
174+
return this.verifyProof(seal.a, seal.b, seal.c, [CONTROL_ID_0, CONTROL_ID_1, claim0, claim1]);
116175
}
117176

118177
function submitOptimisticCommitment(bytes32 blockHash, bytes calldata stateCommitment) external {
@@ -134,4 +193,31 @@ contract Dispute is IRiscZeroVerifier, Groth16Verifier {
134193
emit BlockAccepted(blockHash);
135194
}
136195
}
196+
197+
/// @notice reverse the byte order of the uint256 value.
198+
/// @dev Soldity uses a big-endian ABI encoding. Reversing the byte order before encoding
199+
/// ensure that the encoded value will be little-endian.
200+
/// Written by k06a. https://ethereum.stackexchange.com/a/83627
201+
function reverseByteOrderUint256(uint256 input) public pure returns (uint256 v) {
202+
v = input;
203+
204+
// swap bytes
205+
v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8)
206+
| ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);
207+
208+
// swap 2-byte long pairs
209+
v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16)
210+
| ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);
211+
212+
// swap 4-byte long pairs
213+
v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32)
214+
| ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);
215+
216+
// swap 8-byte long pairs
217+
v = ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64)
218+
| ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);
219+
220+
// swap 16-byte long pairs
221+
v = (v >> 128) | (v << 128);
222+
}
137223
}

protocol-units/dispute/src/RiscZeroCheats.sol

-82
This file was deleted.

protocol-units/dispute/src/groth16/Groth16Verifier.sol

+16-23
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,25 @@ contract Groth16Verifier {
3737
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
3838
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
3939
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
40-
uint256 constant deltax1 = 17459137677540232029121579111806194201335604911445641118023073971023969565095;
41-
uint256 constant deltax2 = 16850927772192893321067430466725055468022063819919435552018169508037555801891;
42-
uint256 constant deltay1 = 16440269342816906375775882524040730637133399248560416660251195197654028701204;
43-
uint256 constant deltay2 = 20318668496029522144912607185068507665315850570859328375503723843595483973858;
40+
uint256 constant deltax1 = 18518940221910320856687047018635785128750837022059566906616608708313475199865;
41+
uint256 constant deltax2 = 9492326610711013918333865133991413442330971822743127449106067493230447878125;
42+
uint256 constant deltay1 = 19483644759748826533215810634368877792922012485854314246298395665859158607201;
43+
uint256 constant deltay2 = 21375251776817431660251933179512026180139877181625068362970095925425149918084;
4444

45-
uint256 constant IC0x = 8446592859352799428420270221449902464741693648963397251242447530457567083492;
46-
uint256 constant IC0y = 1064796367193003797175961162477173481551615790032213185848276823815288302804;
45+
uint256 constant IC0x = 5283414572476013565779278723585415063371186194506872223482170607932178811733;
46+
uint256 constant IC0y = 18704069070102836155408936676819275373965966640372164023392964533091458933020;
4747

48-
uint256 constant IC1x = 3179835575189816632597428042194253779818690147323192973511715175294048485951;
49-
uint256 constant IC1y = 20895841676865356752879376687052266198216014795822152491318012491767775979074;
48+
uint256 constant IC1x = 4204832149120840018317309580010992142700029278901617154852760187580780425598;
49+
uint256 constant IC1y = 12454324579480242399557363837918019584959512625719173397955145140913291575910;
5050

51-
uint256 constant IC2x = 5332723250224941161709478398807683311971555792614491788690328996478511465287;
52-
uint256 constant IC2y = 21199491073419440416471372042641226693637837098357067793586556692319371762571;
51+
uint256 constant IC2x = 14956117485756386823219519866025248834283088288522682527835557402788427995664;
52+
uint256 constant IC2y = 6968527870554016879785099818512699922114301060378071349626144898778340839382;
5353

54-
uint256 constant IC3x = 12457994489566736295787256452575216703923664299075106359829199968023158780583;
55-
uint256 constant IC3y = 19706766271952591897761291684837117091856807401404423804318744964752784280790;
54+
uint256 constant IC3x = 6512168907754184210144919576616764035747139382744482291187821746087116094329;
55+
uint256 constant IC3y = 17156131719875889332084290091263207055049222677188492681713268727972722760739;
5656

57-
uint256 constant IC4x = 19617808913178163826953378459323299110911217259216006187355745713323154132237;
58-
uint256 constant IC4y = 21663537384585072695701846972542344484111393047775983928357046779215877070466;
59-
60-
uint256 constant IC5x = 6834578911681792552110317589222010969491336870276623105249474534788043166867;
61-
uint256 constant IC5y = 15060583660288623605191393599883223885678013570733629274538391874953353488393;
57+
uint256 constant IC4x = 5195346330747727606774560791771406703229046454464300598774280139349802276261;
58+
uint256 constant IC4y = 16279160127031959334335024858510026085227931356896384961436876214395869945425;
6259

6360
// Memory data
6461
uint16 constant pVk = 0;
@@ -70,7 +67,7 @@ contract Groth16Verifier {
7067
uint256[2] calldata _pA,
7168
uint256[2][2] calldata _pB,
7269
uint256[2] calldata _pC,
73-
uint256[5] calldata _pubSignals
70+
uint256[4] calldata _pubSignals
7471
) public view returns (bool) {
7572
assembly {
7673
function checkField(v) {
@@ -123,8 +120,6 @@ contract Groth16Verifier {
123120

124121
g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
125122

126-
g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
127-
128123
// -A
129124
mstore(_pPairing, calldataload(pA))
130125
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))
@@ -185,13 +180,11 @@ contract Groth16Verifier {
185180

186181
checkField(calldataload(add(_pubSignals, 128)))
187182

188-
checkField(calldataload(add(_pubSignals, 160)))
189-
190183
// Validate all evaluations
191184
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
192185

193186
mstore(0, isValid)
194187
return(0, 0x20)
195188
}
196189
}
197-
}
190+
}

0 commit comments

Comments
 (0)