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

docs: validate public input first version #648

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
6d402bb
docs: validate public input first version
NicolasRampoldi Jul 18, 2024
dc988cd
docs: update docs
NicolasRampoldi Jul 18, 2024
b3c7589
feat: add validating-public-input example
NicolasRampoldi Jul 18, 2024
03510e2
fix: init project correctly
NicolasRampoldi Jul 18, 2024
3674fa9
feat: final contract version
NicolasRampoldi Jul 18, 2024
0ebfb67
feat: add forge-std
NicolasRampoldi Jul 18, 2024
05aa046
docs: update docs to be more concise
NicolasRampoldi Jul 18, 2024
07e196e
fix: remove .gitmodules
NicolasRampoldi Jul 18, 2024
1ad2d37
fix: downgrade solidity version
NicolasRampoldi Jul 18, 2024
6a504ff
chore: add remappings
NicolasRampoldi Jul 18, 2024
c46abb4
chore: update .gitmodules
NicolasRampoldi Jul 18, 2024
4345c33
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 18, 2024
a75f8f5
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 19, 2024
098bd93
docs: fix purpose of the guide
NicolasRampoldi Jul 19, 2024
7cc165f
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 23, 2024
162ff85
Merge branch 'refs/heads/main' into 640-docs-create-example-that-chec…
NicolasRampoldi Jul 25, 2024
dcfc37f
fix: merge conflicts
NicolasRampoldi Jul 25, 2024
6f35a5c
Merge branch '640-docs-create-example-that-checks-public-input' of gi…
NicolasRampoldi Jul 25, 2024
bb1fcd1
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 25, 2024
411f5b8
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 26, 2024
26cc958
Merge branch 'refs/heads/main' into 640-docs-create-example-that-chec…
NicolasRampoldi Jul 26, 2024
ca242ba
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 29, 2024
d8f20bd
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 29, 2024
72a3680
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 29, 2024
ccdd913
fix: merge conflicts
NicolasRampoldi Jul 30, 2024
3c57a80
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 30, 2024
25aaf7e
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 30, 2024
bde4dce
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 31, 2024
18101d9
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 31, 2024
f4c7583
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Jul 31, 2024
a9c5fe1
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 1, 2024
e0334a8
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 2, 2024
1a2ba52
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 2, 2024
8b24147
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 2, 2024
ee0459d
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 5, 2024
69e3605
Merge branch 'refs/heads/main' into 640-docs-create-example-that-chec…
NicolasRampoldi Aug 5, 2024
bc4fa19
fix: add variables to env in docs
NicolasRampoldi Aug 6, 2024
c822542
fix: add variables to .env.example
NicolasRampoldi Aug 6, 2024
7bc5736
refactor: rename deployer contract to FibonacciDeployer
NicolasRampoldi Aug 6, 2024
eb6aa2e
refactor: emit event after verification
NicolasRampoldi Aug 6, 2024
87dee6d
chore: bump up sdk version to v0.4.0
NicolasRampoldi Aug 6, 2024
b6f3356
refactor: remove get-commitment
NicolasRampoldi Aug 6, 2024
63e68af
docs: clarify explanation
NicolasRampoldi Aug 6, 2024
fff1398
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 6, 2024
2adbd0a
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 7, 2024
df3c9e1
chore: bump up risc0 version
NicolasRampoldi Aug 8, 2024
2d1b01b
fix: docker container
NicolasRampoldi Aug 8, 2024
a40f52e
chore: add program id to output
NicolasRampoldi Aug 8, 2024
244467f
chore: add program id to output
NicolasRampoldi Aug 8, 2024
e93edc5
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 8, 2024
4818c34
fix: program id should be keccaked
NicolasRampoldi Aug 8, 2024
d611056
Merge branch '640-docs-create-example-that-checks-public-input' of gi…
NicolasRampoldi Aug 8, 2024
ccf9efb
feat: add 0x to public input print
NicolasRampoldi Aug 8, 2024
7aae9bc
Update docs/guides/3_validating_public_input.md
entropidelic Aug 8, 2024
394eb54
docs: add cast
NicolasRampoldi Aug 8, 2024
0920585
Merge branch '640-docs-create-example-that-checks-public-input' of gi…
NicolasRampoldi Aug 8, 2024
662f44a
Merge branch 'main' into 640-docs-create-example-that-checks-public-i…
NicolasRampoldi Aug 8, 2024
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "examples/zkquiz/contracts/lib/openzeppelin-contracts"]
path = examples/zkquiz/contracts/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "examples/validating-public-input/contracts/lib/forge-std"]
path = examples/validating-public-input/contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
5 changes: 3 additions & 2 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
* [Submitting proofs](guides/0_submitting_proofs.md)
* [SDK](guides/1_SDK.md)
* [Integrating Aligned into your Application](guides/2_integrating_aligned_into_your_application.md)
* [Generating proofs for Aligned](guides/3_generating_proofs.md)
* [Contract Addresses](guides/4_contract_addresses.md)
* [Validating public input](guides/3_validating_public_input.md)
* [Generating proofs for Aligned](guides/4_generating_proofs.md)
* [Contract Addresses](guides/5_contract_addresses.md)
* [Generating & submitting proofs of Rust code with ZKRust](guides/0_5_using_zkrust.md)

<!-- * [Setup Aligned](developer_guides/2_setup_aligned.md) -->
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/2_integrating_aligned_into_your_application.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This example shows a sample app that generates an SP1 proof that a user knows th

To submit proofs to Aligned and get them verified, first you need to generate those proofs. Every proving system has its own way of generating proofs.

You can find examples on how to generate proofs in the [generating proofs guide](3_generating_proofs.md).
You can find examples on how to generate proofs in the [generating proofs guide](4_generating_proofs.md).

Also, you can find an example of the ZKQuiz proof [program](../../examples/zkquiz/quiz/program/src/main.rs) as well as the [script](../../examples/zkquiz/quiz/script/src/main.rs) that generates it in the [ZKQuiz example directory](../../examples/zkquiz).

Expand Down
201 changes: 201 additions & 0 deletions docs/guides/3_validating_public_input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Validating public input

You can validate that the public input of the proof sent to Aligned for verification is correct in a few simple steps.

NicolasRampoldi marked this conversation as resolved.
Show resolved Hide resolved
This guide demonstrates the submission of a Risc0 proof to Aligned using the Aligned SDK. The Risc0 program to be proven is a Fibonacci sequence calculator. Risc0 generates a public input corresponding to the last two Fibonacci numbers of the sequence taken modulo 7919, and we want to validate in a smart contract that the public input commitments correspond to those two numbers.

In this case, the Fibonacci number to be calculated is **500** and the last two numbers of the sequence modulo 7919 are **1268** and **1926**.

This guide assumes you are in the `examples/validating-public-input` directory.

## Generate your ZK Proof

To submit proofs to Aligned and get them verified, first you need to generate those proofs. Every proving system has its own way of generating proofs.

You can find examples on how to generate proofs in the [generating proofs guide](4_generating_proofs.md).

To generate the proof needed to try this example, run `make generate_risc_zero_fibonacci_proof`.

## Write your smart contract

To check if a proof was verified in Aligned, you need to make a call to the `AlignedServiceManager` contract inside your smart contract.

Also, you will need a way to check that the proven program is the correct one.

The Aligned CLI provides a way for you to get the verification key commitment without actually generating and submitting a proof.
NicolasRampoldi marked this conversation as resolved.
Show resolved Hide resolved

You can do this by running the following command:

```bash
aligned get-commitment --input <path_to_input_file>
```

The following is an example of how to validate the public input of the Risc0 proof in your smart contract.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract FibonacciValidator {
address public alignedServiceManager;
bytes32 public fibonacciImageId;

bytes32 public fibonacciImageIdCommitment =
0xbfa561e384be753bd6fd75b15db31eb511cd114ec76d619a87c2342af0ee1ed7;

event FibonacciNumbers(uint32 fibN, uint32 fibNPlusOne);

constructor(address _alignedServiceManager) {
alignedServiceManager = _alignedServiceManager;
}

function verifyBatchInclusion(
bytes32 proofCommitment,
bytes32 pubInputCommitment,
bytes32 provingSystemAuxDataCommitment,
bytes20 proofGeneratorAddr,
bytes32 batchMerkleRoot,
bytes memory merkleProof,
uint256 verificationDataBatchIndex,
bytes memory journalBytes
) public returns (bool) {
require(
fibonacciImageIdCommitment == provingSystemAuxDataCommitment,
"Image ID doesn't match"
);

require(
pubInputCommitment == keccak256(abi.encodePacked(journalBytes)),
"Fibonacci numbers don't match with public input"
);

(uint32 fibN, uint32 fibNPlusOne) = bytesToTwoUint32(journalBytes);

emit FibonacciNumbers(fibN, fibNPlusOne);

(
bool callWasSuccessful,
bytes memory proofIsIncluded
) = alignedServiceManager.staticcall(
abi.encodeWithSignature(
"verifyBatchInclusion(bytes32,bytes32,bytes32,bytes20,bytes32,bytes,uint256)",
proofCommitment,
pubInputCommitment,
provingSystemAuxDataCommitment,
proofGeneratorAddr,
batchMerkleRoot,
merkleProof,
verificationDataBatchIndex
)
);

require(callWasSuccessful, "static_call failed");

return abi.decode(proofIsIncluded, (bool));
}

function bytesToTwoUint32(
bytes memory data
) public pure returns (uint32, uint32) {
require(data.length >= 8, "Input bytes must be at least 8 bytes long");

uint32 first = uint32(uint8(data[0])) |
(uint32(uint8(data[1])) << 8) |
(uint32(uint8(data[2])) << 16) |
(uint32(uint8(data[3])) << 24);

uint32 second = uint32(uint8(data[4])) |
(uint32(uint8(data[5])) << 8) |
(uint32(uint8(data[6])) << 16) |
(uint32(uint8(data[7])) << 24);

return (first, second);
}
}
```

### Explanation

1. **Verification Key Check:** The contract first checks if the verification key commitment matches the Fibonacci Image ID commitment.
NicolasRampoldi marked this conversation as resolved.
Show resolved Hide resolved

```solidity
require(
fibonacciImageIdCommitment == provingSystemAuxDataCommitment,
"Image ID doesn't match"
);
```

2. **Public Input Commitment Validation:** The contract validates that the public input commitment matches the keccak256 hash of the journalBytes. It then extracts the last two Fibonacci numbers from the journalBytes and emits an event.
NicolasRampoldi marked this conversation as resolved.
Show resolved Hide resolved

```solidity
require(
pubInputCommitment == keccak256(abi.encodePacked(journalBytes)),
"Fibonacci numbers don't match with public input"
);

(uint32 fibN, uint32 fibNPlusOne) = bytesToTwoUint32(journalBytes);

emit FibonacciNumbers(fibN, fibNPlusOne);
```

3. **Static Call to AlignedServiceManager**: The contract makes a static call to the `AlignedServiceManager` contract to check if the proof was verified in Aligned.

```solidity
(
bool callWasSuccessful,
bytes memory proofIsIncluded
) = alignedServiceManager.staticcall(
abi.encodeWithSignature(
"verifyBatchInclusion(bytes32,bytes32,bytes32,bytes20,bytes32,bytes,uint256)",
proofCommitment,
pubInputCommitment,
provingSystemAuxDataCommitment,
proofGeneratorAddr,
batchMerkleRoot,
merkleProof,
verificationDataBatchIndex
)
);

require(callWasSuccessful, "static_call failed");
```

4. **Bytes to two `uint32` conversion:** A helper function to convert a byte array into two `uint32` numbers, used for extracting the last two Fibonacci numbers from the `journalBytes`.

```solidity
function bytesToTwoUint32(
bytes memory data
) public pure returns (uint32, uint32) {
require(data.length >= 8, "Input bytes must be at least 8 bytes long");

uint32 first = uint32(uint8(data[0])) |
(uint32(uint8(data[1])) << 8) |
(uint32(uint8(data[2])) << 16) |
(uint32(uint8(data[3])) << 24);

uint32 second = uint32(uint8(data[4])) |
(uint32(uint8(data[5])) << 8) |
(uint32(uint8(data[6])) << 16) |
(uint32(uint8(data[7])) << 24);

return (first, second);
}
```

To deploy the contract, first you will need to set up the `.env` file in the contracts folder with the following variables:

```
RPC_URL= #You can use publicnode RPC: https://ethereum-holesky-rpc.publicnode.com
PRIVATE_KEY=
ALIGNED_SERVICE_MANAGER_ADDRESS= #0x58F280BeBE9B34c9939C3C39e0890C81f163B623 for Holesky
NicolasRampoldi marked this conversation as resolved.
Show resolved Hide resolved
```

Then, run `make deploy_fibonacci_validator`.

## Submit and verify the proof to Aligned

The proof submission and verification can be done either with the SDK or by using the Aligned CLI.

To submit the proof generated in this example, run `make submit_fibonacci_proof`. This will output the `AlignedVerificationData` needed to send to the `verifyBatchInclusion` method of the contract in the `batch_inclusion_data` directory inside `aligned-integration`.

For more details on submitting proofs, refer to the [submitting proofs guide](0_submitting_proofs.md).
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions examples/validating-public-input/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Compiler files
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env
11 changes: 11 additions & 0 deletions examples/validating-public-input/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
generate_risc_zero_fibonacci_proof:
@cd risc_zero/fibonacci_proof_generator && \
cargo run --release && \
echo "Fibonacci proof, pub input and image ID generated in risc_zero folder"

submit_fibonacci_proof:
@cd aligned-integration && \
RUST_LOG=info cargo run --release

deploy_fibonacci_validator:
@. ./contracts/.env && . ./contracts/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
batch_inclusion_data/
Loading