Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ batcher_send_sp1_task: ## Send a SP1 fibonacci proof to Batcher. Parameters: RPC
--proving_system SP1 \
--proof ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof \
--vm_program ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf \
--public_input ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub \
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
--rpc_url $(RPC_URL) \
--network $(NETWORK)
Expand All @@ -539,6 +540,7 @@ batcher_send_sp1_burst: ## Send a burst of SP1 fibonacci proofs to Batcher. Para
--proving_system SP1 \
--proof ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof \
--vm_program ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf \
--public_input ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub \
--proof_generator_addr 0x66f9664f97F2b50F62D13eA064982f936dE76657 \
--repetitions $(BURST_SIZE) \
--rpc_url $(RPC_URL) \
Expand Down Expand Up @@ -763,6 +765,10 @@ generate_sp1_fibonacci_proof: ## Run the SP1 Fibonacci proof generator script
@cd scripts/test_files/sp1/fibonacci_proof_generator/script && RUST_LOG=info cargo run --release
@echo "Fibonacci proof and ELF generated in scripts/test_files/sp1 folder"

generate_sp1_fibonacci_proof_no_pub_input: ## Run the SP1 Fibonacci proof generator script with empty journal
@cd scripts/test_files/sp1/no_public_inputs/script && RUST_LOG=info cargo run --release
@echo "Fibonacci proof and ELF with no public inputs generated in scripts/test_files/sp1 folder"

generate_risc_zero_fibonacci_proof: ## Run the Risc0 Fibonacci proof generator script
@cd scripts/test_files/risc_zero/fibonacci_proof_generator && \
RUST_LOG=info cargo run --release && \
Expand Down Expand Up @@ -1073,6 +1079,7 @@ docker_batcher_send_sp1_burst:
--proving_system SP1 \
--proof ./scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof \
--vm_program ./scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf \
--public_input ./scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub \
--repetitions $(DOCKER_BURST_SIZE) \
--proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \
--rpc_url $(DOCKER_RPC_URL) \
Expand Down
11 changes: 7 additions & 4 deletions crates/batcher/src/sp1/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use log::{debug, error, warn};
use sp1_sdk::{EnvProver, ProverClient};
use sp1_sdk::{EnvProver, ProverClient, SP1ProofWithPublicValues};
use std::sync::OnceLock;

static SP1_PROVER_CLIENT: OnceLock<EnvProver> = OnceLock::new();

pub fn verify_sp1_proof(proof: &[u8], elf: &[u8]) -> bool {
pub fn verify_sp1_proof(proof: &[u8], public_inputs: &[u8], elf: &[u8]) -> bool {
if proof.is_empty() || elf.is_empty() {
error!("SP1 Input buffers zero size");
return false;
Expand All @@ -14,8 +14,11 @@ pub fn verify_sp1_proof(proof: &[u8], elf: &[u8]) -> bool {
let prover_client = SP1_PROVER_CLIENT.get_or_init(ProverClient::from_env);

let (_pk, vk) = prover_client.setup(elf);
if let Ok(proof) = bincode::deserialize(proof) {
//client.verify(&proof, &vk).expect("failed to verify proof");
if let Ok(proof) = bincode::deserialize::<SP1ProofWithPublicValues>(proof) {
if *proof.public_values.as_slice() != *public_inputs {
warn!("SP1 public inputs do not match proof public values");
return false;
}
let res = prover_client.verify(&proof, &vk).is_ok();
debug!("SP1 proof is valid: {}", res);
if res {
Expand Down
7 changes: 6 additions & 1 deletion crates/batcher/src/zk_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ fn verify_internal(verification_data: &VerificationData) -> bool {
warn!("Trying to verify SP1 proof but ELF was not provided. Returning invalid");
return false;
};
verify_sp1_proof(verification_data.proof.as_slice(), elf.as_slice())
let pub_inputs = &verification_data.pub_input.clone().unwrap_or_default();
verify_sp1_proof(
verification_data.proof.as_slice(),
pub_inputs.as_slice(),
elf.as_slice(),
)
}
ProvingSystemId::Risc0 => {
let Some(image_id_slice) = &verification_data.vm_program_code else {
Expand Down
14 changes: 13 additions & 1 deletion crates/cli/get_proof_test_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ CURRENT_TAG=$(curl -s -L \

SP1_ELF_URL="https://raw.githubusercontent.com/yetanotherco/aligned_layer/$CURRENT_TAG/scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf"
SP1_PROOF_URL="https://raw.githubusercontent.com/yetanotherco/aligned_layer/$CURRENT_TAG/scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof"
SP1_PUBLIC_INPUT_URL="https://raw.githubusercontent.com/yetanotherco/aligned_layer/$CURRENT_TAG/scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub"

SP1_ELF_NAME="sp1_fibonacci_5_0_0.elf"
SP1_PROOF_NAME="sp1_fibonacci_5_0_0.proof"
SP1_PUBLIC_INPUT_NAME="sp1_fibonacci_5_0_0.pub"

BASE_DIR=$HOME
ALIGNED_DIR="${ALIGNED_DIR-"$BASE_DIR/.aligned"}"
Expand All @@ -36,7 +38,17 @@ else
exit 1
fi

echo "Downloading SP1 public inputs file..."

if curl -sSf -L "$SP1_PUBLIC_INPUT_NAME" -o "$ALIGNED_TEST_FILES_DIR/$SP1_PUBLIC_INPUT_NAME"; then
echo "SP1 public inputs downloaded successful"
else
echo "Error: Failed to downloaded $SP1_PUBLIC_INPUT_NAME"
exit 1
fi

chmod +x "$ALIGNED_TEST_FILES_DIR/$SP1_ELF_NAME"
chmod +x "$ALIGNED_TEST_FILES_DIR/$SP1_PROOF_NAME"
chmod +x "$ALIGNED_TEST_FILES_DIR/$SP1_PUBLIC_INPUT_NAME"

echo "SP1 ELF and proof files downloaded successfully in $ALIGNED_TEST_FILES_DIR"
echo "SP1 ELF, proof and public inputs files downloaded successfully in $ALIGNED_TEST_FILES_DIR"
3 changes: 2 additions & 1 deletion crates/cli/send_proof_with_random_address.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ if [[ $PROOF_TYPE == "sp1" ]]; then
--proving_system SP1 \
--proof ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof \
--vm_program ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf \
--random_address \
--public_input ../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub \
--random_address \
--repetitions $REPETITIONS \
--rpc_url $RPC_URL \
--network $NETWORK
Expand Down
7 changes: 6 additions & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ fn verification_data_from_args(args: &SubmitArgs) -> Result<VerificationData, Su
// Read proof file
let proof = read_file(args.proof_file_name.clone())?;

let mut pub_input: Option<Vec<u8>> = None;
let pub_input: Option<Vec<u8>>;
let mut verification_key: Option<Vec<u8>> = None;
let mut vm_program_code: Option<Vec<u8>> = None;

Expand All @@ -887,6 +887,11 @@ fn verification_data_from_args(args: &SubmitArgs) -> Result<VerificationData, Su
"--vm_program",
args.vm_program_code_file_name.clone(),
)?);
pub_input = args
.pub_input_file_name
.clone()
.map(read_file)
.transpose()?;
}
ProvingSystemId::Risc0 => {
vm_program_code = Some(read_file_option(
Expand Down
1 change: 1 addition & 0 deletions docs/1_introduction/1_try_aligned.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ aligned submit \
--proving_system SP1 \
--proof ~/.aligned/test_files/sp1_fibonacci_5_0_0.proof \
--vm_program ~/.aligned/test_files/sp1_fibonacci_5_0_0.elf \
--public_input ~/.aligned/test_files/sp1_fibonacci_5_0_0.pub \
--aligned_verification_data_path ~/.aligned/aligned_verification_data \
--network holesky \
--rpc_url https://ethereum-holesky-rpc.publicnode.com
Expand Down
4 changes: 3 additions & 1 deletion docs/3_guides/0_submitting_proofs.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ aligned submit \
--proving_system SP1 \
--proof <proof_file> \
--vm_program <vm_program_file> \
--public_input <pub_input_file> \
--proof_generator_addr [proof_generator_addr] \
--batch_inclusion_data_directory_path [batch_inclusion_data_directory_path] \
--keystore_path <path_to_ecdsa_keystore> \
Expand All @@ -149,6 +150,7 @@ aligned submit \
--proving_system SP1 \
--proof ./scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof \
--vm_program ./scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf \
--public_input ./scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub \
--keystore_path ~/.aligned_keystore/keystore0 \
--network holesky \
--rpc_url https://ethereum-holesky-rpc.publicnode.com
Expand All @@ -166,7 +168,7 @@ aligned submit \
--proving_system Risc0 \
--proof <proof_file> \
--vm_program <vm_program_file> \
--pub_input <pub_input_file> \
--public_input <pub_input_file> \
--proof_generator_addr [proof_generator_addr] \
--batch_inclusion_data_directory_path [batch_inclusion_data_directory_path] \
--keystore_path <path_to_ecdsa_keystore> \
Expand Down
2 changes: 1 addition & 1 deletion operator/pkg/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ func (o *Operator) verify(verificationData VerificationData, disabledVerifiersBi
results <- verificationResult

case common.SP1:
verificationResult, err := sp1.VerifySp1Proof(verificationData.Proof, verificationData.VmProgramCode)
verificationResult, err := sp1.VerifySp1Proof(verificationData.Proof, verificationData.PubInput, verificationData.VmProgramCode)
o.Logger.Infof("SP1 proof verification result: %t", verificationResult)
o.handleVerificationResult(results, verificationResult, err, "SP1 proof verification")

Expand Down
3 changes: 2 additions & 1 deletion operator/sp1/lib/sp1.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
#include <stdint.h>

int32_t verify_sp1_proof_ffi(unsigned char *proof_buffer, uint32_t proof_len,
unsigned char *elf_buffer, uint32_t elf_len);
unsigned char *public_inputs_buffer, uint32_t public_inputs_len,
unsigned char *elf_buffer, uint32_t elf_len);
26 changes: 20 additions & 6 deletions operator/sp1/lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use lazy_static::lazy_static;
use log::error;
use sp1_sdk::{ProverClient, EnvProver};
use log::{error, warn};
use sp1_sdk::{ProverClient, EnvProver, SP1ProofWithPublicValues};

lazy_static! {
static ref PROVER_CLIENT: EnvProver = ProverClient::from_env();
Expand All @@ -9,6 +9,8 @@ lazy_static! {
fn inner_verify_sp1_proof_ffi(
proof_bytes: *const u8,
proof_len: u32,
public_inputs_bytes: *const u8,
public_inputs_len: u32,
elf_bytes: *const u8,
elf_len: u32,
) -> bool {
Expand All @@ -23,10 +25,15 @@ fn inner_verify_sp1_proof_ffi(
}

let proof_bytes = unsafe { std::slice::from_raw_parts(proof_bytes, proof_len as usize) };

let public_inputs_bytes =
unsafe { std::slice::from_raw_parts(public_inputs_bytes, public_inputs_len as usize) };
let elf_bytes = unsafe { std::slice::from_raw_parts(elf_bytes, elf_len as usize) };

if let Ok(proof) = bincode::deserialize(proof_bytes) {
if let Ok(proof) = bincode::deserialize::<SP1ProofWithPublicValues>(proof_bytes) {
if *proof.public_values.as_slice() != *public_inputs_bytes {
warn!("SP1 public inputs do not match proof public values");
return false;
}
let (_pk, vk) = PROVER_CLIENT.setup(elf_bytes);
return PROVER_CLIENT.verify(&proof, &vk).is_ok();
}
Expand All @@ -38,11 +45,13 @@ fn inner_verify_sp1_proof_ffi(
pub extern "C" fn verify_sp1_proof_ffi(
proof_bytes: *const u8,
proof_len: u32,
public_inputs_bytes: *const u8,
public_inputs_len: u32,
elf_bytes: *const u8,
elf_len: u32,
) -> i32 {
let result = std::panic::catch_unwind(|| {
inner_verify_sp1_proof_ffi(proof_bytes, proof_len, elf_bytes, elf_len)
inner_verify_sp1_proof_ffi(proof_bytes, proof_len, public_inputs_bytes, public_inputs_len, elf_bytes, elf_len)
});

match result {
Expand All @@ -56,26 +65,31 @@ mod tests {
use super::*;

const PROOF: &[u8] = include_bytes!("../../../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof");
const PUBLIC_INPUTS: &[u8] = include_bytes!("../../../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub");
const ELF: &[u8] = include_bytes!("../../../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf");

#[test]
fn verify_sp1_proof_with_elf_works() {
let proof_bytes = PROOF.as_ptr();
let public_inputs_bytes = PUBLIC_INPUTS.as_ptr();
let elf_bytes = ELF.as_ptr();

let result =
verify_sp1_proof_ffi(proof_bytes, PROOF.len() as u32, elf_bytes, ELF.len() as u32);
verify_sp1_proof_ffi(proof_bytes, PROOF.len() as u32, public_inputs_bytes, PUBLIC_INPUTS.len() as u32, elf_bytes, ELF.len() as u32);
assert_eq!(result, 1)
}

#[test]
fn verify_sp1_aborts_with_bad_proof() {
let proof_bytes = PROOF.as_ptr();
let public_inputs_bytes = PUBLIC_INPUTS.as_ptr();
let elf_bytes = ELF.as_ptr();

let result = verify_sp1_proof_ffi(
proof_bytes,
(PROOF.len() - 1) as u32,
public_inputs_bytes,
PUBLIC_INPUTS.len() as u32,
elf_bytes,
ELF.len() as u32,
);
Expand Down
11 changes: 9 additions & 2 deletions operator/sp1/sp1.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"unsafe"
)

func VerifySp1Proof(proofBuffer []byte, elfBuffer []byte) (isVerified bool, err error) {
func VerifySp1Proof(proofBuffer []byte, publicInputsBuffer []byte, elfBuffer []byte) (isVerified bool, err error) {
// Here we define the return value on failure
isVerified = false
err = nil
Expand All @@ -29,9 +29,16 @@ func VerifySp1Proof(proofBuffer []byte, elfBuffer []byte) (isVerified bool, err
}()

proofPtr := (*C.uchar)(unsafe.Pointer(&proofBuffer[0]))
//publicInputsPtr := (*C.uchar)(unsafe.Pointer(&publicInputsBuffer[0]))
Comment thread
MauroToscano marked this conversation as resolved.
Outdated
elfPtr := (*C.uchar)(unsafe.Pointer(&elfBuffer[0]))

r := (C.int32_t)(C.verify_sp1_proof_ffi(proofPtr, (C.uint32_t)(len(proofBuffer)), elfPtr, (C.uint32_t)(len(elfBuffer))))
r := (C.int32_t)(0)
if len(publicInputsBuffer) == 0 { // allow empty public inputs
r = (C.int32_t)(C.verify_sp1_proof_ffi(proofPtr, (C.uint32_t)(len(proofBuffer)), nil, (C.uint32_t)(0), elfPtr, (C.uint32_t)(len(elfBuffer))))
} else {
publicInputsPtr := (*C.uchar)(unsafe.Pointer(&publicInputsBuffer[0]))
r = (C.int32_t)(C.verify_sp1_proof_ffi(proofPtr, (C.uint32_t)(len(proofBuffer)), publicInputsPtr, (C.uint32_t)(len(publicInputsBuffer)), elfPtr, (C.uint32_t)(len(elfBuffer))))
}

if r == -1 {
err = fmt.Errorf("panic happened on FFI while verifying sp1 proof")
Expand Down
9 changes: 7 additions & 2 deletions operator/sp1/sp1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

const ProofFilePath = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof"

const PublicInputsFilePath = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub"
const ElfFilePath = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf"

func TestFibonacciSp1ProofVerifies(t *testing.T) {
Expand All @@ -17,12 +17,17 @@ func TestFibonacciSp1ProofVerifies(t *testing.T) {
t.Errorf("could not open proof file: %s", err)
}

publicInputsBytes, err := os.ReadFile(PublicInputsFilePath)
if err != nil {
t.Errorf("could not open public inputs file: %s", err)
}

elfBytes, err := os.ReadFile(ElfFilePath)
if err != nil {
t.Errorf("could not open elf file: %s", err)
}

verified, err := sp1.VerifySp1Proof(proofBytes, elfBytes)
verified, err := sp1.VerifySp1Proof(proofBytes, publicInputsBytes, elfBytes)
if err != nil || !verified {
t.Errorf("proof did not verify")
}
Expand Down
4 changes: 4 additions & 0 deletions scripts/test_files/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Note: You have to be in the root of the project
make generate_sp1_fibonacci_proof
```

```bash
make generate_sp1_no_public_input_proof
```

## Generate Risc0 Proof

```bash
Expand Down
13 changes: 13 additions & 0 deletions scripts/test_files/sp1/no_public_inputs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Cargo build
script/target

# Cargo config
.cargo

# Profile-guided optimization
/tmp
pgo-data.profdata

# MacOS nuisances
.DS_Store

Loading
Loading