Skip to content

Commit

Permalink
fix: k256 decompress (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
ctian1 authored Feb 12, 2024
1 parent 7f229e2 commit 802e2ba
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 47 deletions.
20 changes: 20 additions & 0 deletions core/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,20 @@ impl CurtaStdin {
self.buffer.read()
}

/// Read a slice of bytes from the buffer.
pub fn read_slice(&mut self, slice: &mut [u8]) {
self.buffer.read_slice(slice);
}

/// Write a value to the buffer.
pub fn write<T: Serialize + DeserializeOwned>(&mut self, data: &T) {
self.buffer.write(data);
}

/// Write a slice of bytes to the buffer.
pub fn write_slice(&mut self, slice: &[u8]) {
self.buffer.write_slice(slice);
}
}

impl CurtaStdout {
Expand All @@ -62,10 +72,20 @@ impl CurtaStdout {
self.buffer.read()
}

/// Read a slice of bytes from the buffer.
pub fn read_slice(&mut self, slice: &mut [u8]) {
self.buffer.read_slice(slice);
}

/// Write a value to the buffer.
pub fn write<T: Serialize + DeserializeOwned>(&mut self, data: &T) {
self.buffer.write(data);
}

/// Write a slice of bytes to the buffer.
pub fn write_slice(&mut self, slice: &[u8]) {
self.buffer.write_slice(slice);
}
}

pub fn serialize_proof<S, SC: StarkGenericConfig + Serialize>(
Expand Down
2 changes: 1 addition & 1 deletion core/src/stark/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ where

#[cfg(not(feature = "perf"))]
return ShardProof {
main_commit: main_data.main_commit.clone(),
main_commit: shard_data.main_commit.clone(),
traces,
permutation_traces,
chip_ids: chips.iter().map(|chip| chip.name()).collect::<Vec<_>>(),
Expand Down
35 changes: 13 additions & 22 deletions core/src/syscall/precompiles/k256/decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,23 +251,19 @@ impl<V: Copy> K256DecompressCols<V> {
// Interpret the lowest bit of Y as whether it is odd or not.
let y_is_odd = self.y_least_bits[0];

// When y_is_odd == should_be_odd, the result is y, otherwise it is -y.
// When y_is_odd == should_be_odd, result is y
// Equivalent: y_is_odd != !should_be_odd
let y_limbs = limbs_from_access(&self.y_access);
builder
.when(self.is_real)
.when(AB::Expr::one() - (y_is_odd.into() - should_be_odd.clone()))
.when_ne(y_is_odd.into(), AB::Expr::one() - should_be_odd.clone())
.assert_all_eq(self.y.multiplication.result, y_limbs);
// When y_is_odd != should_be_odd, result is -y.
builder
.when(self.is_real)
.when_ne(y_is_odd, should_be_odd)
.assert_all_eq(self.neg_y.result, y_limbs);

// Degree 3 constraint to avoid "OodEvaluationMismatch".
builder.assert_zero(
self.is_real.into() * self.is_real.into() * self.is_real.into()
- self.is_real.into() * self.is_real.into() * self.is_real.into(),
);

for i in 0..NUM_WORDS_FIELD_ELEMENT {
builder.constraint_memory_access(
self.shard,
Expand Down Expand Up @@ -370,35 +366,30 @@ pub mod tests {
use rand::rngs::StdRng;
use rand::SeedableRng;

use crate::utils::setup_logger;
use crate::utils::tests::SECP256K1_DECOMPRESS_ELF;
use crate::utils::BabyBearBlake3;
use crate::{
runtime::{Program, Runtime},
utils::{prove_core, setup_logger},
};
use crate::{CurtaProver, CurtaStdin, CurtaVerifier};

#[test]
fn test_k256_decompress() {
setup_logger();
let mut rng = StdRng::seed_from_u64(2);

for _ in 0..4 {
for _ in 0..10 {
let secret_key = k256::SecretKey::random(&mut rng);
let public_key = secret_key.public_key();
let encoded = public_key.to_encoded_point(false);
let decompressed = encoded.as_bytes();
let compressed = public_key.to_sec1_bytes();
let mut result: [u8; 65] = [0; 65];

let program = Program::from(SECP256K1_DECOMPRESS_ELF);
let mut runtime = Runtime::new(program);
runtime.write_stdin_slice(&compressed);
runtime.run();
runtime.read_stdout_slice(&mut result);
let inputs = CurtaStdin::from(&compressed);

let mut proof = CurtaProver::prove(SECP256K1_DECOMPRESS_ELF, inputs).unwrap();
let mut result = [0; 65];
proof.stdout.read_slice(&mut result);
assert_eq!(result, decompressed);
let config = BabyBearBlake3::new();
prove_core(config, &mut runtime);

CurtaVerifier::verify(SECP256K1_DECOMPRESS_ELF, &proof).unwrap();
}
}
}
11 changes: 11 additions & 0 deletions core/src/utils/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct Buffer {
pub data: Vec<u8>,
#[serde(skip)]
pub ptr: usize,
}

Expand Down Expand Up @@ -36,10 +37,20 @@ impl Buffer {
result
}

pub fn read_slice(&mut self, slice: &mut [u8]) {
slice.copy_from_slice(&self.data[self.ptr..self.ptr + slice.len()]);
self.ptr += slice.len();
}

/// Write the serializable object from the buffer.
pub fn write<T: Serialize + DeserializeOwned>(&mut self, data: &T) {
let mut tmp = Vec::new();
bincode::serialize_into(&mut tmp, data).expect("serialization failed");
self.data.extend(tmp);
}

/// Write the slice of bytes to the buffer.
pub fn write_slice(&mut self, slice: &[u8]) {
self.data.extend_from_slice(slice);
}
}
24 changes: 0 additions & 24 deletions core/src/utils/prove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ pub trait StarkUtils: StarkGenericConfig {
fn uni_stark_config(&self) -> &Self::UniConfig;
}

#[cfg(not(feature = "perf"))]
use crate::lookup::{debug_interactions_with_all_chips, InteractionKind};

pub fn get_cycles(program: Program) -> u64 {
let mut runtime = Runtime::new(program);
runtime.run();
Expand Down Expand Up @@ -102,10 +99,6 @@ where
let machine = RiscvStark::new(config);
let (pk, _) = machine.setup(runtime.program.as_ref());

// Because proving modifies the shard, clone beforehand if we debug interactions.
#[cfg(not(feature = "perf"))]
let shard = runtime.record.clone();

// Prove the program.
let proof = tracing::info_span!("runtime.prove(...)")
.in_scope(|| machine.prove::<LocalProver<_>>(&pk, &mut runtime.record, &mut challenger));
Expand All @@ -121,23 +114,6 @@ where
Size::from_bytes(nb_bytes),
);

#[cfg(not(feature = "perf"))]
tracing::info_span!("debug interactions with all chips").in_scope(|| {
debug_interactions_with_all_chips(
&machine.chips(),
&shard,
vec![
InteractionKind::Field,
InteractionKind::Range,
InteractionKind::Byte,
InteractionKind::Alu,
InteractionKind::Memory,
InteractionKind::Program,
InteractionKind::Instruction,
],
);
});

proof
}

Expand Down

0 comments on commit 802e2ba

Please sign in to comment.