diff --git a/acir/src/circuit/opcodes/black_box_function_call.rs b/acir/src/circuit/opcodes/black_box_function_call.rs index 827f15c31..b2ca0440b 100644 --- a/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acir/src/circuit/opcodes/black_box_function_call.rs @@ -72,7 +72,8 @@ pub enum BlackBoxFuncCall { output: Witness, }, FixedBaseScalarMul { - input: FunctionInput, + low: FunctionInput, + high: FunctionInput, outputs: (Witness, Witness), }, Keccak256 { @@ -160,7 +161,8 @@ impl BlackBoxFuncCall { output: Witness(0), }, BlackBoxFunc::FixedBaseScalarMul => BlackBoxFuncCall::FixedBaseScalarMul { - input: FunctionInput::dummy(), + low: FunctionInput::dummy(), + high: FunctionInput::dummy(), outputs: (Witness(0), Witness(0)), }, BlackBoxFunc::Keccak256 => { @@ -210,8 +212,8 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => { vec![*lhs, *rhs] } - BlackBoxFuncCall::FixedBaseScalarMul { input, .. } - | BlackBoxFuncCall::RANGE { input } => vec![*input], + BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], + BlackBoxFuncCall::RANGE { input } => vec![*input], BlackBoxFuncCall::SchnorrVerify { public_key_x, public_key_y, diff --git a/acir/tests/test_program_serialization.rs b/acir/tests/test_program_serialization.rs index 6d69a1392..e8bd066e6 100644 --- a/acir/tests/test_program_serialization.rs +++ b/acir/tests/test_program_serialization.rs @@ -60,7 +60,8 @@ fn addition_circuit() { #[test] fn fixed_base_scalar_mul_circuit() { let fixed_base_scalar_mul = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::FixedBaseScalarMul { - input: FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }, + low: FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }, + high: FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }, outputs: (Witness(2), Witness(3)), }); @@ -76,9 +77,9 @@ fn fixed_base_scalar_mul_circuit() { circuit.write(&mut bytes).unwrap(); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 137, 91, 10, 0, 0, 4, 4, 215, 227, 203, 253, 207, - 43, 132, 146, 169, 105, 106, 87, 1, 16, 154, 170, 77, 61, 229, 84, 222, 191, 240, 169, 156, - 61, 0, 36, 111, 164, 5, 80, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 202, 65, 10, 0, 64, 8, 2, 64, 183, 246, 212, 255, + 223, 27, 21, 21, 72, 130, 12, 136, 31, 192, 67, 167, 180, 209, 73, 201, 234, 249, 109, 132, + 84, 218, 3, 23, 46, 165, 61, 88, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs index 6ace112e6..975025971 100644 --- a/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs +++ b/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -11,12 +11,14 @@ use crate::{ pub(super) fn fixed_base_scalar_mul( backend: &impl BlackBoxFunctionSolver, initial_witness: &mut WitnessMap, - input: FunctionInput, + low: FunctionInput, + high: FunctionInput, outputs: (Witness, Witness), ) -> Result<(), OpcodeResolutionError> { - let scalar = witness_to_value(initial_witness, input.witness)?; + let low = witness_to_value(initial_witness, low.witness)?; + let high = witness_to_value(initial_witness, high.witness)?; - let (pub_x, pub_y) = backend.fixed_base_scalar_mul(scalar)?; + let (pub_x, pub_y) = backend.fixed_base_scalar_mul(low, high)?; insert_value(&outputs.0, pub_x, initial_witness)?; insert_value(&outputs.1, pub_y, initial_witness)?; diff --git a/acvm/src/pwg/blackbox/mod.rs b/acvm/src/pwg/blackbox/mod.rs index f224ce0e6..0e8ed2bc5 100644 --- a/acvm/src/pwg/blackbox/mod.rs +++ b/acvm/src/pwg/blackbox/mod.rs @@ -148,8 +148,8 @@ pub(crate) fn solve( message, *output, ), - BlackBoxFuncCall::FixedBaseScalarMul { input, outputs } => { - fixed_base_scalar_mul(backend, initial_witness, *input, *outputs) + BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => { + fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs) } BlackBoxFuncCall::RecursiveAggregation { output_aggregation_object, .. } => { // Solve the output of the recursive aggregation to zero to prevent missing assignment errors diff --git a/acvm/tests/solver.rs b/acvm/tests/solver.rs index ce13ff268..de5c53ce6 100644 --- a/acvm/tests/solver.rs +++ b/acvm/tests/solver.rs @@ -38,7 +38,8 @@ impl BlackBoxFunctionSolver for StubbedBackend { } fn fixed_base_scalar_mul( &self, - _input: &FieldElement, + _low: &FieldElement, + _high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { panic!("Path not trodden by this test") } diff --git a/acvm_js/test/shared/fixed_base_scalar_mul.ts b/acvm_js/test/shared/fixed_base_scalar_mul.ts index 4ab05544f..a1fd36d71 100644 --- a/acvm_js/test/shared/fixed_base_scalar_mul.ts +++ b/acvm_js/test/shared/fixed_base_scalar_mul.ts @@ -1,10 +1,9 @@ // See `fixed_base_scalar_mul_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 137, 91, 10, 0, 0, 4, 4, 215, 227, 203, - 253, 207, 43, 132, 146, 169, 105, 106, 87, 1, 16, 154, 170, 77, 61, 229, 84, - 222, 191, 240, 169, 156, 61, 0, 36, 111, 164, 5, 80, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 202, 65, 10, 0, 64, 8, 2, 64, 183, 246, + 212, 255, 223, 27, 21, 21, 72, 130, 12, 136, 31, 192, 67, 167, 180, 209, 73, + 201, 234, 249, 109, 132, 84, 218, 3, 23, 46, 165, 61, 88, 0, 0, 0, ]); - export const initialWitnessMap = new Map([ [1, "0x0000000000000000000000000000000000000000000000000000000000000001"], ]); diff --git a/blackbox_solver/src/barretenberg/mod.rs b/blackbox_solver/src/barretenberg/mod.rs index 875a995ff..1058d5afb 100644 --- a/blackbox_solver/src/barretenberg/mod.rs +++ b/blackbox_solver/src/barretenberg/mod.rs @@ -71,10 +71,11 @@ impl BlackBoxFunctionSolver for BarretenbergSolver { fn fixed_base_scalar_mul( &self, - input: &FieldElement, + low: &FieldElement, + high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { #[allow(deprecated)] - self.blackbox_vendor.fixed_base(input).map_err(|err| { + self.blackbox_vendor.fixed_base(low, high).map_err(|err| { BlackBoxResolutionError::Failed(BlackBoxFunc::FixedBaseScalarMul, err.to_string()) }) } diff --git a/blackbox_solver/src/barretenberg/wasm/scalar_mul.rs b/blackbox_solver/src/barretenberg/wasm/scalar_mul.rs index 1a9f5b060..008eaa1d2 100644 --- a/blackbox_solver/src/barretenberg/wasm/scalar_mul.rs +++ b/blackbox_solver/src/barretenberg/wasm/scalar_mul.rs @@ -3,14 +3,22 @@ use acir::FieldElement; use super::{Barretenberg, Error, FIELD_BYTES}; pub(crate) trait ScalarMul { - fn fixed_base(&self, input: &FieldElement) -> Result<(FieldElement, FieldElement), Error>; + fn fixed_base( + &self, + low: &FieldElement, + high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), Error>; } impl ScalarMul for Barretenberg { - fn fixed_base(&self, input: &FieldElement) -> Result<(FieldElement, FieldElement), Error> { + fn fixed_base( + &self, + low: &FieldElement, + _high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), Error> { let lhs_ptr: usize = 0; let result_ptr: usize = lhs_ptr + FIELD_BYTES; - self.transfer_to_heap(&input.to_be_bytes(), lhs_ptr); + self.transfer_to_heap(&low.to_be_bytes(), lhs_ptr); self.call_multiple("compute_public_key", vec![&lhs_ptr.into(), &result_ptr.into()])?; @@ -34,7 +42,7 @@ mod test { let barretenberg = Barretenberg::new(); let input = FieldElement::one(); - let res = barretenberg.fixed_base(&input)?; + let res = barretenberg.fixed_base(&input, &FieldElement::zero())?; let x = "0000000000000000000000000000000000000000000000000000000000000001"; let y = "0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c"; diff --git a/blackbox_solver/src/lib.rs b/blackbox_solver/src/lib.rs index 251b9f0d3..6a5847338 100644 --- a/blackbox_solver/src/lib.rs +++ b/blackbox_solver/src/lib.rs @@ -44,7 +44,8 @@ pub trait BlackBoxFunctionSolver { ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; fn fixed_base_scalar_mul( &self, - input: &FieldElement, + low: &FieldElement, + high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; } diff --git a/brillig/src/black_box.rs b/brillig/src/black_box.rs index 3e51158a4..be858a43c 100644 --- a/brillig/src/black_box.rs +++ b/brillig/src/black_box.rs @@ -43,6 +43,6 @@ pub enum BlackBoxOp { }, /// Calculates a Pedersen commitment to the inputs. Pedersen { inputs: HeapVector, domain_separator: RegisterIndex, output: HeapArray }, - /// Performs scalar multiplication over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined. - FixedBaseScalarMul { input: RegisterIndex, result: HeapArray }, + /// Performs scalar multiplication over the embedded curve. + FixedBaseScalarMul { low: RegisterIndex, high: RegisterIndex, result: HeapArray }, } diff --git a/brillig_vm/src/black_box.rs b/brillig_vm/src/black_box.rs index 8f3cdbb6c..5eb2b0abd 100644 --- a/brillig_vm/src/black_box.rs +++ b/brillig_vm/src/black_box.rs @@ -140,9 +140,10 @@ pub(crate) fn evaluate_black_box( registers.set(*result, verified.into()); Ok(()) } - BlackBoxOp::FixedBaseScalarMul { input, result } => { - let input = registers.get(*input).to_field(); - let (x, y) = solver.fixed_base_scalar_mul(&input)?; + BlackBoxOp::FixedBaseScalarMul { low, high, result } => { + let low = registers.get(*low).to_field(); + let high = registers.get(*high).to_field(); + let (x, y) = solver.fixed_base_scalar_mul(&low, &high)?; memory.write_slice(registers.get(result.pointer).to_usize(), &[x.into(), y.into()]); Ok(()) } diff --git a/brillig_vm/src/lib.rs b/brillig_vm/src/lib.rs index af95abdf2..cd614d762 100644 --- a/brillig_vm/src/lib.rs +++ b/brillig_vm/src/lib.rs @@ -410,7 +410,8 @@ impl BlackBoxFunctionSolver for DummyBlackBoxSolver { } fn fixed_base_scalar_mul( &self, - _input: &FieldElement, + _low: &FieldElement, + _high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Ok((4_u128.into(), 5_u128.into())) }