Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ jobs:
RUSTFLAGS: "-C opt-level=3"
run: cargo run --release --package ceno_zkvm --bin e2e -- --platform=ceno examples/target/riscv32im-ceno-zkvm-elf/release/examples/bn254_curve_syscalls

- name: Run uint256_mul_syscall (release)
env:
RUSTFLAGS: "-C opt-level=3"
run: cargo run --release --package ceno_zkvm --bin e2e -- --platform=ceno examples/target/riscv32im-ceno-zkvm-elf/release/examples/uint256_mul_syscall

- name: Install cargo make
run: |
cargo make --version || cargo install cargo-make
Expand Down
58 changes: 45 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 21 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ repository = "https://github.com/scroll-tech/ceno"
version = "0.1.0"

[workspace.dependencies]
ff_ext = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "ff_ext", rev = "v1.0.0-alpha.9" }
mpcs = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "mpcs", rev = "v1.0.0-alpha.9" }
multilinear_extensions = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "multilinear_extensions", rev = "v1.0.0-alpha.9" }
p3 = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "p3", rev = "v1.0.0-alpha.9" }
poseidon = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "poseidon", rev = "v1.0.0-alpha.9" }
sp1-curves = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "sp1-curves", rev = "v1.0.0-alpha.9" }
sumcheck = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "sumcheck", rev = "v1.0.0-alpha.9" }
transcript = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "transcript", rev = "v1.0.0-alpha.9" }
whir = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "whir", rev = "v1.0.0-alpha.9" }
witness = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "witness", rev = "v1.0.0-alpha.9" }
ff_ext = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "ff_ext", rev = "v1.0.0-alpha.11" }
mpcs = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "mpcs", rev = "v1.0.0-alpha.11" }
multilinear_extensions = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "multilinear_extensions", rev = "v1.0.0-alpha.11" }
p3 = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "p3", rev = "v1.0.0-alpha.11" }
poseidon = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "poseidon", rev = "v1.0.0-alpha.11" }
sp1-curves = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "sp1-curves", rev = "v1.0.0-alpha.11" }
sumcheck = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "sumcheck", rev = "v1.0.0-alpha.11" }
transcript = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "transcript", rev = "v1.0.0-alpha.11" }
whir = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "whir", rev = "v1.0.0-alpha.11" }
witness = { git = "https://github.com/scroll-tech/gkr-backend.git", package = "witness", rev = "v1.0.0-alpha.11" }

alloy-primitives = "1.3"
anyhow = { version = "1.0", default-features = false }
Expand Down Expand Up @@ -91,13 +91,14 @@ lto = "thin"
# [patch."ssh://[email protected]/scroll-tech/ceno-gpu.git"]
# ceno_gpu = { path = "../ceno-gpu/cuda_hal", package = "cuda_hal" }

#[patch."https://github.com/scroll-tech/gkr-backend"]
#ff_ext = { path = "../gkr-backend/crates/ff_ext", package = "ff_ext" }
#mpcs = { path = "../gkr-backend/crates/mpcs", package = "mpcs" }
#multilinear_extensions = { path = "../gkr-backend/crates/multilinear_extensions", package = "multilinear_extensions" }
#p3 = { path = "../gkr-backend/crates/p3", package = "p3" }
#poseidon = { path = "../gkr-backend/crates/poseidon", package = "poseidon" }
#sumcheck = { path = "../gkr-backend/crates/sumcheck", package = "sumcheck" }
#transcript = { path = "../gkr-backend/crates/transcript", package = "transcript" }
#whir = { path = "../gkr-backend/crates/whir", package = "whir" }
#witness = { path = "../gkr-backend/crates/witness", package = "witness" }
# [patch."https://github.com/scroll-tech/gkr-backend"]
# ff_ext = { path = "../gkr-backend/crates/ff_ext", package = "ff_ext" }
# mpcs = { path = "../gkr-backend/crates/mpcs", package = "mpcs" }
# multilinear_extensions = { path = "../gkr-backend/crates/multilinear_extensions", package = "multilinear_extensions" }
# p3 = { path = "../gkr-backend/crates/p3", package = "p3" }
# poseidon = { path = "../gkr-backend/crates/poseidon", package = "poseidon" }
# sp1-curves = { path = "../gkr-backend/crates/p3", package = "sp1-curves" }
# sumcheck = { path = "../gkr-backend/crates/sumcheck", package = "sumcheck" }
# transcript = { path = "../gkr-backend/crates/transcript", package = "transcript" }
# whir = { path = "../gkr-backend/crates/whir", package = "whir" }
# witness = { path = "../gkr-backend/crates/witness", package = "witness" }
3 changes: 3 additions & 0 deletions ceno_emul/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ elf = "0.7"
ff_ext.workspace = true
itertools.workspace = true
multilinear_extensions.workspace = true
num.workspace = true
num-derive.workspace = true
num-traits.workspace = true
rrs_lib = { package = "rrs-succinct", version = "0.1.0" }
secp.workspace = true
serde.workspace = true
sp1-curves.workspace = true
strum.workspace = true
strum_macros.workspace = true
substrate-bn.workspace = true
tiny-keccak.workspace = true
tracing.workspace = true
typenum = "1.19.0"

[features]
default = ["forbid_overflow"]
Expand Down
3 changes: 2 additions & 1 deletion ceno_emul/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub use syscalls::{
BLS12381_ADD, BLS12381_DECOMPRESS, BLS12381_DOUBLE, BN254_ADD, BN254_DOUBLE, BN254_FP_ADD,
BN254_FP_MUL, BN254_FP2_ADD, BN254_FP2_MUL, KECCAK_PERMUTE, SECP256K1_ADD,
SECP256K1_DECOMPRESS, SECP256K1_DOUBLE, SECP256R1_ADD, SECP256R1_DECOMPRESS, SECP256R1_DOUBLE,
SHA_EXTEND, SyscallSpec,
SHA_EXTEND, SyscallSpec, UINT256_MUL,
bn254::{
BN254_FP_WORDS, BN254_FP2_WORDS, BN254_POINT_WORDS, Bn254AddSpec, Bn254DoubleSpec,
Bn254Fp2AddSpec, Bn254Fp2MulSpec, Bn254FpAddSpec, Bn254FpMulSpec,
Expand All @@ -38,6 +38,7 @@ pub use syscalls::{
Secp256k1DecompressSpec, Secp256k1DoubleSpec,
},
sha256::{SHA_EXTEND_WORDS, Sha256ExtendSpec},
uint256::{UINT256_WORDS_FIELD_ELEMENT, Uint256MulSpec},
};

pub mod utils;
Expand Down
4 changes: 3 additions & 1 deletion ceno_emul/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod bn254;
pub mod keccak_permute;
pub mod secp256k1;
pub mod sha256;
pub mod uint256;

// Using the same function codes as sp1:
// https://github.com/succinctlabs/sp1/blob/013c24ea2fa15a0e7ed94f7d11a7ada4baa39ab9/crates/core/executor/src/syscalls/code.rs
Expand All @@ -13,7 +14,7 @@ pub use ceno_syscall::{
BLS12381_ADD, BLS12381_DECOMPRESS, BLS12381_DOUBLE, BN254_ADD, BN254_DOUBLE, BN254_FP_ADD,
BN254_FP_MUL, BN254_FP2_ADD, BN254_FP2_MUL, KECCAK_PERMUTE, SECP256K1_ADD,
SECP256K1_DECOMPRESS, SECP256K1_DOUBLE, SECP256R1_ADD, SECP256R1_DECOMPRESS, SECP256R1_DOUBLE,
SHA_EXTEND,
SHA_EXTEND, UINT256_MUL,
};

pub trait SyscallSpec {
Expand Down Expand Up @@ -42,6 +43,7 @@ pub fn handle_syscall(vm: &VMState, function_code: u32) -> Result<SyscallEffects
BN254_FP_MUL => Ok(bn254::bn254_fp_mul(vm)),
BN254_FP2_ADD => Ok(bn254::bn254_fp2_add(vm)),
BN254_FP2_MUL => Ok(bn254::bn254_fp2_mul(vm)),
UINT256_MUL => Ok(uint256::uint256_mul(vm)),
// TODO: introduce error types.
_ => Err(anyhow::anyhow!("Unknown syscall: {}", function_code)),
}
Expand Down
80 changes: 80 additions & 0 deletions ceno_emul/src/syscalls/uint256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::{
Change, EmuContext, Platform, SyscallSpec, VMState, WriteOp,
syscalls::{SyscallEffects, SyscallWitness},
utils::MemoryView,
};

use itertools::Itertools;
use num::{BigUint, One, Zero};
use sp1_curves::{
params::NumWords,
uint256::U256Field,
utils::{biguint_from_words, biguint_to_words},
};
use typenum::marker_traits::Unsigned;

type WordsFieldElement = <U256Field as NumWords>::WordsFieldElement;
pub const UINT256_WORDS_FIELD_ELEMENT: usize = WordsFieldElement::USIZE;

pub struct Uint256MulSpec;

impl SyscallSpec for Uint256MulSpec {
const NAME: &'static str = "UINT256_MUL";

const REG_OPS_COUNT: usize = 2;
const MEM_OPS_COUNT: usize = 3 * UINT256_WORDS_FIELD_ELEMENT; // x, y, modulus
const CODE: u32 = ceno_syscall::UINT256_MUL;
}

pub fn uint256_mul(vm: &VMState) -> SyscallEffects {
let x_ptr = vm.peek_register(Platform::reg_arg0());
let y_ptr = vm.peek_register(Platform::reg_arg1());

// Read the argument pointers
let reg_ops = vec![
WriteOp::new_register_op(
Platform::reg_arg0(),
Change::new(x_ptr, x_ptr),
0, // Cycle set later in finalize().
),
WriteOp::new_register_op(
Platform::reg_arg1(),
Change::new(y_ptr, y_ptr),
0, // Cycle set later in finalize().
),
];

// Memory segments of x, y, and modulus
let mut x_view = MemoryView::<UINT256_WORDS_FIELD_ELEMENT>::new(vm, x_ptr);
let y_and_modulus_view = MemoryView::<{ UINT256_WORDS_FIELD_ELEMENT * 2 }>::new(vm, y_ptr);

// Read x, y, and modulus from words via wrapper type
let x = biguint_from_words(&x_view.words());
let y = biguint_from_words(&y_and_modulus_view.words()[..UINT256_WORDS_FIELD_ELEMENT]);
let modulus = biguint_from_words(&y_and_modulus_view.words()[UINT256_WORDS_FIELD_ELEMENT..]);

// Perform the multiplication and take the result modulo the modulus.
let result: BigUint = if modulus.is_zero() {
let modulus = BigUint::one() << 256;
(x * y) % modulus
} else {
(x * y) % modulus
};

// Convert the result to little endian u32 words.
let result_words = biguint_to_words(&result, UINT256_WORDS_FIELD_ELEMENT)
.try_into()
.unwrap();
x_view.write(result_words);

let mem_ops = x_view
.mem_ops()
.into_iter()
.chain(y_and_modulus_view.mem_ops())
.collect_vec();

SyscallEffects {
witness: SyscallWitness::new(mem_ops, reg_ops),
next_pc: None,
}
}
Loading