diff --git a/Cargo.lock b/Cargo.lock index de99543221..29ec1b028b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1422,6 +1422,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -1603,6 +1604,8 @@ dependencies = [ "ff 0.13.0", "generic-array 0.14.7", "group 0.13.0", + "hkdf", + "pem-rfc7468", "pkcs8", "rand_core", "sec1", @@ -2076,6 +2079,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -3115,6 +3127,18 @@ dependencies = [ "serde", ] +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "pairing" version = "0.22.0" @@ -3209,6 +3233,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -3326,6 +3359,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -4343,6 +4385,7 @@ dependencies = [ "p3-symmetric", "p3-uni-stark", "p3-util", + "p384", "rand", "rayon-scan", "rrs-lib", @@ -4404,6 +4447,7 @@ dependencies = [ "hex", "k256", "num", + "p384", "rand", "serde", "snowbridge-amcl", @@ -4652,6 +4696,7 @@ dependencies = [ "once_cell", "p3-baby-bear", "p3-field", + "p384", "rand", "serde", "sha2", diff --git a/core/Cargo.toml b/core/Cargo.toml index e477ec2639..1b44380fa4 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -46,6 +46,7 @@ curve25519-dalek = { version = "4.1.2" } elliptic-curve = "0.13.8" hex = "0.4.3" k256 = { version = "0.13.3", features = ["expose-field"] } +p384 = { version = "0.13.0", features = ["expose-field"] } num_cpus = "1.16.0" serde_with = "3.8.1" size = "0.4.1" diff --git a/core/src/operations/field/field_den.rs b/core/src/operations/field/field_den.rs index eab87631ca..26d1e1b1bc 100644 --- a/core/src/operations/field/field_den.rs +++ b/core/src/operations/field/field_den.rs @@ -113,9 +113,11 @@ where V: Into, { let p_a = Polynomial::from(*a); - let p_b = (*b).into(); + // let p_b = (*b).into(); + let p_b = Polynomial::from(*b); let p_result = self.result.into(); - let p_carry = self.carry.into(); + // let p_carry = self.carry.into(); + let p_carry = Polynomial::from(self.carry); // Compute the vanishing polynomial: // lhs(x) = sign * (b(x) * result(x) + result(x)) + (1 - sign) * (b(x) * result(x) + a(x)) @@ -136,7 +138,13 @@ where let p_witness_low = self.witness_low.0.iter().into(); let p_witness_high = self.witness_high.0.iter().into(); - eval_field_operation::(builder, &p_vanishing, &p_witness_low, &p_witness_high); + eval_field_operation::( + builder, + &p_vanishing, + &p_witness_low, + &p_witness_high, + is_real.clone(), + ); // Range checks for the result, carry, and witness columns. builder.slice_range_check_u8(&self.result.0, shard.clone(), is_real.clone()); diff --git a/core/src/operations/field/field_inner_product.rs b/core/src/operations/field/field_inner_product.rs index 070b174bd1..efe3b3a416 100644 --- a/core/src/operations/field/field_inner_product.rs +++ b/core/src/operations/field/field_inner_product.rs @@ -116,7 +116,7 @@ where let p_a_vec: Vec> = a.iter().map(|x| (*x).into()).collect(); let p_b_vec: Vec> = b.iter().map(|x| (*x).into()).collect(); let p_result = self.result.into(); - let p_carry = self.carry.into(); + let p_carry: Polynomial = self.carry.into(); let p_zero = Polynomial::::new(vec![AB::Expr::zero()]); @@ -135,7 +135,13 @@ where let p_witness_low = self.witness_low.0.iter().into(); let p_witness_high = self.witness_high.0.iter().into(); - eval_field_operation::(builder, &p_vanishing, &p_witness_low, &p_witness_high); + eval_field_operation::( + builder, + &p_vanishing, + &p_witness_low, + &p_witness_high, + is_real.clone(), + ); // Range checks for the result, carry, and witness columns. builder.slice_range_check_u8(&self.result.0, shard.clone(), is_real.clone()); diff --git a/core/src/operations/field/field_op.rs b/core/src/operations/field/field_op.rs index 9c8943d0ce..6087103926 100644 --- a/core/src/operations/field/field_op.rs +++ b/core/src/operations/field/field_op.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use num::{BigUint, Zero}; +use num::BigUint; use p3_air::AirBuilder; use p3_field::PrimeField32; use sp1_derive::AlignedBorrow; @@ -117,14 +117,14 @@ impl FieldOpCols { modulus: &BigUint, op: FieldOperation, ) -> BigUint { - if b == &BigUint::zero() && op == FieldOperation::Div { - // Division by 0 is allowed only when dividing 0 so that padded rows can be all 0. - assert_eq!( - *a, - BigUint::zero(), - "division by zero is allowed only when dividing zero" - ); - } + // if b == &BigUint::zero() && op == FieldOperation::Div { + // // Division by 0 is allowed only when dividing 0 so that padded rows can be all 0. + // assert_eq!( + // *a, + // BigUint::zero(), + // "division by zero is allowed only when dividing zero" + // ); + // } let result = match op { // If doing the subtraction operation, a - b = result, equivalent to a = result + b. @@ -212,7 +212,13 @@ impl FieldOpCols { let p_vanishing = p_op_minus_result - &(&p_carry * &p_modulus); let p_witness_low = self.witness_low.0.iter().into(); let p_witness_high = self.witness_high.0.iter().into(); - eval_field_operation::(builder, &p_vanishing, &p_witness_low, &p_witness_high); + eval_field_operation::( + builder, + &p_vanishing, + &p_witness_low, + &p_witness_high, + is_real.clone(), + ); // Range checks for the result, carry, and witness columns. builder.slice_range_check_u8(&self.result.0, shard.clone(), is_real.clone()); diff --git a/core/src/operations/field/util_air.rs b/core/src/operations/field/util_air.rs index 54ae64216d..c8c552084c 100644 --- a/core/src/operations/field/util_air.rs +++ b/core/src/operations/field/util_air.rs @@ -2,13 +2,16 @@ use p3_field::AbstractField; use crate::air::Polynomial; use crate::air::SP1AirBuilder; -use crate::operations::field::params::FieldParameters; +use p3_air::AirBuilder; + +use super::params::FieldParameters; pub fn eval_field_operation( builder: &mut AB, p_vanishing: &Polynomial, p_witness_low: &Polynomial, p_witness_high: &Polynomial, + is_real: impl Into + Clone, ) { // Reconstruct and shift back the witness polynomial let limb: AB::Expr = AB::F::from_canonical_u32(2u32.pow(P::NB_BITS_PER_LIMB as u32)).into(); @@ -26,6 +29,6 @@ pub fn eval_field_operation( let constraints = p_vanishing - &(p_witness * root_monomial); for constr in constraints.as_coefficients() { - builder.assert_zero(constr); + builder.when(is_real.clone()).assert_zero(constr); } } diff --git a/core/src/runtime/record.rs b/core/src/runtime/record.rs index 83210fcb22..ee5fec2823 100644 --- a/core/src/runtime/record.rs +++ b/core/src/runtime/record.rs @@ -81,6 +81,10 @@ pub struct ExecutionRecord { pub secp256k1_double_events: Vec, + pub secp384r1_add_events: Vec, + + pub secp384r1_double_events: Vec, + pub bn254_add_events: Vec, pub bn254_double_events: Vec, @@ -119,6 +123,8 @@ pub struct ShardingConfig { pub keccak_len: usize, pub secp256k1_add_len: usize, pub secp256k1_double_len: usize, + pub secp384r1_add_len: usize, + pub secp384r1_double_len: usize, pub bn254_add_len: usize, pub bn254_double_len: usize, pub bls12381_add_len: usize, @@ -149,6 +155,8 @@ impl Default for ShardingConfig { keccak_len: shard_size, secp256k1_add_len: shard_size, secp256k1_double_len: shard_size, + secp384r1_add_len: shard_size, + secp384r1_double_len: shard_size, bn254_add_len: shard_size, bn254_double_len: shard_size, bls12381_add_len: shard_size, @@ -211,6 +219,14 @@ impl MachineRecord for ExecutionRecord { "secp256k1_double_events".to_string(), self.secp256k1_double_events.len(), ); + stats.insert( + "secp384r1_add_events".to_string(), + self.secp384r1_add_events.len(), + ); + stats.insert( + "secp384r1_double_events".to_string(), + self.secp384r1_double_events.len(), + ); stats.insert("bn254_add_events".to_string(), self.bn254_add_events.len()); stats.insert( "bn254_double_events".to_string(), @@ -267,6 +283,10 @@ impl MachineRecord for ExecutionRecord { .append(&mut other.secp256k1_add_events); self.secp256k1_double_events .append(&mut other.secp256k1_double_events); + self.secp384r1_add_events + .append(&mut other.secp384r1_add_events); + self.secp384r1_double_events + .append(&mut other.secp384r1_double_events); self.bn254_add_events.append(&mut other.bn254_add_events); self.bn254_double_events .append(&mut other.bn254_double_events); @@ -452,6 +472,26 @@ impl MachineRecord for ExecutionRecord { .extend_from_slice(secp256k1_double_chunk); } + // secp384r1 curve add events. + for (secp384r1_add_chunk, shard) in take(&mut self.secp384r1_add_events) + .chunks_mut(config.secp384r1_add_len) + .zip(shards.iter_mut()) + { + shard + .secp384r1_add_events + .extend_from_slice(secp384r1_add_chunk); + } + + // secp384r1 curve double events. + for (secp384r1_double_chunk, shard) in take(&mut self.secp384r1_double_events) + .chunks_mut(config.secp384r1_double_len) + .zip(shards.iter_mut()) + { + shard + .secp384r1_double_events + .extend_from_slice(secp384r1_double_chunk); + } + // bn254 curve add events. for (bn254_add_chunk, shard) in take(&mut self.bn254_add_events) .chunks_mut(config.bn254_add_len) diff --git a/core/src/runtime/syscall.rs b/core/src/runtime/syscall.rs index 4e6304b429..ad9226f525 100644 --- a/core/src/runtime/syscall.rs +++ b/core/src/runtime/syscall.rs @@ -19,7 +19,7 @@ use crate::syscall::{ }; use crate::utils::ec::edwards::ed25519::{Ed25519, Ed25519Parameters}; use crate::utils::ec::weierstrass::bls12_381::Bls12381; -use crate::utils::ec::weierstrass::{bn254::Bn254, secp256k1::Secp256k1}; +use crate::utils::ec::weierstrass::{bn254::Bn254, secp256k1::Secp256k1, secp384r1::Secp384r1}; use crate::{runtime::ExecutionRecord, runtime::MemoryReadRecord, runtime::MemoryWriteRecord}; /// A system call is invoked by the the `ecall` instruction with a specific value in register t0. @@ -102,6 +102,12 @@ pub enum SyscallCode { /// Executes the `BLS12381_DOUBLE` precompile. BLS12381_DOUBLE = 0x00_00_01_1F, + + /// Executes the `SECP256K1_ADD` precompile. + SECP384R1_ADD = 0x00_01_01_16, + + /// Executes the `SECP256K1_DOUBLE` precompile. + SECP384R1_DOUBLE = 0x00_00_01_17, } impl SyscallCode { @@ -132,6 +138,8 @@ impl SyscallCode { 0x00_00_00_F1 => SyscallCode::HINT_READ, 0x00_00_01_1D => SyscallCode::UINT256_MUL, 0x00_00_01_1C => SyscallCode::BLS12381_DECOMPRESS, + 0x00_01_01_16 => SyscallCode::SECP384R1_ADD, + 0x00_00_01_17 => SyscallCode::SECP384R1_DOUBLE, _ => panic!("invalid syscall number: {}", value), } } @@ -281,6 +289,14 @@ pub fn default_syscall_map() -> HashMap> { SyscallCode::SECP256K1_DOUBLE, Rc::new(WeierstrassDoubleAssignChip::::new()), ); + syscall_map.insert( + SyscallCode::SECP384R1_ADD, + Rc::new(WeierstrassAddAssignChip::::new()), + ); + syscall_map.insert( + SyscallCode::SECP384R1_DOUBLE, + Rc::new(WeierstrassDoubleAssignChip::::new()), + ); syscall_map.insert(SyscallCode::SHA_COMPRESS, Rc::new(ShaCompressChip::new())); syscall_map.insert( SyscallCode::SECP256K1_DECOMPRESS, @@ -402,6 +418,12 @@ mod tests { SyscallCode::SECP256K1_DOUBLE => { assert_eq!(code as u32, sp1_zkvm::syscalls::SECP256K1_DOUBLE) } + SyscallCode::SECP384R1_ADD => { + assert_eq!(code as u32, sp1_zkvm::syscalls::SECP384R1_ADD) + } + SyscallCode::SECP384R1_DOUBLE => { + assert_eq!(code as u32, sp1_zkvm::syscalls::SECP384R1_DOUBLE) + } SyscallCode::BLAKE3_COMPRESS_INNER => { assert_eq!(code as u32, sp1_zkvm::syscalls::BLAKE3_COMPRESS_INNER) } diff --git a/core/src/stark/air.rs b/core/src/stark/air.rs index dc181b18d2..2599aad526 100644 --- a/core/src/stark/air.rs +++ b/core/src/stark/air.rs @@ -36,6 +36,7 @@ pub(crate) mod riscv_chips { pub use crate::utils::ec::weierstrass::bls12_381::Bls12381Parameters; pub use crate::utils::ec::weierstrass::bn254::Bn254Parameters; pub use crate::utils::ec::weierstrass::secp256k1::Secp256k1Parameters; + pub use crate::utils::ec::weierstrass::secp384r1::Secp384r1Parameters; pub use crate::utils::ec::weierstrass::SwCurve; } @@ -86,6 +87,10 @@ pub enum RiscvAir { Secp256k1Add(WeierstrassAddAssignChip>), /// A precompile for doubling a point on the Elliptic curve secp256k1. Secp256k1Double(WeierstrassDoubleAssignChip>), + /// A precompile for addition on the Elliptic curve secp384r1. + Secp384r1Add(WeierstrassAddAssignChip>), + /// A precompile for doubling a point on the Elliptic curve secp384r1. + Secp384r1Double(WeierstrassDoubleAssignChip>), /// A precompile for the Keccak permutation. KeccakP(KeccakPermuteChip), /// A precompile for the Blake3 compression function. (Disabled by default.) @@ -138,6 +143,11 @@ impl RiscvAir { let secp256k1_double_assign = WeierstrassDoubleAssignChip::>::new(); chips.push(RiscvAir::Secp256k1Double(secp256k1_double_assign)); + let secp384r1_add_assign = WeierstrassAddAssignChip::>::new(); + chips.push(RiscvAir::Secp384r1Add(secp384r1_add_assign)); + let secp384r1_double_assign = + WeierstrassDoubleAssignChip::>::new(); + chips.push(RiscvAir::Secp384r1Double(secp384r1_double_assign)); let keccak_permute = KeccakPermuteChip::new(); chips.push(RiscvAir::KeccakP(keccak_permute)); let bn254_add_assign = WeierstrassAddAssignChip::>::new(); diff --git a/core/src/syscall/precompiles/weierstrass/weierstrass_add.rs b/core/src/syscall/precompiles/weierstrass/weierstrass_add.rs index f2282632b8..07d51cb57a 100644 --- a/core/src/syscall/precompiles/weierstrass/weierstrass_add.rs +++ b/core/src/syscall/precompiles/weierstrass/weierstrass_add.rs @@ -80,6 +80,7 @@ impl Syscall for WeierstrassAddAssignChip { CurveType::Secp256k1 => rt.record_mut().secp256k1_add_events.push(event), CurveType::Bn254 => rt.record_mut().bn254_add_events.push(event), CurveType::Bls12381 => rt.record_mut().bls12381_add_events.push(event), + CurveType::Secp384r1 => rt.record_mut().secp384r1_add_events.push(event), _ => panic!("Unsupported curve"), } None @@ -181,6 +182,7 @@ where CurveType::Secp256k1 => "Secp256k1AddAssign".to_string(), CurveType::Bn254 => "Bn254AddAssign".to_string(), CurveType::Bls12381 => "Bls12381AddAssign".to_string(), + CurveType::Secp384r1 => "Secp384r1AddAssign".to_string(), _ => panic!("Unsupported curve"), } } @@ -194,6 +196,7 @@ where CurveType::Secp256k1 => &input.secp256k1_add_events, CurveType::Bn254 => &input.bn254_add_events, CurveType::Bls12381 => &input.bls12381_add_events, + CurveType::Secp384r1 => &input.secp384r1_add_events, _ => panic!("Unsupported curve"), }; @@ -273,6 +276,7 @@ where CurveType::Secp256k1 => !shard.secp256k1_add_events.is_empty(), CurveType::Bn254 => !shard.bn254_add_events.is_empty(), CurveType::Bls12381 => !shard.bls12381_add_events.is_empty(), + CurveType::Secp384r1 => !shard.secp384r1_add_events.is_empty(), _ => panic!("Unsupported curve"), } } @@ -432,6 +436,9 @@ where CurveType::Bls12381 => { AB::F::from_canonical_u32(SyscallCode::BLS12381_ADD.syscall_id()) } + CurveType::Secp384r1 => { + AB::F::from_canonical_u32(SyscallCode::SECP384R1_ADD.syscall_id()) + } _ => panic!("Unsupported curve"), }; @@ -455,7 +462,8 @@ mod tests { run_test, setup_logger, tests::{ BLS12381_ADD_ELF, BLS12381_DOUBLE_ELF, BLS12381_MUL_ELF, BN254_ADD_ELF, - BN254_MUL_ELF, SECP256K1_ADD_ELF, SECP256K1_MUL_ELF, + BN254_MUL_ELF, SECP256K1_ADD_ELF, SECP256K1_MUL_ELF, SECP384R1_ADD_ELF, + SECP384R1_MUL_ELF, }, }, }; @@ -467,6 +475,13 @@ mod tests { run_test(program).unwrap(); } + #[test] + fn test_secp384r1_add_simple() { + setup_logger(); + let program = Program::from(SECP384R1_ADD_ELF); + run_test(program).unwrap(); + } + #[test] fn test_bn254_add_simple() { setup_logger(); @@ -488,6 +503,13 @@ mod tests { run_test(program).unwrap(); } + #[test] + fn test_secp384r1_mul_simple() { + setup_logger(); + let program = Program::from(SECP384R1_MUL_ELF); + run_test(program).unwrap(); + } + #[test] fn test_bls12381_add_simple() { setup_logger(); diff --git a/core/src/syscall/precompiles/weierstrass/weierstrass_double.rs b/core/src/syscall/precompiles/weierstrass/weierstrass_double.rs index 2730c4924e..d8dfeb5c35 100644 --- a/core/src/syscall/precompiles/weierstrass/weierstrass_double.rs +++ b/core/src/syscall/precompiles/weierstrass/weierstrass_double.rs @@ -81,6 +81,7 @@ impl Syscall for WeierstrassDoubleAssi CurveType::Secp256k1 => rt.record_mut().secp256k1_double_events.push(event), CurveType::Bn254 => rt.record_mut().bn254_double_events.push(event), CurveType::Bls12381 => rt.record_mut().bls12381_double_events.push(event), + CurveType::Secp384r1 => rt.record_mut().secp384r1_double_events.push(event), _ => panic!("Unsupported curve"), } None @@ -203,6 +204,7 @@ where CurveType::Secp256k1 => "Secp256k1DoubleAssign".to_string(), CurveType::Bn254 => "Bn254DoubleAssign".to_string(), CurveType::Bls12381 => "Bls12381DoubleAssign".to_string(), + CurveType::Secp384r1 => "Secp384r1DoubleAssign".to_string(), _ => panic!("Unsupported curve"), } } @@ -217,6 +219,7 @@ where CurveType::Secp256k1 => &input.secp256k1_double_events, CurveType::Bn254 => &input.bn254_double_events, CurveType::Bls12381 => &input.bls12381_double_events, + CurveType::Secp384r1 => &input.secp384r1_double_events, _ => panic!("Unsupported curve"), }; @@ -296,6 +299,7 @@ where CurveType::Secp256k1 => !shard.secp256k1_double_events.is_empty(), CurveType::Bn254 => !shard.bn254_double_events.is_empty(), CurveType::Bls12381 => !shard.bls12381_double_events.is_empty(), + CurveType::Secp384r1 => !shard.secp384r1_double_events.is_empty(), _ => panic!("Unsupported curve"), } } @@ -465,6 +469,9 @@ where CurveType::Bls12381 => { AB::F::from_canonical_u32(SyscallCode::BLS12381_DOUBLE.syscall_id()) } + CurveType::Secp384r1 => { + AB::F::from_canonical_u32(SyscallCode::SECP384R1_DOUBLE.syscall_id()) + } _ => panic!("Unsupported curve"), }; @@ -486,7 +493,9 @@ pub mod tests { runtime::Program, utils::{ run_test, setup_logger, - tests::{BLS12381_DOUBLE_ELF, BN254_DOUBLE_ELF, SECP256K1_DOUBLE_ELF}, + tests::{ + BLS12381_DOUBLE_ELF, BN254_DOUBLE_ELF, SECP256K1_DOUBLE_ELF, SECP384R1_DOUBLE_ELF, + }, }, }; @@ -510,4 +519,11 @@ pub mod tests { let program = Program::from(BLS12381_DOUBLE_ELF); run_test(program).unwrap(); } + + #[test] + fn test_secp384r1_double_simple() { + setup_logger(); + let program = Program::from(SECP384R1_DOUBLE_ELF); + run_test(program).unwrap(); + } } diff --git a/core/src/utils/ec/mod.rs b/core/src/utils/ec/mod.rs index 6ec4ad0327..511f0e592b 100644 --- a/core/src/utils/ec/mod.rs +++ b/core/src/utils/ec/mod.rs @@ -28,6 +28,7 @@ pub enum CurveType { Bn254, Ed25519, Bls12381, + Secp384r1, } impl Display for CurveType { @@ -37,6 +38,7 @@ impl Display for CurveType { CurveType::Bn254 => write!(f, "Bn254"), CurveType::Ed25519 => write!(f, "Ed25519"), CurveType::Bls12381 => write!(f, "Bls12381"), + CurveType::Secp384r1 => write!(f, "Secp384r1"), } } } diff --git a/core/src/utils/ec/weierstrass/mod.rs b/core/src/utils/ec/weierstrass/mod.rs index 5ab6f47ae5..c802509b65 100644 --- a/core/src/utils/ec/weierstrass/mod.rs +++ b/core/src/utils/ec/weierstrass/mod.rs @@ -11,6 +11,7 @@ use crate::utils::ec::{AffinePoint, EllipticCurve, EllipticCurveParameters}; pub mod bls12_381; pub mod bn254; pub mod secp256k1; +pub mod secp384r1; /// Parameters that specify a short Weierstrass curve : y^2 = x^3 + ax + b. pub trait WeierstrassParameters: EllipticCurveParameters { diff --git a/core/src/utils/ec/weierstrass/secp384r1.rs b/core/src/utils/ec/weierstrass/secp384r1.rs new file mode 100644 index 0000000000..9027a44935 --- /dev/null +++ b/core/src/utils/ec/weierstrass/secp384r1.rs @@ -0,0 +1,144 @@ +//! Modulo defining the Secp384r1 curve and its base field. The constants are all taken from +//! https://www.secg.org/sec2-v2.pdf. + +use std::str::FromStr; + +use generic_array::GenericArray; +use num::traits::FromBytes; +use num::traits::ToBytes; +use num::BigUint; +use p384::FieldElement; +use serde::{Deserialize, Serialize}; +use typenum::{U48, U94}; + +use super::{SwCurve, WeierstrassParameters}; +use crate::operations::field::params::FieldParameters; +use crate::operations::field::params::NumLimbs; +use crate::utils::ec::CurveType; +use crate::utils::ec::EllipticCurveParameters; + +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +/// Secp384r1 curve parameter +pub struct Secp384r1Parameters; + +pub type Secp384r1 = SwCurve; + +#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)] +/// Secp384r1 base field parameter +pub struct Secp384r1BaseField; + +impl FieldParameters for Secp384r1BaseField { + const MODULUS: &'static [u8] = &[ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, + ]; + + /// A rough witness-offset estimate given the size of the limbs and the size of the field. + const WITNESS_OFFSET: usize = 1usize << 15; + + fn modulus() -> BigUint { + BigUint::from_bytes_le(Self::MODULUS) + } +} + +impl NumLimbs for Secp384r1BaseField { + type Limbs = U48; + type Witness = U94; +} + +impl EllipticCurveParameters for Secp384r1Parameters { + type BaseField = Secp384r1BaseField; + const CURVE_TYPE: CurveType = CurveType::Secp384r1; +} + +impl WeierstrassParameters for Secp384r1Parameters { + const A: GenericArray = GenericArray::from_array([ + 252, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 254, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, + ]); + + const B: GenericArray = GenericArray::from_array([ + 239, 42, 236, 211, 237, 200, 133, 42, 157, 209, 46, 138, 141, 57, 86, 198, 90, 135, 19, 80, + 143, 8, 20, 3, 18, 65, 129, 254, 110, 156, 29, 24, 25, 45, 248, 227, 107, 5, 142, 152, 228, + 231, 62, 226, 167, 47, 49, 179, + ]); + fn generator() -> (BigUint, BigUint) { + let x = BigUint::from_str( + "26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087", + ) + .unwrap(); + let y = BigUint::from_str( + "8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871", + ) + .unwrap(); + (x, y) + } + + fn prime_group_order() -> num::BigUint { + BigUint::from_slice(&[ + 0xCCC52973, 0xECEC196A, 0x48B0A77A, 0x581A0DB2, 0xF4372DDF, 0xC7634D81, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + ]) + } + + fn a_int() -> BigUint { + BigUint::from_slice(&[ + 0xFFFFFFFC, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + ]) + } + + fn b_int() -> BigUint { + BigUint::from_slice(&[ + 0xD3EC2AEF, 0x2A85C8ED, 0x8A2ED19D, 0xC656398D, 0x5013875A, 0x0314088F, 0xFE814112, + 0x181D9C6E, 0xE3F82D19, 0x988E056B, 0xE23EE7E4, 0xB3312FA7, + ]) + } +} + +pub fn secp384r1_sqrt(n: &BigUint) -> BigUint { + let be_bytes = n.to_be_bytes(); + let mut bytes = [0_u8; 48]; + bytes[48 - be_bytes.len()..].copy_from_slice(&be_bytes); + let fe = FieldElement::from_bytes(&bytes.into()).unwrap(); + let result_bytes = fe.sqrt().unwrap().to_bytes(); + BigUint::from_be_bytes(&result_bytes as &[u8]) +} + +#[cfg(test)] +mod tests { + + use super::*; + use crate::utils::ec::utils::biguint_from_limbs; + use num::bigint::RandBigInt; + use rand::thread_rng; + + #[test] + fn test_weierstrass_biguint_scalar_mul_p384() { + assert_eq!( + biguint_from_limbs(Secp384r1BaseField::MODULUS), + Secp384r1BaseField::modulus() + ); + } + + #[test] + fn test_secp384r_sqrt() { + let mut rng = thread_rng(); + for _ in 0..10 { + // Check that sqrt(x^2)^2 == x^2 + // We use x^2 since not all field elements have a square root + let x = rng.gen_biguint(256) % Secp384r1BaseField::modulus(); + let x_2 = (&x * &x) % Secp384r1BaseField::modulus(); + let sqrt = secp384r1_sqrt(&x_2); + + println!("sqrt: {}", sqrt); + + let sqrt_2 = (&sqrt * &sqrt) % Secp384r1BaseField::modulus(); + + assert_eq!(sqrt_2, x_2); + } + } +} diff --git a/core/src/utils/programs.rs b/core/src/utils/programs.rs index 839a55b37a..2b68f8bf98 100644 --- a/core/src/utils/programs.rs +++ b/core/src/utils/programs.rs @@ -58,12 +58,18 @@ pub mod tests { pub const SECP256K1_ADD_ELF: &[u8] = include_bytes!("../../../tests/secp256k1-add/elf/riscv32im-succinct-zkvm-elf"); + pub const SECP384R1_ADD_ELF: &[u8] = + include_bytes!("../../../tests/secp384r1-add/elf/riscv32im-succinct-zkvm-elf"); + pub const SECP256K1_DECOMPRESS_ELF: &[u8] = include_bytes!("../../../tests/secp256k1-decompress/elf/riscv32im-succinct-zkvm-elf"); pub const SECP256K1_DOUBLE_ELF: &[u8] = include_bytes!("../../../tests/secp256k1-double/elf/riscv32im-succinct-zkvm-elf"); + pub const SECP384R1_DOUBLE_ELF: &[u8] = + include_bytes!("../../../tests/secp384r1-double/elf/riscv32im-succinct-zkvm-elf"); + pub const SHA_COMPRESS_ELF: &[u8] = include_bytes!("../../../tests/sha-compress/elf/riscv32im-succinct-zkvm-elf"); @@ -85,6 +91,9 @@ pub mod tests { pub const SECP256K1_MUL_ELF: &[u8] = include_bytes!("../../../tests/secp256k1-mul/elf/riscv32im-succinct-zkvm-elf"); + pub const SECP384R1_MUL_ELF: &[u8] = + include_bytes!("../../../tests/secp384r1-mul/elf/riscv32im-succinct-zkvm-elf"); + pub const BLS12381_ADD_ELF: &[u8] = include_bytes!("../../../tests/bls12381-add/elf/riscv32im-succinct-zkvm-elf"); diff --git a/tests/secp384r1-add/Cargo.lock b/tests/secp384r1-add/Cargo.lock new file mode 100644 index 0000000000..12c8b61081 --- /dev/null +++ b/tests/secp384r1-add/Cargo.lock @@ -0,0 +1,812 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "tap", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "scale-info" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp384r1-add-test" +version = "0.1.0" +dependencies = [ + "hex-literal", + "num", + "sp1-zkvm", +] + +[[package]] +name = "serde" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "snowbridge-amcl" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" +dependencies = [ + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "sp1-precompiles" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "cfg-if", + "getrandom", + "hex", + "k256", + "num", + "p384", + "rand", + "serde", + "snowbridge-amcl", +] + +[[package]] +name = "sp1-zkvm" +version = "0.1.0" +dependencies = [ + "bincode", + "cfg-if", + "getrandom", + "k256", + "libm", + "once_cell", + "p384", + "rand", + "serde", + "sha2", + "sp1-precompiles", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/tests/secp384r1-add/Cargo.toml b/tests/secp384r1-add/Cargo.toml new file mode 100644 index 0000000000..c0b4d7f139 --- /dev/null +++ b/tests/secp384r1-add/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +[package] +version = "0.1.0" +name = "secp384r1-add-test" +edition = "2021" + +[dependencies] +sp1-zkvm = { path = "../../zkvm/entrypoint" } +hex-literal = "0.4.1" +num = { version = "0.4.1", default-features = false } \ No newline at end of file diff --git a/tests/secp384r1-add/elf/riscv32im-succinct-zkvm-elf b/tests/secp384r1-add/elf/riscv32im-succinct-zkvm-elf new file mode 100755 index 0000000000..18b96e7315 Binary files /dev/null and b/tests/secp384r1-add/elf/riscv32im-succinct-zkvm-elf differ diff --git a/tests/secp384r1-add/src/main.rs b/tests/secp384r1-add/src/main.rs new file mode 100644 index 0000000000..1fb8839b5a --- /dev/null +++ b/tests/secp384r1-add/src/main.rs @@ -0,0 +1,49 @@ +#![no_main] +sp1_zkvm::entrypoint!(main); + +extern "C" { + fn syscall_secp384r1_add(p: *mut u32, q: *const u32); +} + +pub fn main() { + // generator. + // 26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087 + // 8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871 + let mut a: [u8; 96] = [ + 183, 10, 118, 114, 56, 94, 84, 58, 108, 41, 85, 191, 93, 242, 2, 85, 56, 42, 84, 130, 224, + 65, 247, 89, 152, 155, 167, 139, 98, 59, 29, 110, 116, 173, 32, 243, 30, 199, 177, 142, 55, + 5, 139, 190, 34, 202, 135, 170, 95, 14, 234, 144, 124, 29, 67, 122, 157, 129, 126, 29, 206, + 177, 96, 10, 192, 184, 240, 181, 19, 49, 218, 233, 124, 20, 154, 40, 189, 29, 244, 248, 41, + 220, 146, 146, 191, 152, 158, 93, 111, 44, 38, 150, 74, 222, 23, 54, + ]; + + // 2 * generator. + // 1362138308511466522361153706999924933599454966107597910086607881313301390679204654798639248640660900363360053616481 + // 21933325650940841369538204578070064804451893403314136885642470114978241170633179043576249504748352841115137159204480 + let b: [u8; 96] = [ + 97, 223, 149, 82, 199, 169, 150, 91, 248, 100, 14, 190, 110, 232, 224, 79, 158, 110, 185, + 159, 209, 7, 210, 81, 214, 52, 244, 166, 89, 89, 2, 137, 240, 151, 91, 197, 69, 0, 38, 105, + 217, 210, 163, 123, 5, 153, 217, 8, 128, 14, 148, 10, 112, 30, 80, 97, 45, 226, 57, 77, + 233, 67, 253, 95, 37, 180, 106, 37, 95, 80, 78, 144, 62, 196, 108, 188, 117, 216, 117, 178, + 116, 186, 109, 253, 223, 232, 191, 183, 237, 60, 27, 91, 250, 241, 128, 142, + ]; + + unsafe { + syscall_secp384r1_add(a.as_mut_ptr() as *mut u32, b.as_ptr() as *const u32); + } + + // 3 * generator. + // 1150902892488483458936980703033240421996917307006362560128741616924334451190275252566486993672663650518120360101937 + // 31026896179475916024120184231935979451435829475766013456640577102369059008378103381483562093497986423351518602141169 + let c: [u8; 96] = [ + 49, 200, 0, 5, 199, 229, 215, 2, 13, 88, 38, 80, 174, 187, 8, 180, 166, 109, 86, 211, 64, + 242, 164, 190, 6, 205, 45, 32, 16, 57, 157, 203, 152, 125, 220, 95, 126, 60, 121, 100, 20, + 250, 111, 96, 212, 65, 122, 7, 241, 29, 47, 10, 96, 40, 95, 182, 152, 210, 181, 228, 107, + 189, 74, 194, 172, 30, 17, 220, 14, 76, 104, 247, 165, 90, 17, 133, 28, 180, 32, 133, 153, + 252, 169, 2, 150, 190, 11, 125, 131, 66, 12, 11, 202, 247, 149, 201, + ]; + + assert_eq!(a, c); + + println!("done"); +} diff --git a/tests/secp384r1-double/Cargo.lock b/tests/secp384r1-double/Cargo.lock new file mode 100644 index 0000000000..2f905b2cde --- /dev/null +++ b/tests/secp384r1-double/Cargo.lock @@ -0,0 +1,812 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "tap", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "scale-info" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp384r1-double-test" +version = "0.1.0" +dependencies = [ + "hex-literal", + "num", + "sp1-zkvm", +] + +[[package]] +name = "serde" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "snowbridge-amcl" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" +dependencies = [ + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "sp1-precompiles" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "cfg-if", + "getrandom", + "hex", + "k256", + "num", + "p384", + "rand", + "serde", + "snowbridge-amcl", +] + +[[package]] +name = "sp1-zkvm" +version = "0.1.0" +dependencies = [ + "bincode", + "cfg-if", + "getrandom", + "k256", + "libm", + "once_cell", + "p384", + "rand", + "serde", + "sha2", + "sp1-precompiles", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/tests/secp384r1-double/Cargo.toml b/tests/secp384r1-double/Cargo.toml new file mode 100644 index 0000000000..9b43cee570 --- /dev/null +++ b/tests/secp384r1-double/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +[package] +version = "0.1.0" +name = "secp384r1-double-test" +edition = "2021" + +[dependencies] +sp1-zkvm = { path = "../../zkvm/entrypoint" } +hex-literal = "0.4.1" +num = { version = "0.4.1", default-features = false } \ No newline at end of file diff --git a/tests/secp384r1-double/elf/riscv32im-succinct-zkvm-elf b/tests/secp384r1-double/elf/riscv32im-succinct-zkvm-elf new file mode 100755 index 0000000000..a72425f560 Binary files /dev/null and b/tests/secp384r1-double/elf/riscv32im-succinct-zkvm-elf differ diff --git a/tests/secp384r1-double/src/main.rs b/tests/secp384r1-double/src/main.rs new file mode 100644 index 0000000000..b70b08773d --- /dev/null +++ b/tests/secp384r1-double/src/main.rs @@ -0,0 +1,41 @@ +#![no_main] +sp1_zkvm::entrypoint!(main); + +extern "C" { + fn syscall_secp384r1_double(p: *mut u32); +} + +pub fn main() { + for _ in 0..10i64.pow(3) { + // generator. + // 26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087 + // 8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871 + let mut a: [u8; 96] = [ + 183, 10, 118, 114, 56, 94, 84, 58, 108, 41, 85, 191, 93, 242, 2, 85, 56, 42, 84, 130, + 224, 65, 247, 89, 152, 155, 167, 139, 98, 59, 29, 110, 116, 173, 32, 243, 30, 199, 177, + 142, 55, 5, 139, 190, 34, 202, 135, 170, 95, 14, 234, 144, 124, 29, 67, 122, 157, 129, + 126, 29, 206, 177, 96, 10, 192, 184, 240, 181, 19, 49, 218, 233, 124, 20, 154, 40, 189, + 29, 244, 248, 41, 220, 146, 146, 191, 152, 158, 93, 111, 44, 38, 150, 74, 222, 23, 54, + ]; + + unsafe { + syscall_secp384r1_double(a.as_mut_ptr() as *mut u32); + } + + // 2 * generator. + // 1362138308511466522361153706999924933599454966107597910086607881313301390679204654798639248640660900363360053616481 + // 21933325650940841369538204578070064804451893403314136885642470114978241170633179043576249504748352841115137159204480 + let b: [u8; 96] = [ + 97, 223, 149, 82, 199, 169, 150, 91, 248, 100, 14, 190, 110, 232, 224, 79, 158, 110, + 185, 159, 209, 7, 210, 81, 214, 52, 244, 166, 89, 89, 2, 137, 240, 151, 91, 197, 69, 0, + 38, 105, 217, 210, 163, 123, 5, 153, 217, 8, 128, 14, 148, 10, 112, 30, 80, 97, 45, + 226, 57, 77, 233, 67, 253, 95, 37, 180, 106, 37, 95, 80, 78, 144, 62, 196, 108, 188, + 117, 216, 117, 178, 116, 186, 109, 253, 223, 232, 191, 183, 237, 60, 27, 91, 250, 241, + 128, 142, + ]; + + assert_eq!(a, b); + } + + println!("done"); +} diff --git a/tests/secp384r1-mul/Cargo.lock b/tests/secp384r1-mul/Cargo.lock new file mode 100644 index 0000000000..41b1a0b56c --- /dev/null +++ b/tests/secp384r1-mul/Cargo.lock @@ -0,0 +1,814 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "tap", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "scale-info" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp384r1-mul-test" +version = "0.1.0" +dependencies = [ + "sp1-derive", + "sp1-zkvm", +] + +[[package]] +name = "serde" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "snowbridge-amcl" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" +dependencies = [ + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "sp1-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sp1-precompiles" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "cfg-if", + "getrandom", + "hex", + "k256", + "num", + "p384", + "rand", + "serde", + "snowbridge-amcl", +] + +[[package]] +name = "sp1-zkvm" +version = "0.1.0" +dependencies = [ + "bincode", + "cfg-if", + "getrandom", + "k256", + "libm", + "once_cell", + "p384", + "rand", + "serde", + "sha2", + "sp1-precompiles", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/tests/secp384r1-mul/Cargo.toml b/tests/secp384r1-mul/Cargo.toml new file mode 100644 index 0000000000..6a4fa80a3f --- /dev/null +++ b/tests/secp384r1-mul/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] +[package] +name = "secp384r1-mul-test" +version = "0.1.0" +edition = "2021" + +[dependencies] +sp1-zkvm = { path = "../../zkvm/entrypoint" } +sp1-derive = { path = "../../derive" } \ No newline at end of file diff --git a/tests/secp384r1-mul/elf/riscv32im-succinct-zkvm-elf b/tests/secp384r1-mul/elf/riscv32im-succinct-zkvm-elf new file mode 100755 index 0000000000..634b860c65 Binary files /dev/null and b/tests/secp384r1-mul/elf/riscv32im-succinct-zkvm-elf differ diff --git a/tests/secp384r1-mul/src/main.rs b/tests/secp384r1-mul/src/main.rs new file mode 100644 index 0000000000..770ddefeae --- /dev/null +++ b/tests/secp384r1-mul/src/main.rs @@ -0,0 +1,44 @@ +#![no_main] +sp1_zkvm::entrypoint!(main); + +use sp1_zkvm::precompiles::secp384r1::Secp384r1Operations; +use sp1_zkvm::precompiles::utils::AffinePoint; + +#[sp1_derive::cycle_tracker] +pub fn main() { + // generator. + // 26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087 + // 8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871 + let a: [u8; 96] = [ + 183, 10, 118, 114, 56, 94, 84, 58, 108, 41, 85, 191, 93, 242, 2, 85, 56, 42, 84, 130, 224, + 65, 247, 89, 152, 155, 167, 139, 98, 59, 29, 110, 116, 173, 32, 243, 30, 199, 177, 142, 55, + 5, 139, 190, 34, 202, 135, 170, 95, 14, 234, 144, 124, 29, 67, 122, 157, 129, 126, 29, 206, + 177, 96, 10, 192, 184, 240, 181, 19, 49, 218, 233, 124, 20, 154, 40, 189, 29, 244, 248, 41, + 220, 146, 146, 191, 152, 158, 93, 111, 44, 38, 150, 74, 222, 23, 54, + ]; + + let mut a_point = AffinePoint::::from_le_bytes(a); + + // scalar. + // 3 + let scalar: [u32; 12] = [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + + println!("cycle-tracker-start: secp384r1_mul"); + a_point.mul_assign(&scalar); + println!("cycle-tracker-end: secp384r1_mul"); + + // 3 * generator. + // 1150902892488483458936980703033240421996917307006362560128741616924334451190275252566486993672663650518120360101937 + // 31026896179475916024120184231935979451435829475766013456640577102369059008378103381483562093497986423351518602141169 + let c: [u8; 96] = [ + 49, 200, 0, 5, 199, 229, 215, 2, 13, 88, 38, 80, 174, 187, 8, 180, 166, 109, 86, 211, 64, + 242, 164, 190, 6, 205, 45, 32, 16, 57, 157, 203, 152, 125, 220, 95, 126, 60, 121, 100, 20, + 250, 111, 96, 212, 65, 122, 7, 241, 29, 47, 10, 96, 40, 95, 182, 152, 210, 181, 228, 107, + 189, 74, 194, 172, 30, 17, 220, 14, 76, 104, 247, 165, 90, 17, 133, 28, 180, 32, 133, 153, + 252, 169, 2, 150, 190, 11, 125, 131, 66, 12, 11, 202, 247, 149, 201, + ]; + + assert_eq!(a_point.to_le_bytes(), c); + + println!("done"); +} diff --git a/zkvm/entrypoint/Cargo.toml b/zkvm/entrypoint/Cargo.toml index e111a881ea..de013e3ef6 100644 --- a/zkvm/entrypoint/Cargo.toml +++ b/zkvm/entrypoint/Cargo.toml @@ -12,6 +12,7 @@ bincode = "1.3.3" cfg-if = "1.0.0" getrandom = { version = "0.2.15", features = ["custom"] } k256 = { version = "0.13.3", features = ["ecdsa", "std", "bits"] } +p384 = { version = "0.13.0", features = ["ecdsa", "std", "bits"] } once_cell = "1.19.0" rand = "0.8.5" serde = { version = "1.0.201", features = ["derive"] } diff --git a/zkvm/entrypoint/src/syscalls/mod.rs b/zkvm/entrypoint/src/syscalls/mod.rs index 760cabad2c..9678d390c8 100644 --- a/zkvm/entrypoint/src/syscalls/mod.rs +++ b/zkvm/entrypoint/src/syscalls/mod.rs @@ -7,6 +7,7 @@ mod io; mod keccak_permute; mod memory; mod secp256k1; +mod secp384r1; mod sha_compress; mod sha_extend; mod sys; @@ -23,6 +24,7 @@ pub use io::*; pub use keccak_permute::*; pub use memory::*; pub use secp256k1::*; +pub use secp384r1::*; pub use sha_compress::*; pub use sha_extend::*; pub use sys::*; @@ -105,3 +107,9 @@ pub const BLS12381_ADD: u32 = 0x00_01_01_1E; /// Executes the `BLS12381_DOUBLE` precompile. pub const BLS12381_DOUBLE: u32 = 0x00_00_01_1F; + +/// Executes `SECP384R1_ADD`. +pub const SECP384R1_ADD: u32 = 0x00_01_01_16; + +/// Executes `SECP384R1_DOUBLE`. +pub const SECP384R1_DOUBLE: u32 = 0x00_00_01_17; diff --git a/zkvm/entrypoint/src/syscalls/secp384r1.rs b/zkvm/entrypoint/src/syscalls/secp384r1.rs new file mode 100644 index 0000000000..859878e503 --- /dev/null +++ b/zkvm/entrypoint/src/syscalls/secp384r1.rs @@ -0,0 +1,42 @@ +#[cfg(target_os = "zkvm")] +use core::arch::asm; + +/// Adds two Secp384r1 points. +/// +/// The result is stored in the first point. +#[allow(unused_variables)] +#[no_mangle] +pub extern "C" fn syscall_secp384r1_add(p: *mut u32, q: *mut u32) { + #[cfg(target_os = "zkvm")] + unsafe { + asm!( + "ecall", + in("t0") crate::syscalls::SECP384R1_ADD, + in("a0") p, + in("a1") q + ); + } + + #[cfg(not(target_os = "zkvm"))] + unreachable!() +} + +/// Double a Secp384r1 point. +/// +/// The result is stored in the first point. +#[allow(unused_variables)] +#[no_mangle] +pub extern "C" fn syscall_secp384r1_double(p: *mut u32) { + #[cfg(target_os = "zkvm")] + unsafe { + asm!( + "ecall", + in("t0") crate::syscalls::SECP384R1_DOUBLE, + in("a0") p, + in("a1") 0 + ); + } + + #[cfg(not(target_os = "zkvm"))] + unreachable!() +} diff --git a/zkvm/precompiles/Cargo.toml b/zkvm/precompiles/Cargo.toml index e38ba017a3..6e7123459b 100644 --- a/zkvm/precompiles/Cargo.toml +++ b/zkvm/precompiles/Cargo.toml @@ -11,6 +11,7 @@ cfg-if = "1.0.0" getrandom = { version = "0.2.15", features = ["custom"] } hex = "0.4.3" k256 = { version = "0.13.3", features = ["ecdsa", "std", "bits"] } +p384 = { version = "0.13.0", features = ["ecdsa", "std", "bits"] } rand = "0.8.5" serde = { version = "1.0.201", features = ["derive"] } num = {version = "0.4.3"} diff --git a/zkvm/precompiles/src/lib.rs b/zkvm/precompiles/src/lib.rs index f5cf90bdcc..9aca481c1d 100644 --- a/zkvm/precompiles/src/lib.rs +++ b/zkvm/precompiles/src/lib.rs @@ -6,6 +6,7 @@ pub mod bls12381; pub mod bn254; pub mod io; pub mod secp256k1; +pub mod secp384r1; pub mod uint256_div; pub mod unconstrained; pub mod utils; @@ -22,6 +23,8 @@ extern "C" { pub fn syscall_ed_decompress(point: &mut [u8; 64]); pub fn syscall_secp256k1_add(p: *mut u32, q: *const u32); pub fn syscall_secp256k1_double(p: *mut u32); + pub fn syscall_secp384r1_add(p: *mut u32, q: *const u32); + pub fn syscall_secp384r1_double(p: *mut u32); pub fn syscall_secp256k1_decompress(point: &mut [u8; 64], is_odd: bool); pub fn syscall_bn254_add(p: *mut u32, q: *const u32); pub fn syscall_bn254_double(p: *mut u32); diff --git a/zkvm/precompiles/src/secp384r1.rs b/zkvm/precompiles/src/secp384r1.rs new file mode 100644 index 0000000000..a023a56850 --- /dev/null +++ b/zkvm/precompiles/src/secp384r1.rs @@ -0,0 +1,190 @@ +#![allow(unused)] + +use crate::utils::{AffinePoint, CurveOperations}; +use crate::{syscall_secp384r1_add, syscall_secp384r1_double}; +use anyhow::Context; +use anyhow::{anyhow, Result}; +use core::convert::TryInto; +use k256::ecdsa::hazmat::bits2field; +use k256::ecdsa::signature::hazmat::PrehashVerifier; +use k256::ecdsa::RecoveryId; +use p384::ecdsa::{Signature, VerifyingKey}; +use p384::elliptic_curve::ff::PrimeFieldBits; +use p384::elliptic_curve::ops::Invert; +use p384::elliptic_curve::sec1::ToEncodedPoint; +use p384::elliptic_curve::PrimeField; +use p384::{NistP384, PublicKey, Scalar}; + +use crate::io; +use crate::unconstrained; + +const NUM_WORDS: usize = 24; + +#[derive(Copy, Clone)] +pub struct Secp384r1Operations; + +impl CurveOperations for Secp384r1Operations { + const GENERATOR: [u32; NUM_WORDS] = [ + 1920338615, 978607672, 3210029420, 1426256477, 2186553912, 1509376480, 2343017368, + 1847409506, 4079005044, 2394015518, 3196781879, 2861025826, 2431258207, 2051218812, + 494829981, 174109134, 3052452032, 3923390739, 681186428, 4176747965, 2459098153, + 1570674879, 2519084143, 907533898, + ]; + + fn add_assign(limbs: &mut [u32; NUM_WORDS], other: &[u32; NUM_WORDS]) { + unsafe { + syscall_secp384r1_add(limbs.as_mut_ptr(), other.as_ptr()); + } + } + + fn double(limbs: &mut [u32; NUM_WORDS]) { + unsafe { + syscall_secp384r1_double(limbs.as_mut_ptr()); + } + } +} + +/// Verifies a secp384r1 signature using the public key and the message hash. If the s_inverse is +/// provided, it will be validated and used to verify the signature. Otherwise, the inverse of s +/// will be computed and used. +/// +/// Warning: this function does not check if the key is actually on the curve. +pub fn verify_signature( + pubkey: &[u8; 97], + msg_hash: &[u8; 48], + signature: &Signature, + s_inverse: Option<&Scalar>, +) -> bool { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "zkvm", target_vendor = "succinct"))] { + let pubkey_x = Scalar::from_repr(bits2field::(&pubkey[1..49]).unwrap()).unwrap(); + let pubkey_y = Scalar::from_repr(bits2field::(&pubkey[49..]).unwrap()).unwrap(); + + let mut pubkey_x_le_bytes = pubkey_x.to_bytes(); + pubkey_x_le_bytes.reverse(); + let mut pubkey_y_le_bytes = pubkey_y.to_bytes(); + pubkey_y_le_bytes.reverse(); + + // Convert the public key to an affine point + let affine = AffinePoint::::from(pubkey_x_le_bytes.into(), pubkey_y_le_bytes.into()); + + const GENERATOR: AffinePoint = AffinePoint::::generator_in_affine(); + + let field = bits2field::(msg_hash); + if field.is_err() { + return false; + } + let field = Scalar::from_repr(field.unwrap()).unwrap(); + let z = field; + let (r, s) = signature.split_scalars(); + let computed_s_inv; + let s_inv = match s_inverse { + Some(s_inv) => { + assert_eq!(s_inv * s.as_ref(), Scalar::ONE); + s_inv + } + None => { + computed_s_inv = s.invert(); + &computed_s_inv + } + }; + + let u1 = z * s_inv; + let u2 = *r * s_inv; + + let res = double_and_add_base(&u1, &GENERATOR, &u2, &affine).unwrap(); + let mut x_bytes_be = [0u8; 48]; + for i in 0..8 { + x_bytes_be[i * 4..(i * 4) + 4].copy_from_slice(&res.limbs[i].to_le_bytes()); + } + x_bytes_be.reverse(); + + let x_field = bits2field::(&x_bytes_be); + if x_field.is_err() { + return false; + } + *r == Scalar::from_repr(x_field.unwrap()).unwrap() + } else { + let public_key = PublicKey::from_sec1_bytes(pubkey); + if public_key.is_err() { + return false; + } + let public_key = public_key.unwrap(); + + let verify_key = VerifyingKey::from(&public_key); + let res = verify_key + .verify_prehash(msg_hash, signature) + .context("invalid signature"); + + res.is_ok() + } + } +} + +#[allow(non_snake_case)] +fn double_and_add_base( + a: &Scalar, + A: &AffinePoint, + b: &Scalar, + B: &AffinePoint, +) -> Option> { + let mut res: Option> = None; + let mut temp_A = *A; + let mut temp_B = *B; + + let a_bits = a.to_le_bits(); + let b_bits = b.to_le_bits(); + for (a_bit, b_bit) in a_bits.iter().zip(b_bits) { + if *a_bit { + match res.as_mut() { + Some(res) => res.add_assign(&temp_A), + None => res = Some(temp_A), + }; + } + + if b_bit { + match res.as_mut() { + Some(res) => res.add_assign(&temp_B), + None => res = Some(temp_B), + }; + } + + temp_A.double(); + temp_B.double(); + } + + res +} + +/// Outside of the VM, computes the pubkey and s_inverse value from a signature and a message hash. +/// +/// WARNING: The values are read from outside of the VM and are not constrained to be correct. +/// Either use `decompress_pubkey` and `verify_signature` to verify the results of this function, or +/// use `ecrecover`. +pub fn unconstrained_ecrecover(sig: &[u8; 97], msg_hash: &[u8; 48]) -> ([u8; 49], Scalar) { + unconstrained! { + let mut recovery_id = sig[96]; + let mut sig = Signature::from_slice(&sig[..96]).unwrap(); + + if let Some(sig_normalized) = sig.normalize_s() { + sig = sig_normalized; + recovery_id ^= 1 + }; + let recid = RecoveryId::from_byte(recovery_id).expect("Recovery ID is valid"); + + let recovered_key = VerifyingKey::recover_from_prehash(&msg_hash[..], &sig, recid).unwrap(); + let bytes = recovered_key.to_sec1_bytes(); + io::hint_slice(&bytes); + + let (_, s) = sig.split_scalars(); + let s_inverse = s.invert(); + io::hint_slice(&s_inverse.to_bytes()); + } + + let recovered_bytes: [u8; 49] = io::read_vec().try_into().unwrap(); + + let s_inv_bytes: [u8; 48] = io::read_vec().try_into().unwrap(); + let s_inverse = Scalar::from_repr(bits2field::(&s_inv_bytes).unwrap()).unwrap(); + + (recovered_bytes, s_inverse) +}