diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index ffe95c546..ff4831ea2 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -157,6 +157,16 @@ 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/secp256k1_scalar_algebra + - name: Run p256 verify hash (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/secp256r1_verify_prehash + + - name: Run p256 scalar algebra (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/secp256r1_scalar_algebra + - name: Run uint256_mul_syscall (release) env: RUSTFLAGS: "-C opt-level=3" diff --git a/Cargo.lock b/Cargo.lock index 3fc4bb335..be858ab57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -934,10 +934,10 @@ dependencies = [ "ceno_zkvm", "clap", "console", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "get_dir", "gkr_iop", - "mpcs 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "mpcs", "openvm-circuit", "openvm-continuations", "openvm-cuda-backend", @@ -1028,6 +1028,7 @@ dependencies = [ "ceno_sha2", "ceno_syscall", "k256 0.13.4 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", + "p256 0.13.2 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", "revm-precompile", "substrate-bn 0.6.0 (git+https://github.com/scroll-tech/bn?branch=ceno)", "thiserror 2.0.12", @@ -1036,7 +1037,7 @@ dependencies = [ [[package]] name = "ceno_crypto_primitives" version = "0.1.0" -source = "git+https://github.com/scroll-tech/ceno-patch.git?branch=main#0cb2c93e02e2e859e55d5d889ca8abd0a13b13be" +source = "git+https://github.com/scroll-tech/ceno-patch.git?branch=main#bc61dbd54f5cc58af6f8300997aa0d1ac9de1527" dependencies = [ "ceno_syscall", "elliptic-curve", @@ -1050,14 +1051,15 @@ dependencies = [ "ceno_rt", "ceno_syscall", "elf", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.13.0", "k256 0.13.4 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "multilinear_extensions", "num", "num-derive", "num-traits", "once_cell", + "p256 0.13.2 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", "rayon", "rrs-succinct", "rustc-hash", @@ -1105,11 +1107,11 @@ dependencies = [ "ceno_host", "ceno_zkvm", "clap", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "gkr_iop", "itertools 0.13.0", - "mpcs 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "mpcs", + "multilinear_extensions", "openvm", "openvm-circuit", "openvm-continuations", @@ -1123,18 +1125,18 @@ dependencies = [ "openvm-sdk", "openvm-stark-backend", "openvm-stark-sdk", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "parse-size", "rand 0.8.5", "serde", "serde_json", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "sumcheck", "tracing", "tracing-forest", "tracing-subscriber", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "whir 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "transcript", + "whir", + "witness", ] [[package]] @@ -1167,7 +1169,7 @@ dependencies = [ [[package]] name = "ceno_syscall" version = "0.1.0" -source = "git+https://github.com/scroll-tech/ceno-patch.git?branch=main#0cb2c93e02e2e859e55d5d889ca8abd0a13b13be" +source = "git+https://github.com/scroll-tech/ceno-patch.git?branch=main#bc61dbd54f5cc58af6f8300997aa0d1ac9de1527" [[package]] name = "ceno_zkvm" @@ -1186,20 +1188,20 @@ dependencies = [ "cudarc", "derive", "either", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "generic-array 1.2.0", "generic_static", "gkr_iop", "glob", "itertools 0.13.0", "metrics", - "mpcs 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "mpcs", + "multilinear_extensions", "ndarray", "num", "num-bigint 0.4.6", "once_cell", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "parse-size", "pprof2", "prettytable-rs", @@ -1213,7 +1215,7 @@ dependencies = [ "sp1-curves", "strum", "strum_macros", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "sumcheck", "tempfile", "tikv-jemalloc-ctl", "tikv-jemallocator", @@ -1221,10 +1223,10 @@ dependencies = [ "tracing", "tracing-forest", "tracing-subscriber", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "transcript", "typenum", - "whir 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "whir", + "witness", ] [[package]] @@ -1574,22 +1576,7 @@ checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cuda_hal" version = "0.1.0" -source = "git+https://github.com/scroll-tech/ceno-gpu-mock.git?branch=main#802928096212ecb1d7347922bc13526ea63e1b01" -dependencies = [ - "anyhow", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "itertools 0.13.0", - "mpcs 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rand 0.8.5", - "rayon", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "thiserror 2.0.12", - "tracing", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", -] +source = "git+https://github.com/scroll-tech/ceno-gpu-mock.git?branch=main#fe8f7923b7d3a3823c27949fab0aab8e31011aa9" [[package]] name = "cudarc" @@ -2135,6 +2122,7 @@ dependencies = [ "ceno_syscall", "getrandom 0.3.2", "k256 0.13.4 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", + "p256 0.13.2 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", "rand 0.8.5", "revm-precompile", "substrate-bn 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2219,24 +2207,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "ff_ext" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "once_cell", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rand_core 0.6.4", - "serde", -] - [[package]] name = "ff_ext" version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ "once_cell", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "rand_core 0.6.4", "serde", ] @@ -2403,18 +2380,18 @@ dependencies = [ "cuda_hal", "cudarc", "either", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.13.0", - "mpcs 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "mpcs", + "multilinear_extensions", "once_cell", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "rand 0.8.5", "rayon", "serde", "strum", "strum_macros", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "sumcheck", "thiserror 2.0.12", "thread_local", "tikv-jemalloc-ctl", @@ -2422,8 +2399,8 @@ dependencies = [ "tracing", "tracing-forest", "tracing-subscriber", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "transcript", + "witness", ] [[package]] @@ -3000,7 +2977,7 @@ dependencies = [ [[package]] name = "k256" version = "0.13.4" -source = "git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4#05a8a81ef6300ff8bbf1d810b018bbeb71ab947c" +source = "git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4#e7c4aaa5f44b20ff948292510ed28c4e0a567211" dependencies = [ "ceno_crypto_primitives", "ceno_syscall", @@ -3234,30 +3211,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "mpcs" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "bincode 1.3.3", - "clap", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "itertools 0.13.0", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "num-integer", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rayon", - "serde", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "tracing", - "tracing-subscriber", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "whir 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", -] - [[package]] name = "mpcs" version = "0.1.0" @@ -3265,36 +3218,21 @@ source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19 dependencies = [ "bincode 1.3.3", "clap", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.13.0", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "multilinear_extensions", "num-integer", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", "serde", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "sumcheck", "tracing", "tracing-subscriber", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "whir 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", -] - -[[package]] -name = "multilinear_extensions" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "either", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "itertools 0.13.0", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rand 0.8.5", - "rayon", - "serde", - "tracing", + "transcript", + "whir", + "witness", ] [[package]] @@ -3303,9 +3241,9 @@ version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ "either", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.13.0", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "rand 0.8.5", "rayon", "serde", @@ -4568,33 +4506,21 @@ checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve", - "primeorder", + "primeorder 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", "sha2", ] [[package]] -name = "p3" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" +name = "p256" +version = "0.13.2" +source = "git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4#e7c4aaa5f44b20ff948292510ed28c4e0a567211" dependencies = [ - "p3-air", - "p3-baby-bear", - "p3-challenger", - "p3-commit", - "p3-dft", - "p3-field", - "p3-fri", - "p3-goldilocks", - "p3-matrix", - "p3-maybe-rayon", - "p3-mds", - "p3-merkle-tree", - "p3-monty-31", - "p3-poseidon", - "p3-poseidon2", - "p3-poseidon2-air", - "p3-symmetric", - "p3-util", + "ceno_crypto_primitives", + "ceno_syscall", + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve", + "primeorder 0.13.6 (git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4)", + "sha2", ] [[package]] @@ -5165,23 +5091,13 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "poseidon" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "serde", -] - [[package]] name = "poseidon" version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", + "p3", "serde", ] @@ -5255,6 +5171,14 @@ dependencies = [ "elliptic-curve", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "git+https://github.com/scroll-tech/elliptic-curves?branch=ceno%2Fk256-13.4#e7c4aaa5f44b20ff948292510ed28c4e0a567211" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -5602,7 +5526,7 @@ dependencies = [ "aurora-engine-modexp", "cfg-if", "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", - "p256", + "p256 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "revm-primitives", "ripemd", "sha2", @@ -6131,13 +6055,13 @@ dependencies = [ "cfg-if", "dashu", "elliptic-curve", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "generic-array 1.2.0", "itertools 0.13.0", "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "multilinear_extensions", "num", - "p256", + "p256 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "p3-field", "rug", "serde", @@ -6248,53 +6172,22 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "sumcheck" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "either", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "itertools 0.13.0", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rayon", - "serde", - "sumcheck_macro 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "thiserror 1.0.69", - "tracing", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", -] - [[package]] name = "sumcheck" version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ "either", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.13.0", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "multilinear_extensions", + "p3", "rayon", "serde", - "sumcheck_macro 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "sumcheck_macro", "thiserror 1.0.69", "tracing", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", -] - -[[package]] -name = "sumcheck_macro" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "itertools 0.13.0", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "proc-macro2", - "quote", - "rand 0.8.5", - "syn 2.0.101", + "transcript", ] [[package]] @@ -6303,7 +6196,7 @@ version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ "itertools 0.13.0", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", "proc-macro2", "quote", "rand 0.8.5", @@ -6704,26 +6597,15 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transcript" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "itertools 0.13.0", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "poseidon 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", -] - [[package]] name = "transcript" version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.13.0", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "poseidon 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "p3", + "poseidon", ] [[package]] @@ -7009,29 +6891,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "whir" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "bincode 1.3.3", - "clap", - "derive_more 1.0.0", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "itertools 0.14.0", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rayon", - "serde", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "tracing", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "transpose", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", -] - [[package]] name = "whir" version = "0.1.0" @@ -7040,19 +6899,19 @@ dependencies = [ "bincode 1.3.3", "clap", "derive_more 1.0.0", - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", "itertools 0.14.0", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "multilinear_extensions", + "p3", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", "serde", - "sumcheck 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "sumcheck", "tracing", - "transcript 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "transcript", "transpose", - "witness 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "witness", ] [[package]] @@ -7319,27 +7178,14 @@ dependencies = [ "bitflags", ] -[[package]] -name = "witness" -version = "0.1.0" -source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15#9be620b18900138d0b89569759fc2b3b9451b49e" -dependencies = [ - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.15)", - "rand 0.8.5", - "rayon", - "tracing", -] - [[package]] name = "witness" version = "0.1.0" source = "git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19#eb292fef68831ba85e6553a56cacbf770ea9d122" dependencies = [ - "ff_ext 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "multilinear_extensions 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", - "p3 0.1.0 (git+https://github.com/scroll-tech/gkr-backend.git?tag=v1.0.0-alpha.19)", + "ff_ext", + "multilinear_extensions", + "p3", "rand 0.8.5", "rayon", "tracing", diff --git a/ceno_emul/Cargo.toml b/ceno_emul/Cargo.toml index a0c0ef8fc..8c3d56a42 100644 --- a/ceno_emul/Cargo.toml +++ b/ceno_emul/Cargo.toml @@ -26,6 +26,7 @@ rrs_lib = { package = "rrs-succinct", version = "0.1.0" } rustc-hash.workspace = true # TODO clean up secp and only use k256 from elliptic-curves k256 = { git = "https://github.com/scroll-tech/elliptic-curves", branch = "ceno/k256-13.4", default-features = false, features = ["std", "ecdsa"] } +p256 = { git = "https://github.com/scroll-tech/elliptic-curves", branch = "ceno/k256-13.4", default-features = false, features = ["std", "ecdsa", "arithmetic"] } secp = { workspace = true } serde.workspace = true smallvec.workspace = true diff --git a/ceno_emul/src/lib.rs b/ceno_emul/src/lib.rs index 18f3f5953..c5d901d40 100644 --- a/ceno_emul/src/lib.rs +++ b/ceno_emul/src/lib.rs @@ -32,7 +32,8 @@ 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, SECP256K1_SCALAR_INVERT, SECP256R1_ADD, - SECP256R1_DECOMPRESS, SECP256R1_DOUBLE, SHA_EXTEND, SyscallSpec, UINT256_MUL, + SECP256R1_DECOMPRESS, SECP256R1_DOUBLE, SECP256R1_SCALAR_INVERT, SHA_EXTEND, SyscallSpec, + UINT256_MUL, bn254::{ BN254_FP_WORDS, BN254_FP2_WORDS, BN254_POINT_WORDS, Bn254AddSpec, Bn254DoubleSpec, Bn254Fp2AddSpec, Bn254Fp2MulSpec, Bn254FpAddSpec, Bn254FpMulSpec, @@ -43,6 +44,10 @@ pub use syscalls::{ COORDINATE_WORDS as SECP256K1_COORDINATE_WORDS, SECP256K1_ARG_WORDS, Secp256k1AddSpec, Secp256k1DecompressSpec, Secp256k1DoubleSpec, Secp256k1ScalarInvertSpec, }, + secp256r1::{ + COORDINATE_WORDS as SECP256R1_COORDINATE_WORDS, SECP256R1_ARG_WORDS, Secp256r1AddSpec, + Secp256r1DoubleSpec, Secp256r1ScalarInvertSpec, + }, sha256::{SHA_EXTEND_WORDS, Sha256ExtendSpec}, uint256::{UINT256_WORDS_FIELD_ELEMENT, Uint256MulSpec}, }; diff --git a/ceno_emul/src/syscalls.rs b/ceno_emul/src/syscalls.rs index 6eb33e059..5d9674fc6 100644 --- a/ceno_emul/src/syscalls.rs +++ b/ceno_emul/src/syscalls.rs @@ -5,6 +5,7 @@ pub mod bn254; pub mod keccak_permute; pub mod phantom; pub mod secp256k1; +pub(crate) mod secp256r1; pub mod sha256; pub mod uint256; // Using the same function codes as sp1: @@ -14,7 +15,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, PHANTOM_LOG_PC_CYCLE, SECP256K1_ADD, SECP256K1_DECOMPRESS, SECP256K1_DOUBLE, SECP256K1_SCALAR_INVERT, SECP256R1_ADD, - SECP256R1_DECOMPRESS, SECP256R1_DOUBLE, SHA_EXTEND, UINT256_MUL, + SECP256R1_DECOMPRESS, SECP256R1_DOUBLE, SECP256R1_SCALAR_INVERT, SHA_EXTEND, UINT256_MUL, }; pub trait SyscallSpec { @@ -37,6 +38,9 @@ pub fn handle_syscall(vm: &VMState, function_code: u32) -> Result< SECP256K1_DOUBLE => Ok(secp256k1::secp256k1_double(vm)), SECP256K1_DECOMPRESS => Ok(secp256k1::secp256k1_decompress(vm)), SECP256K1_SCALAR_INVERT => Ok(secp256k1::secp256k1_invert(vm)), + SECP256R1_ADD => Ok(secp256r1::secp256r1_add(vm)), + SECP256R1_DOUBLE => Ok(secp256r1::secp256r1_double(vm)), + SECP256R1_SCALAR_INVERT => Ok(secp256r1::secp256r1_invert(vm)), SHA_EXTEND => Ok(sha256::extend(vm)), BN254_ADD => Ok(bn254::bn254_add(vm)), BN254_DOUBLE => Ok(bn254::bn254_double(vm)), diff --git a/ceno_emul/src/syscalls/secp256r1.rs b/ceno_emul/src/syscalls/secp256r1.rs new file mode 100644 index 000000000..40ff092d6 --- /dev/null +++ b/ceno_emul/src/syscalls/secp256r1.rs @@ -0,0 +1,242 @@ +use super::{SyscallEffects, SyscallSpec, SyscallWitness}; +use crate::{ + Change, EmuContext, Platform, Tracer, VMState, WORD_SIZE, Word, WriteOp, utils::MemoryView, +}; +use itertools::Itertools; +use p256::{ + AffinePoint, EncodedPoint, FieldBytes, ProjectivePoint, Scalar, + elliptic_curve::{ + PrimeField, + group::Group, + sec1::{Coordinates, FromEncodedPoint, ToEncodedPoint}, + }, +}; + +pub struct Secp256r1AddSpec; + +pub struct Secp256r1DoubleSpec; + +pub struct Secp256r1ScalarInvertSpec; + +impl SyscallSpec for Secp256r1AddSpec { + const NAME: &'static str = "SECP256R1_ADD"; + + const REG_OPS_COUNT: usize = 2; + const MEM_OPS_COUNT: usize = 2 * SECP256R1_ARG_WORDS; + const CODE: u32 = ceno_syscall::SECP256R1_ADD; +} + +impl SyscallSpec for Secp256r1DoubleSpec { + const NAME: &'static str = "SECP256R1_DOUBLE"; + + const REG_OPS_COUNT: usize = 1; + const MEM_OPS_COUNT: usize = SECP256R1_ARG_WORDS; + const CODE: u32 = ceno_syscall::SECP256R1_DOUBLE; +} + +impl SyscallSpec for Secp256r1ScalarInvertSpec { + const NAME: &'static str = "SECP256R1_SCALAR_INVERT"; + + const REG_OPS_COUNT: usize = 1; + const MEM_OPS_COUNT: usize = COORDINATE_WORDS; + const CODE: u32 = ceno_syscall::SECP256R1_SCALAR_INVERT; +} + +// A secp256r1 point in uncompressed form takes 64 bytes +pub const SECP256R1_ARG_WORDS: usize = 16; + +/// Wrapper type for a point on the secp256r1 curve that implements conversions +/// from and to VM word-representations according to the syscall spec +pub struct SecpPoint(pub AffinePoint); + +impl From<[Word; SECP256R1_ARG_WORDS]> for SecpPoint { + fn from(words: [Word; SECP256R1_ARG_WORDS]) -> Self { + if words.iter().all(|&word| word == 0) { + return SecpPoint(AffinePoint::IDENTITY); + } + + let x_words: [Word; COORDINATE_WORDS] = words[..COORDINATE_WORDS] + .try_into() + .expect("invalid point words"); + let y_words: [Word; COORDINATE_WORDS] = words[COORDINATE_WORDS..] + .try_into() + .expect("invalid point words"); + + let mut x_bytes = SecpCoordinate::from(x_words).0; + let mut y_bytes = SecpCoordinate::from(y_words).0; + x_bytes.reverse(); + y_bytes.reverse(); + + let encoded = EncodedPoint::from_affine_coordinates( + FieldBytes::from_slice(&x_bytes), + FieldBytes::from_slice(&y_bytes), + false, + ); + + let point = Option::from(AffinePoint::from_encoded_point(&encoded)) + .expect("illegal secp256r1 point"); + SecpPoint(point) + } +} + +impl From for [Word; SECP256R1_ARG_WORDS] { + fn from(point: SecpPoint) -> [Word; SECP256R1_ARG_WORDS] { + if bool::from(point.0.is_identity()) { + return [0; SECP256R1_ARG_WORDS]; + } + + let encoded = point.0.to_encoded_point(false); + let (x, y) = match encoded.coordinates() { + Coordinates::Uncompressed { x, y } => (x, y), + _ => panic!("unexpected coordinate encoding"), + }; + + let mut x_bytes = [0u8; COORDINATE_WORDS * WORD_SIZE]; + x_bytes.copy_from_slice(x.as_slice()); + x_bytes.reverse(); + + let mut y_bytes = [0u8; COORDINATE_WORDS * WORD_SIZE]; + y_bytes.copy_from_slice(y.as_slice()); + y_bytes.reverse(); + + let x_words: [Word; COORDINATE_WORDS] = SecpCoordinate(x_bytes).into(); + let y_words: [Word; COORDINATE_WORDS] = SecpCoordinate(y_bytes).into(); + + let mut words = [0u32; SECP256R1_ARG_WORDS]; + words[..COORDINATE_WORDS].copy_from_slice(&x_words); + words[COORDINATE_WORDS..].copy_from_slice(&y_words); + words + } +} + +/// Trace the execution of a secp256r1_add call +pub fn secp256r1_add(vm: &VMState) -> SyscallEffects { + let p_ptr = vm.peek_register(Platform::reg_arg0()); + let q_ptr = vm.peek_register(Platform::reg_arg1()); + + // Read the argument pointers + let reg_ops = vec![ + WriteOp::new_register_op( + Platform::reg_arg0(), + Change::new(p_ptr, p_ptr), + 0, // Cycle set later in finalize(). + ), + WriteOp::new_register_op( + Platform::reg_arg1(), + Change::new(q_ptr, q_ptr), + 0, // Cycle set later in finalize(). + ), + ]; + + // Memory segments of P and Q + let [mut p_view, q_view] = + [p_ptr, q_ptr].map(|start| MemoryView::<_, SECP256R1_ARG_WORDS>::new(vm, start)); + + // Read P and Q from words via wrapper type + let [p, q] = [&p_view, &q_view].map(|view| SecpPoint::from(view.words())); + + // Compute the sum and convert back to words + let sum = ProjectivePoint::from(p.0) + ProjectivePoint::from(q.0); + let output_words: [Word; SECP256R1_ARG_WORDS] = SecpPoint(AffinePoint::from(sum)).into(); + + p_view.write(output_words); + + let mem_ops = p_view + .mem_ops() + .into_iter() + .chain(q_view.mem_ops()) + .collect_vec(); + + assert_eq!(mem_ops.len(), 2 * SECP256R1_ARG_WORDS); + SyscallEffects { + witness: SyscallWitness::new(mem_ops, reg_ops), + next_pc: None, + } +} + +/// Trace the execution of a secp256r1_double call +pub fn secp256r1_double(vm: &VMState) -> SyscallEffects { + let p_ptr = vm.peek_register(Platform::reg_arg0()); + + // Read the argument pointers + let reg_ops = vec![WriteOp::new_register_op( + Platform::reg_arg0(), + Change::new(p_ptr, p_ptr), + 0, // Cycle set later in finalize(). + )]; + + // P's memory segment + let mut p_view = MemoryView::<_, SECP256R1_ARG_WORDS>::new(vm, p_ptr); + // Create point from words via wrapper type + let p = SecpPoint::from(p_view.words()); + + // Compute result and convert back into words + let doubled = ProjectivePoint::from(p.0).double(); + let output_words: [Word; SECP256R1_ARG_WORDS] = SecpPoint(AffinePoint::from(doubled)).into(); + + p_view.write(output_words); + + let mem_ops = p_view.mem_ops().to_vec(); + + assert_eq!(mem_ops.len(), SECP256R1_ARG_WORDS); + SyscallEffects { + witness: SyscallWitness::new(mem_ops, reg_ops), + next_pc: None, + } +} + +pub fn secp256r1_invert(vm: &VMState) -> SyscallEffects { + let p_ptr = vm.peek_register(Platform::reg_arg0()); + + // Read the argument pointers + let reg_ops = vec![WriteOp::new_register_op( + Platform::reg_arg0(), + Change::new(p_ptr, p_ptr), + 0, // Cycle set later in finalize(). + )]; + + // P's memory segment + let mut p_view = MemoryView::<_, COORDINATE_WORDS>::new(vm, p_ptr); + let p = Scalar::from_repr(*FieldBytes::from_slice(&p_view.bytes())).expect("illegal p"); + let p_inv = p.invert().unwrap(); + let bytes: [u8; 32] = p_inv.to_bytes().into(); + let output_words: [Word; COORDINATE_WORDS] = unsafe { std::mem::transmute(bytes) }; + + p_view.write(output_words); + let mem_ops = p_view.mem_ops().to_vec(); + + assert_eq!(mem_ops.len(), COORDINATE_WORDS); + SyscallEffects { + witness: SyscallWitness::new(mem_ops, reg_ops), + next_pc: None, + } +} + +pub const COORDINATE_WORDS: usize = SECP256R1_ARG_WORDS / 2; + +/// Wrapper type for a single coordinate of a point on the secp256r1 curve. +/// It implements conversions from and to VM word-representations according +/// to the spec of syscall +pub struct SecpCoordinate(pub [u8; COORDINATE_WORDS * WORD_SIZE]); + +impl From<[Word; COORDINATE_WORDS]> for SecpCoordinate { + fn from(words: [Word; COORDINATE_WORDS]) -> Self { + let bytes = (words.iter().flat_map(|word| word.to_le_bytes())) + .collect_vec() + .try_into() + .unwrap(); + SecpCoordinate(bytes) + } +} + +impl From for [Word; COORDINATE_WORDS] { + fn from(coord: SecpCoordinate) -> [Word; COORDINATE_WORDS] { + coord + .0 + .chunks_exact(4) + .map(|chunk| Word::from_le_bytes(chunk.try_into().unwrap())) + .collect_vec() + .try_into() + .unwrap() + } +} diff --git a/ceno_zkvm/src/instructions/riscv/ecall.rs b/ceno_zkvm/src/instructions/riscv/ecall.rs index ab1371143..ce4427386 100644 --- a/ceno_zkvm/src/instructions/riscv/ecall.rs +++ b/ceno_zkvm/src/instructions/riscv/ecall.rs @@ -12,7 +12,7 @@ pub use fptower_fp::{FpAddInstruction, FpMulInstruction}; pub use fptower_fp2_add::Fp2AddInstruction; pub use fptower_fp2_mul::Fp2MulInstruction; pub use keccak::KeccakInstruction; -pub use uint256::{Secp256k1InvInstruction, Uint256MulInstruction}; +pub use uint256::{Secp256k1InvInstruction, Secp256r1InvInstruction, Uint256MulInstruction}; pub use weierstrass_add::WeierstrassAddAssignInstruction; pub use weierstrass_decompress::WeierstrassDecompressInstruction; pub use weierstrass_double::WeierstrassDoubleAssignInstruction; diff --git a/ceno_zkvm/src/instructions/riscv/ecall/uint256.rs b/ceno_zkvm/src/instructions/riscv/ecall/uint256.rs index ea7246a6c..b305e7e58 100644 --- a/ceno_zkvm/src/instructions/riscv/ecall/uint256.rs +++ b/ceno_zkvm/src/instructions/riscv/ecall/uint256.rs @@ -1,8 +1,8 @@ use std::marker::PhantomData; use ceno_emul::{ - ByteAddr, Change, Cycle, InsnKind, Platform, SECP256K1_SCALAR_INVERT, StepRecord, UINT256_MUL, - WORD_SIZE, WriteOp, + ByteAddr, Change, Cycle, InsnKind, Platform, SECP256K1_SCALAR_INVERT, SECP256R1_SCALAR_INVERT, + StepRecord, UINT256_MUL, WORD_SIZE, WriteOp, }; use ff_ext::ExtensionField; use generic_array::typenum::Unsigned; @@ -26,6 +26,7 @@ use sp1_curves::{ weierstrass::{ WeierstrassParameters, secp256k1::{Secp256k1, Secp256k1BaseField}, + secp256r1::{Secp256r1, Secp256r1BaseField}, }, }; use witness::{InstancePaddingStrategy, RowMajorMatrix}; @@ -385,6 +386,26 @@ impl Uint256InvSpec for Secp256K1EcallSpec { pub type Secp256k1InvInstruction = Uint256InvInstruction; +pub struct Secp256R1EcallSpec; + +impl Uint256InvSpec for Secp256R1EcallSpec { + type P = Secp256r1BaseField; + + fn syscall() -> u32 { + SECP256R1_SCALAR_INVERT + } + + fn name() -> String { + "secp256r1_scalar_invert".to_string() + } + + fn modulus() -> BigUint { + Secp256r1::prime_group_order() + } +} + +pub type Secp256r1InvInstruction = Uint256InvInstruction; + #[derive(Debug)] pub struct EcallUint256InvConfig { pub layout: Uint256InvLayout, diff --git a/ceno_zkvm/src/instructions/riscv/rv32im.rs b/ceno_zkvm/src/instructions/riscv/rv32im.rs index fff13df5c..01dad68dc 100644 --- a/ceno_zkvm/src/instructions/riscv/rv32im.rs +++ b/ceno_zkvm/src/instructions/riscv/rv32im.rs @@ -21,9 +21,9 @@ use crate::{ div::{DivInstruction, DivuInstruction, RemInstruction, RemuInstruction}, ecall::{ Fp2AddInstruction, Fp2MulInstruction, FpAddInstruction, FpMulInstruction, - KeccakInstruction, Secp256k1InvInstruction, Uint256MulInstruction, - WeierstrassAddAssignInstruction, WeierstrassDecompressInstruction, - WeierstrassDoubleAssignInstruction, + KeccakInstruction, Secp256k1InvInstruction, Secp256r1InvInstruction, + Uint256MulInstruction, WeierstrassAddAssignInstruction, + WeierstrassDecompressInstruction, WeierstrassDoubleAssignInstruction, }, logic::{AndInstruction, OrInstruction, XorInstruction}, logic_imm::{AndiInstruction, OriInstruction, XoriInstruction}, @@ -46,8 +46,8 @@ use ceno_emul::{ Bn254FpMulSpec, InsnKind::{self, *}, KeccakSpec, LogPcCycleSpec, Platform, Secp256k1AddSpec, Secp256k1DecompressSpec, - Secp256k1DoubleSpec, Secp256k1ScalarInvertSpec, Sha256ExtendSpec, StepRecord, SyscallSpec, - Uint256MulSpec, + Secp256k1DoubleSpec, Secp256k1ScalarInvertSpec, Secp256r1AddSpec, Secp256r1DoubleSpec, + Secp256r1ScalarInvertSpec, Sha256ExtendSpec, StepRecord, SyscallSpec, Uint256MulSpec, }; use dummy::LargeEcallDummy; use ecall::EcallDummy; @@ -61,6 +61,7 @@ use sp1_curves::weierstrass::{ SwCurve, bn254::{Bn254, Bn254BaseField}, secp256k1::Secp256k1, + secp256r1::Secp256r1, }; use std::{ cmp::Reverse, @@ -153,6 +154,12 @@ pub struct Rv32imConfig { as Instruction>::InstructionConfig, pub secp256k1_decompress_config: > as Instruction>::InstructionConfig, + pub secp256r1_add_config: + > as Instruction>::InstructionConfig, + pub secp256r1_double_config: + > as Instruction>::InstructionConfig, + pub secp256r1_scalar_invert: + as Instruction>::InstructionConfig, pub uint256_mul_config: as Instruction>::InstructionConfig, @@ -323,6 +330,10 @@ impl Rv32imConfig { let secp256k1_decompress_config = register_ecall_circuit!(WeierstrassDecompressInstruction>, ecall_cells_map); let secp256k1_scalar_invert = register_ecall_circuit!(Secp256k1InvInstruction, ecall_cells_map); + let secp256r1_add_config = register_ecall_circuit!(WeierstrassAddAssignInstruction>, ecall_cells_map); + let secp256r1_double_config = register_ecall_circuit!(WeierstrassDoubleAssignInstruction>, ecall_cells_map); + let secp256r1_scalar_invert = + register_ecall_circuit!(Secp256r1InvInstruction, ecall_cells_map); let uint256_mul_config = register_ecall_circuit!(Uint256MulInstruction, ecall_cells_map); // tables @@ -402,6 +413,9 @@ impl Rv32imConfig { secp256k1_double_config, secp256k1_scalar_invert, secp256k1_decompress_config, + secp256r1_add_config, + secp256r1_double_config, + secp256r1_scalar_invert, uint256_mul_config, // tables dynamic_range_config, @@ -516,6 +530,14 @@ impl Rv32imConfig { cs, &self.secp256k1_decompress_config, ); + fixed.register_opcode_circuit::>>( + cs, + &self.secp256r1_add_config, + ); + fixed.register_opcode_circuit::>>( + cs, + &self.secp256r1_double_config, + ); fixed.register_opcode_circuit::>(cs, &self.uint256_mul_config); // table @@ -560,6 +582,9 @@ impl Rv32imConfig { let mut secp256k1_decompress_records = Vec::new(); let mut uint256_mul_records = Vec::new(); let mut secp256k1_scalar_invert_records = Vec::new(); + let mut secp256r1_add_records = Vec::new(); + let mut secp256r1_double_records = Vec::new(); + let mut secp256r1_scalar_invert_records = Vec::new(); steps.iter().for_each(|record| { let insn_kind = record.insn.kind; match insn_kind { @@ -594,11 +619,22 @@ impl Rv32imConfig { InsnKind::ECALL if record.rs1().unwrap().value == Secp256k1DoubleSpec::CODE => { secp256k1_double_records.push(record); } + InsnKind::ECALL if record.rs1().unwrap().value == Secp256r1AddSpec::CODE => { + secp256r1_add_records.push(record); + } + InsnKind::ECALL if record.rs1().unwrap().value == Secp256r1DoubleSpec::CODE => { + secp256r1_double_records.push(record); + } InsnKind::ECALL if record.rs1().unwrap().value == Secp256k1ScalarInvertSpec::CODE => { secp256k1_scalar_invert_records.push(record); } + InsnKind::ECALL + if record.rs1().unwrap().value == Secp256r1ScalarInvertSpec::CODE => + { + secp256r1_scalar_invert_records.push(record); + } InsnKind::ECALL if record.rs1().unwrap().value == Secp256k1DecompressSpec::CODE => { secp256k1_decompress_records.push(record); } @@ -802,6 +838,25 @@ impl Rv32imConfig { &self.secp256k1_decompress_config, secp256k1_decompress_records, )?; + witness.assign_opcode_circuit::>>( + cs, + shard_ctx, + &self.secp256r1_add_config, + secp256r1_add_records, + )?; + witness + .assign_opcode_circuit::>>( + cs, + shard_ctx, + &self.secp256r1_double_config, + secp256r1_double_records, + )?; + witness.assign_opcode_circuit::>( + cs, + shard_ctx, + &self.secp256r1_scalar_invert, + secp256r1_scalar_invert_records, + )?; witness.assign_opcode_circuit::>( cs, shard_ctx, @@ -1003,6 +1058,18 @@ impl StepCellExtractor for &Rv32imConfig { .ecall_cells_map .get(&WeierstrassDecompressInstruction::>::name()) .expect("unable to find name"), + Secp256r1AddSpec::CODE => *self + .ecall_cells_map + .get(&WeierstrassAddAssignInstruction::>::name()) + .expect("unable to find name"), + Secp256r1DoubleSpec::CODE => *self + .ecall_cells_map + .get(&WeierstrassDoubleAssignInstruction::>::name()) + .expect("unable to find name"), + Secp256r1ScalarInvertSpec::CODE => *self + .ecall_cells_map + .get(&Secp256r1InvInstruction::::name()) + .expect("unable to find name"), Uint256MulSpec::CODE => *self .ecall_cells_map .get(&Uint256MulInstruction::::name()) diff --git a/clippy.toml b/clippy.toml index bc98e0cd5..41690a1eb 100644 --- a/clippy.toml +++ b/clippy.toml @@ -23,5 +23,7 @@ allowed-duplicate-crates = [ "num-bigint", "rfc6979", "k256", + "p256", + "primeorder", "ecdsa", ] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index c90d6a950..762c9883b 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -25,7 +25,8 @@ tiny-keccak.workspace = true bn = { package = "substrate-bn", git = "https://github.com/scroll-tech/bn", branch = "ceno" } k256 = { git = "https://github.com/scroll-tech/elliptic-curves", branch = "ceno/k256-13.4", default-features = false, features = ["std", "ecdsa"] } +p256 = { git = "https://github.com/scroll-tech/elliptic-curves", branch = "ceno/k256-13.4", default-features = false, features = ["std", "ecdsa", "arithmetic"] } substrate-bn.workspace = true [features] -profiling = ["k256/std", "k256/ecdsa", "k256/profiling"] +profiling = ["k256/std", "k256/ecdsa", "k256/profiling", "p256/std", "p256/ecdsa", "p256/arithmetic", "p256/profiling"] diff --git a/examples/examples/secp256r1_scalar_algebra.rs b/examples/examples/secp256r1_scalar_algebra.rs new file mode 100644 index 000000000..94cc2b7de --- /dev/null +++ b/examples/examples/secp256r1_scalar_algebra.rs @@ -0,0 +1,10 @@ +extern crate ceno_rt; + +use p256::{Scalar, elliptic_curve::Field}; + +fn main() { + // test scalar invert + let s = Scalar::random(rand::thread_rng()); + let s_inv = s.invert().unwrap(); + assert_eq!(s * s_inv, Scalar::ONE); +} diff --git a/examples/examples/secp256r1_verify_prehash.rs b/examples/examples/secp256r1_verify_prehash.rs new file mode 100644 index 000000000..3a453199a --- /dev/null +++ b/examples/examples/secp256r1_verify_prehash.rs @@ -0,0 +1,41 @@ +extern crate ceno_rt; + +use alloy_primitives::hex; +use p256::{ + AffinePoint, EncodedPoint, + ecdsa::{Signature, VerifyingKey, signature::hazmat::PrehashVerifier}, + elliptic_curve::{generic_array::GenericArray, sec1::FromEncodedPoint}, +}; + +fn main() { + // The following test vector adapted from the FIPS 186-4 ECDSA test vectors + // (P-256, SHA-384, from `SigGen.txt` in `186-4ecdsatestvectors.zip`) + // + let verifier = VerifyingKey::from_affine( + AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates( + GenericArray::from_slice(&hex!( + "e0e7b99bc62d8dd67883e39ed9fa0657789c5ff556cc1fd8dd1e2a55e9e3f243" + )), + GenericArray::from_slice(&hex!( + "63fbfd0232b95578075c903a4dbf85ad58f8350516e1ec89b0ee1f5e1362da69" + )), + false, + )) + .unwrap(), + ) + .unwrap(); + let signature = Signature::from_scalars( + GenericArray::clone_from_slice(&hex!( + "f5087878e212b703578f5c66f434883f3ef414dc23e2e8d8ab6a8d159ed5ad83" + )), + GenericArray::clone_from_slice(&hex!( + "306b4c6c20213707982dffbb30fba99b96e792163dd59dbe606e734328dd7c8a" + )), + ) + .unwrap(); + let result = verifier.verify_prehash( + &hex!("d9c83b92fa0979f4a5ddbd8dd22ab9377801c3c31bf50f932ace0d2146e2574da0d5552dbed4b18836280e9f94558ea6"), + &signature, + ); + assert!(result.is_ok()); +} diff --git a/guest_libs/crypto/Cargo.toml b/guest_libs/crypto/Cargo.toml index f8fc04ec4..a6f9fe08b 100644 --- a/guest_libs/crypto/Cargo.toml +++ b/guest_libs/crypto/Cargo.toml @@ -15,6 +15,7 @@ ceno_keccak = { path = "../keccak" } ceno_sha2 = { path = "../sha2" } ceno_syscall.workspace = true k256 = { git = "https://github.com/scroll-tech/elliptic-curves", branch = "ceno/k256-13.4", default-features = false, features = ["std", "ecdsa"] } +p256 = { git = "https://github.com/scroll-tech/elliptic-curves", branch = "ceno/k256-13.4", default-features = false, features = ["std", "ecdsa", "arithmetic"] } thiserror.workspace = true [dev-dependencies] @@ -23,4 +24,4 @@ alloy-primitives = "1.4" revm-precompile.workspace = true [features] -profiling = ["k256/profiling"] +profiling = ["k256/std", "k256/ecdsa", "k256/profiling", "p256/std", "p256/ecdsa", "p256/arithmetic", "p256/profiling"] diff --git a/guest_libs/crypto/src/macros.rs b/guest_libs/crypto/src/macros.rs index cd9afb81b..47d4b4e70 100644 --- a/guest_libs/crypto/src/macros.rs +++ b/guest_libs/crypto/src/macros.rs @@ -137,7 +137,7 @@ macro_rules! ceno_crypto { sig: &[u8; 64], pk: &[u8; 64], ) -> bool { - $crate::secp256r1::secp256r1_verify_signature(msg, sig, pk) + $crate::secp256r1::secp256r1_verify_signature(msg, sig, pk).is_some() } } diff --git a/guest_libs/crypto/src/secp256r1.rs b/guest_libs/crypto/src/secp256r1.rs index 2e73c277c..9b4af90e7 100644 --- a/guest_libs/crypto/src/secp256r1.rs +++ b/guest_libs/crypto/src/secp256r1.rs @@ -1,5 +1,28 @@ +use p256::{ + EncodedPoint, + ecdsa::{Signature, VerifyingKey, signature::hazmat::PrehashVerifier}, +}; + /// secp256r1 (P-256) signature verification. #[inline] -pub fn secp256r1_verify_signature(_msg: &[u8; 32], _sig: &[u8; 64], _pk: &[u8; 64]) -> bool { - unimplemented!() +pub fn secp256r1_verify_signature(msg: &[u8; 32], sig: &[u8; 64], pk: &[u8; 64]) -> Option<()> { + #[cfg(feature = "profiling")] + ceno_syscall::syscall_phantom_log_pc_cycle("secp256r1_verify_signature start"); + // Can fail only if the input is not exact length. + let signature = Signature::from_slice(sig).ok()?; + // Decode the public key bytes (x,y coordinates) using EncodedPoint + let encoded_point = EncodedPoint::from_untagged_bytes(pk.into()); + // Create VerifyingKey from the encoded point + let public_key = VerifyingKey::from_encoded_point(&encoded_point).ok()?; + + #[cfg(feature = "profiling")] + { + let res = public_key.verify_prehash(msg, &signature).ok(); + ceno_syscall::syscall_phantom_log_pc_cycle("secp256r1_verify_signature end"); + res + } + #[cfg(not(feature = "profiling"))] + { + public_key.verify_prehash(msg, &signature).ok() + } }