From eb8944f0e6dda43d520dffb05374314a1193dd39 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 07:35:15 +0000 Subject: [PATCH 01/32] feat: variable_base_scalar_mul blacbox func --- .../dsl/acir_format/serde/acir.hpp | 163 ++++++++++++++++++ noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 8 + 2 files changed, 171 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index e2c9d020d6bc..1cdc8a7a7330 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -145,6 +145,18 @@ struct BlackBoxFuncCall { static FixedBaseScalarMul bincodeDeserialize(std::vector); }; + struct VariableBaseScalarMul { + Program::FunctionInput point_x; + Program::FunctionInput point_y; + Program::FunctionInput low; + Program::FunctionInput high; + std::array outputs; + + friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); + std::vector bincodeSerialize() const; + static VariableBaseScalarMul bincodeDeserialize(std::vector); + }; + struct EmbeddedCurveAdd { Program::FunctionInput input1_x; Program::FunctionInput input1_y; @@ -278,6 +290,7 @@ struct BlackBoxFuncCall { EcdsaSecp256k1, EcdsaSecp256r1, FixedBaseScalarMul, + VariableBaseScalarMul, EmbeddedCurveAdd, Keccak256, Keccakf1600, @@ -753,6 +766,18 @@ struct BlackBoxOp { static FixedBaseScalarMul bincodeDeserialize(std::vector); }; + struct VariableBaseScalarMul { + Program::MemoryAddress point_x; + Program::MemoryAddress point_y; + Program::MemoryAddress low; + Program::MemoryAddress high; + Program::HeapArray result; + + friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); + std::vector bincodeSerialize() const; + static VariableBaseScalarMul bincodeDeserialize(std::vector); + }; + struct EmbeddedCurveAdd { Program::MemoryAddress input1_x; Program::MemoryAddress input1_y; @@ -855,6 +880,7 @@ struct BlackBoxOp { PedersenCommitment, PedersenHash, FixedBaseScalarMul, + VariableBaseScalarMul, EmbeddedCurveAdd, BigIntAdd, BigIntSub, @@ -3068,6 +3094,75 @@ Program::BlackBoxFuncCall::FixedBaseScalarMul serde::Deserializable< namespace Program { +inline bool operator==(const BlackBoxFuncCall::VariableBaseScalarMul& lhs, + const BlackBoxFuncCall::VariableBaseScalarMul& rhs) +{ + if (!(lhs.point_x == rhs.point_x)) { + return false; + } + if (!(lhs.point_y == rhs.point_y)) { + return false; + } + if (!(lhs.low == rhs.low)) { + return false; + } + if (!(lhs.high == rhs.high)) { + return false; + } + if (!(lhs.outputs == rhs.outputs)) { + return false; + } + return true; +} + +inline std::vector BlackBoxFuncCall::VariableBaseScalarMul::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxFuncCall::VariableBaseScalarMul BlackBoxFuncCall::VariableBaseScalarMul::bincodeDeserialize( + std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize( + const Program::BlackBoxFuncCall::VariableBaseScalarMul& obj, Serializer& serializer) +{ + serde::Serializable::serialize(obj.point_x, serializer); + serde::Serializable::serialize(obj.point_y, serializer); + serde::Serializable::serialize(obj.low, serializer); + serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.outputs, serializer); +} + +template <> +template +Program::BlackBoxFuncCall::VariableBaseScalarMul serde::Deserializable< + Program::BlackBoxFuncCall::VariableBaseScalarMul>::deserialize(Deserializer& deserializer) +{ + Program::BlackBoxFuncCall::VariableBaseScalarMul obj; + obj.point_x = serde::Deserializable::deserialize(deserializer); + obj.point_y = serde::Deserializable::deserialize(deserializer); + obj.low = serde::Deserializable::deserialize(deserializer); + obj.high = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Program { + inline bool operator==(const BlackBoxFuncCall::EmbeddedCurveAdd& lhs, const BlackBoxFuncCall::EmbeddedCurveAdd& rhs) { if (!(lhs.input1_x == rhs.input1_x)) { @@ -4444,6 +4539,74 @@ Program::BlackBoxOp::FixedBaseScalarMul serde::Deserializable BlackBoxOp::VariableBaseScalarMul::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::VariableBaseScalarMul BlackBoxOp::VariableBaseScalarMul::bincodeDeserialize( + std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize( + const Program::BlackBoxOp::VariableBaseScalarMul& obj, Serializer& serializer) +{ + serde::Serializable::serialize(obj.point_x, serializer); + serde::Serializable::serialize(obj.point_y, serializer); + serde::Serializable::serialize(obj.low, serializer); + serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Program::BlackBoxOp::VariableBaseScalarMul serde::Deserializable< + Program::BlackBoxOp::VariableBaseScalarMul>::deserialize(Deserializer& deserializer) +{ + Program::BlackBoxOp::VariableBaseScalarMul obj; + obj.point_x = serde::Deserializable::deserialize(deserializer); + obj.point_y = serde::Deserializable::deserialize(deserializer); + obj.low = serde::Deserializable::deserialize(deserializer); + obj.high = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Program { + inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd& lhs, const BlackBoxOp::EmbeddedCurveAdd& rhs) { if (!(lhs.input1_x == rhs.input1_x)) { diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index eee7aac39f2e..7f63a028755f 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -32,6 +32,14 @@ pub fn fixed_base_embedded_curve( // docs:end:fixed_base_embedded_curve {} +#[foreign(variable_base_scalar_mul)] +pub fn variable_base_embedded_curve( + point: EmbeddedCurvePoint, // point to multiply the scalar with + low: Field, // low limb of the scalar + high: Field // high limb of the scalar +) -> [Field; 2] +{} + // This is a hack as returning an `EmbeddedCurvePoint` from a foreign function in brillig returns a [BrilligVariable::SingleAddr; 2] rather than BrilligVariable::BrilligArray // as is defined in the brillig bytecode format. This is a workaround which allows us to fix this without modifying the serialization format. fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { From ea1b654e496d4a5c67b056395e36e20de1b1c860 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 09:10:34 +0000 Subject: [PATCH 02/32] WIP --- .../dsl/acir_format/acir_format.hpp | 1 + .../acir_format/acir_to_constraint_buf.hpp | 9 ++++ .../acir_format/variable_base_scalar_mul.cpp | 42 ++++++++++++++++ .../acir_format/variable_base_scalar_mul.hpp | 23 +++++++++ .../src/pwg/blackbox/fixed_base_scalar_mul.rs | 23 +++++++++ .../acvm-repo/acvm/src/pwg/blackbox/mod.rs | 3 ++ .../src/curve_specific_solver.rs | 7 +++ .../src/fixed_base_scalar_mul.rs | 50 +++++++++++++++++++ .../acvm-repo/brillig/src/black_box.rs | 8 +++ .../acvm-repo/brillig_vm/src/black_box.rs | 10 ++++ .../brillig/brillig_gen/brillig_black_box.rs | 19 +++++++ .../src/brillig/brillig_ir/debug_show.rs | 11 ++++ .../ssa/acir_gen/acir_ir/generated_acir.rs | 13 ++++- .../src/ssa/ir/instruction/call.rs | 1 + 14 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp create mode 100644 barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index ec82362e2d8b..8cebc1a5fd6f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -48,6 +48,7 @@ struct AcirFormat { std::vector pedersen_hash_constraints; std::vector poseidon2_constraints; std::vector fixed_base_scalar_mul_constraints; + std::vector variable_base_scalar_mul_constraints; std::vector ec_add_constraints; std::vector recursion_constraints; std::vector bigint_from_le_bytes_constraints; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp index 778363f3258c..e82a1ec38d03 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp @@ -317,6 +317,15 @@ void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg, Aci .pub_key_x = arg.outputs[0].value, .pub_key_y = arg.outputs[1].value, }); + } else if constexpr (std::is_same_v) { + af.variable_base_scalar_mul_constraints.push_back(VariableBaseScalarMul{ + .point_x = arg.low.witness.point_x, + .point_y = arg.low.witness.point_y, + .low = arg.low.witness.value, + .high = arg.high.witness.value, + .pub_key_x = arg.outputs[0].value, + .pub_key_y = arg.outputs[1].value, + }); } else if constexpr (std::is_same_v) { af.ec_add_constraints.push_back(EcAdd{ .input1_x = arg.input1_x.witness.value, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp new file mode 100644 index 000000000000..36ebc8d5fd9e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp @@ -0,0 +1,42 @@ +#include "variable_base_scalar_mul.hpp" +#include "barretenberg/dsl/types.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "barretenberg/plonk_honk_shared/arithmetization/gate_data.hpp" + +namespace acir_format { + +template void create_variable_base_constraint(Builder& builder, const VariableBaseScalarMul& input) +{ + using cycle_group_ct = bb::stdlib::cycle_group; + using cycle_scalar_ct = typename bb::stdlib::cycle_group::cycle_scalar; + using field_ct = bb::stdlib::field_t; + + // Computes low * P + high * 2^128 * P where P is the variable base we multiply the scalar with + // + // Low and high need to be less than 2^128 + // TODO(benesjan): nuke the following 4 lines + auto x = field_ct::from_witness_index(&builder, input.pub_key_x); + auto y = field_ct::from_witness_index(&builder, input.pub_key_y); + grumpkin::g1::affine_element base_point_var(x.get_value(), y.get_value()); + cycle_group_ct base_point(base_point_var); + + auto point_x = field_ct::from_witness_index(&builder, input.point_x); + auto point_y = field_ct::from_witness_index(&builder, input.point_y); + cycle_group_ct input_point(point_x, point_y, false); + + field_ct low_as_field = field_ct::from_witness_index(&builder, input.low); + field_ct high_as_field = field_ct::from_witness_index(&builder, input.high); + cycle_scalar_ct scalar(low_as_field, high_as_field); + auto result = input_point * scalar; + + builder.assert_equal(result.x.get_witness_index(), input.pub_key_x); + builder.assert_equal(result.y.get_witness_index(), input.pub_key_y); +} + +template void create_variable_base_constraint(UltraCircuitBuilder& builder, + const VariableBaseScalarMul& input); +template void create_variable_base_constraint(GoblinUltraCircuitBuilder& builder, + const VariableBaseScalarMul& input); + +} // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp new file mode 100644 index 000000000000..b9d4c2aff4e0 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp @@ -0,0 +1,23 @@ +#pragma once +#include "barretenberg/dsl/types.hpp" +#include "barretenberg/serialize/msgpack.hpp" +#include + +namespace acir_format { + +struct VariableBaseScalarMul { + uint32_t point_x; + uint32_t point_y; + uint32_t low; + uint32_t high; + uint32_t pub_key_x; + uint32_t pub_key_y; + + // for serialization, update with any new fields + MSGPACK_FIELDS(point_x, point_y, low, high, pub_key_x, pub_key_y); + friend bool operator==(VariableBaseScalarMul const& lhs, VariableBaseScalarMul const& rhs) = default; +}; + +template void create_fixed_base_constraint(Builder& builder, const VariableBaseScalarMul& input); + +} // namespace acir_format diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs index c5bfd1d5646d..52adb35e9ced 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -24,6 +24,29 @@ pub(super) fn fixed_base_scalar_mul( Ok(()) } +// TODO(benesjan): rename this file to something more generic? +pub(super) fn variable_base_scalar_mul( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + point_x: FunctionInput, + point_y: FunctionInput, + low: FunctionInput, + high: FunctionInput, + outputs: (Witness, Witness), +) -> Result<(), OpcodeResolutionError> { + let point_x = witness_to_value(initial_witness, point_x.witness)?; + let point_y = witness_to_value(initial_witness, point_y.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.variable_base_scalar_mul(point_x, point_y, low, high)?; + + insert_value(&outputs.0, pub_x, initial_witness)?; + insert_value(&outputs.1, pub_y, initial_witness)?; + + Ok(()) +} + pub(super) fn embedded_curve_add( backend: &impl BlackBoxFunctionSolver, initial_witness: &mut WitnessMap, diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 2753c7baaaa9..9673ba3467be 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -158,6 +158,9 @@ pub(crate) fn solve( BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => { fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs) } + BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, outputs } => { + variable_base_scalar_mul(backend, initial_witness, *point_x, *point_y, *low, *high, *outputs) + } BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, outputs } => { embedded_curve_add( backend, diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index fab67467d9ab..a3d13984d5d2 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -29,6 +29,13 @@ pub trait BlackBoxFunctionSolver { low: &FieldElement, high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; + fn variable_base_scalar_mul( + &self, + point_x: &FieldElement, + point_y: &FieldElement, + low: &FieldElement, + high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; fn ec_add( &self, input1_x: &FieldElement, diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index cd91c290f494..90be1a79bb45 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -58,6 +58,54 @@ fn create_point(x: FieldElement, y: FieldElement) -> Result Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + let point1 = create_point(point_x, point_y) + .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; + + let low: u128 = low.try_into_u128().ok_or_else(|| { + BlackBoxResolutionError::Failed( + BlackBoxFunc::VariableBaseScalarMul, + format!("Limb {} is not less than 2^128", low.to_hex()), + ) + })?; + + let high: u128 = high.try_into_u128().ok_or_else(|| { + BlackBoxResolutionError::Failed( + BlackBoxFunc::VariableBaseScalarMul, + format!("Limb {} is not less than 2^128", high.to_hex()), + ) + })?; + + let mut bytes = high.to_be_bytes().to_vec(); + bytes.extend_from_slice(&low.to_be_bytes()); + + // Check if this is smaller than the grumpkin modulus + let grumpkin_integer = BigUint::from_bytes_be(&bytes); + + if grumpkin_integer >= grumpkin::FrConfig::MODULUS.into() { + return Err(BlackBoxResolutionError::Failed( + BlackBoxFunc::VariableBaseScalarMul, + format!("{} is not a valid grumpkin scalar", grumpkin_integer.to_str_radix(16)), + )); + } + + let result = grumpkin::SWAffine::from( + point1.mul_bigint(grumpkin_integer.to_u64_digits()), + ); + if let Some((res_x, res_y)) = result.xy() { + Ok((FieldElement::from_repr(*res_x), FieldElement::from_repr(*res_y))) + } else { + Ok((FieldElement::zero(), FieldElement::zero())) + } +} + pub fn embedded_curve_add( input1_x: FieldElement, input1_y: FieldElement, @@ -147,6 +195,8 @@ mod grumpkin_fixed_base_scalar_mul { ); } + // TODO(benesjan): variable_base_scalar_mul tests + #[test] fn rejects_addition_of_points_not_in_curve() { let x = FieldElement::from(1u128); diff --git a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs index 29861d0fd841..5744321d2433 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs @@ -72,6 +72,14 @@ pub enum BlackBoxOp { high: MemoryAddress, result: HeapArray, }, + /// Performs scalar multiplication over the embedded curve with variable base point. + VariableBaseScalarMul { + point_x: MemoryAddress, + point_y: MemoryAddress, + low: MemoryAddress, + high: MemoryAddress, + result: HeapArray, + }, /// Performs addition over the embedded curve. EmbeddedCurveAdd { input1_x: MemoryAddress, diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 19407da52dbe..38713c775eee 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -143,6 +143,15 @@ pub(crate) fn evaluate_black_box( memory.write_slice(memory.read_ref(result.pointer), &[x.into(), y.into()]); Ok(()) } + BlackBoxOp::VariableBaseScalarMul { point_x, point_y, low, high, result } => { + let point_x = memory.read(*point_x).try_into().unwrap(); + let point_y = memory.read(*point_y).try_into().unwrap(); + let low = memory.read(*low).try_into().unwrap(); + let high = memory.read(*high).try_into().unwrap(); + let (x, y) = solver.fixed_base_scalar_mul(&low, &high)?; + memory.write_slice(memory.read_ref(result.pointer), &[point_x.into(), point_y.into(), x.into(), y.into()]); + Ok(()) + } BlackBoxOp::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, result } => { let input1_x = memory.read(*input1_x).try_into().unwrap(); let input1_y = memory.read(*input1_y).try_into().unwrap(); @@ -289,6 +298,7 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { BlackBoxOp::PedersenCommitment { .. } => BlackBoxFunc::PedersenCommitment, BlackBoxOp::PedersenHash { .. } => BlackBoxFunc::PedersenHash, BlackBoxOp::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul, + BlackBoxOp::VariableBaseScalarMul { .. } => BlackBoxFunc::VariableBaseScalarMul, BlackBoxOp::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd, BlackBoxOp::BigIntAdd { .. } => BlackBoxFunc::BigIntAdd, BlackBoxOp::BigIntSub { .. } => BlackBoxFunc::BigIntSub, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index ee047903743d..68233c6e4a3d 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -205,6 +205,25 @@ pub(crate) fn convert_black_box_call( ) } } + BlackBoxFunc::VariableBaseScalarMul => { + if let ( + [BrilligVariable::SingleAddr(point_x), BrilligVariable::SingleAddr(point_y), BrilligVariable::SingleAddr(low), BrilligVariable::SingleAddr(high)], + [BrilligVariable::BrilligArray(result_array)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::VariableBaseScalarMul { + point_x: point_x.address, + point_y: point_y.address, + low: low.address, + high: high.address, + result: result_array.to_heap_array(), + }); + } else { + unreachable!( + "ICE: VariableBaseScalarMul expects one register argument and one array result" + ) + } + } BlackBoxFunc::EmbeddedCurveAdd => { if let ( [BrilligVariable::SingleAddr(input1_x), BrilligVariable::SingleAddr(input1_y), BrilligVariable::SingleAddr(input2_x), BrilligVariable::SingleAddr(input2_y)], diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 5601bbde8772..5a2a9eeeaf44 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -324,6 +324,17 @@ impl DebugShow { result ); } + BlackBoxOp::VariableBaseScalarMul { point_x, point_y, low, high, result } => { + debug_println!( + self.enable_debug_trace, + " VARIABLE_BASE_SCALAR_MUL {} {} -> {}", + point_x, + point_y, + low, + high, + result + ); + } BlackBoxOp::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, result } => { debug_println!( self.enable_debug_trace, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index c084ba37fee6..e761e483e7ff 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -283,6 +283,13 @@ impl GeneratedAcir { high: inputs[1][0], outputs: (outputs[0], outputs[1]), }, + BlackBoxFunc::VariableBaseScalarMul => BlackBoxFuncCall::VariableBaseScalarMul { + point_x: inputs[0][0], + point_y: inputs[1][0], + low: inputs[2][0], + high: inputs[3][0], + outputs: (outputs[0], outputs[1]), + }, BlackBoxFunc::EmbeddedCurveAdd => BlackBoxFuncCall::EmbeddedCurveAdd { input1_x: inputs[0][0], input1_y: inputs[1][0], @@ -669,6 +676,10 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { // is the low and high limbs of the scalar BlackBoxFunc::FixedBaseScalarMul => Some(2), + // Inputs for variable based scalar multiplication are the x and y coordinates of the base point and low + // and high limbs of the scalar + BlackBoxFunc::VariableBaseScalarMul => Some(4), + // Recursive aggregation has a variable number of inputs BlackBoxFunc::RecursiveAggregation => None, @@ -723,7 +734,7 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { // Output of operations over the embedded curve // will be 2 field elements representing the point. - BlackBoxFunc::FixedBaseScalarMul | BlackBoxFunc::EmbeddedCurveAdd => Some(2), + BlackBoxFunc::FixedBaseScalarMul | BlackBoxFunc::VariableBaseScalarMul | BlackBoxFunc::EmbeddedCurveAdd => Some(2), // Big integer operations return a big integer BlackBoxFunc::BigIntAdd diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 1187ea8cb07c..a8365ffef39b 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -453,6 +453,7 @@ fn simplify_black_box_func( } BlackBoxFunc::FixedBaseScalarMul + | BlackBoxFunc::VariableBaseScalarMul | BlackBoxFunc::SchnorrVerify | BlackBoxFunc::PedersenCommitment | BlackBoxFunc::PedersenHash From e12fcce0c8d57f0c901acd43fcdf037e13ada557 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 09:52:05 +0000 Subject: [PATCH 03/32] WIP --- .../barretenberg/dsl/acir_format/acir_format.cpp | 5 +++++ .../barretenberg/dsl/acir_format/acir_format.hpp | 1 + .../dsl/acir_format/variable_base_scalar_mul.cpp | 14 +++++--------- .../dsl/acir_format/variable_base_scalar_mul.hpp | 2 +- noir/noir-repo/acvm-repo/acir/README.md | 9 +++++++++ .../acir/src/circuit/black_box_functions.rs | 6 +++++- .../src/circuit/opcodes/black_box_function_call.rs | 10 ++++++++++ .../acir/tests/test_program_serialization.rs | 2 ++ .../acvm_js/test/browser/execute_circuit.test.ts | 10 ++++++++++ .../acvm_js/test/node/execute_circuit.test.ts | 10 ++++++++++ .../blackbox_solver/src/curve_specific_solver.rs | 9 +++++++++ .../acvm-repo/brillig_vm/src/black_box.rs | 2 +- 12 files changed, 68 insertions(+), 12 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 5ece3c031d48..736990478529 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -89,6 +89,11 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo create_fixed_base_constraint(builder, constraint); } + // Add variable base scalar mul constraints + for (const auto& constraint : constraint_system.variable_base_scalar_mul_constraints) { + create_variable_base_constraint(builder, constraint); + } + // Add ec add constraints for (const auto& constraint : constraint_system.ec_add_constraints) { create_ec_add_constraint(builder, constraint, has_valid_witness_assignments); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index 8cebc1a5fd6f..a6ddd729ac24 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -17,6 +17,7 @@ #include "recursion_constraint.hpp" #include "schnorr_verify.hpp" #include "sha256_constraint.hpp" +#include "variable_base_scalar_mul.hpp" #include namespace acir_format { diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp index 36ebc8d5fd9e..9137cb0fc28f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp @@ -12,24 +12,20 @@ template void create_variable_base_constraint(Builder& builde using cycle_scalar_ct = typename bb::stdlib::cycle_group::cycle_scalar; using field_ct = bb::stdlib::field_t; - // Computes low * P + high * 2^128 * P where P is the variable base we multiply the scalar with - // - // Low and high need to be less than 2^128 - // TODO(benesjan): nuke the following 4 lines - auto x = field_ct::from_witness_index(&builder, input.pub_key_x); - auto y = field_ct::from_witness_index(&builder, input.pub_key_y); - grumpkin::g1::affine_element base_point_var(x.get_value(), y.get_value()); - cycle_group_ct base_point(base_point_var); - + // We instantiate the input point/variable base as `cycle_group_ct` auto point_x = field_ct::from_witness_index(&builder, input.point_x); auto point_y = field_ct::from_witness_index(&builder, input.point_y); cycle_group_ct input_point(point_x, point_y, false); + // We reconstruct the scalar from the low and high limbs field_ct low_as_field = field_ct::from_witness_index(&builder, input.low); field_ct high_as_field = field_ct::from_witness_index(&builder, input.high); cycle_scalar_ct scalar(low_as_field, high_as_field); + + // We multiply the scalar with input point/variable base to get the result auto result = input_point * scalar; + // Finally we add the constraints builder.assert_equal(result.x.get_witness_index(), input.pub_key_x); builder.assert_equal(result.y.get_witness_index(), input.pub_key_y); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp index b9d4c2aff4e0..91b433b4bcc1 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp @@ -18,6 +18,6 @@ struct VariableBaseScalarMul { friend bool operator==(VariableBaseScalarMul const& lhs, VariableBaseScalarMul const& rhs) = default; }; -template void create_fixed_base_constraint(Builder& builder, const VariableBaseScalarMul& input); +template void create_variable_base_constraint(Builder& builder, const VariableBaseScalarMul& input); } // namespace acir_format diff --git a/noir/noir-repo/acvm-repo/acir/README.md b/noir/noir-repo/acvm-repo/acir/README.md index 801aeac1140a..ae219023e08d 100644 --- a/noir/noir-repo/acvm-repo/acir/README.md +++ b/noir/noir-repo/acvm-repo/acir/README.md @@ -146,6 +146,15 @@ Inputs and outputs are similar to SchnorrVerify, except that because we use a di Because the Grumpkin scalar field is bigger than the ACIR field, we provide 2 ACIR fields representing the low and high parts of the Grumpkin scalar $a$: $a=low+high*2^{128},$ with $low, high < 2^{128}$ +**VariableBaseScalarMul**: scalar multiplication with a variable base/input point (P) of the embedded curve +- input: + point_x, point_y representing x and y coordinates of input point P + low, high are 2 (field , 254), representing the low and high part of the input scalar. For Barretenberg, they must both be less than 128 bits. +- output: x and y coordinates of $low*P+high*2^{128}*P$, where P is the input point P + +Because the Grumpkin scalar field is bigger than the ACIR field, we provide 2 ACIR fields representing the low and high parts of the Grumpkin scalar $a$: +$a=low+high*2^{128},$ with $low, high < 2^{128}$ + **Keccak256**: Computes the Keccak-256 (Ethereum version) of the inputs. - inputs: Vector of bytes (FieldElement, 8) - outputs: Vector of 32 bytes (FieldElement, 8) diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs index 0a7ee244a5ee..9a43702a408c 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -36,8 +36,10 @@ pub enum BlackBoxFunc { EcdsaSecp256k1, /// Verifies a ECDSA signature over the secp256r1 curve. EcdsaSecp256r1, - /// Performs scalar multiplication over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined. + /// Performs scalar multiplication over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined and a fixed base/generator point G1. FixedBaseScalarMul, + /// Performs scalar multiplication over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined and a variable base/input point P. + VariableBaseScalarMul, /// Calculates the Keccak256 hash of the inputs. Keccak256, /// Keccak Permutation function of 1600 width @@ -82,6 +84,7 @@ impl BlackBoxFunc { BlackBoxFunc::PedersenHash => "pedersen_hash", BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1", BlackBoxFunc::FixedBaseScalarMul => "fixed_base_scalar_mul", + BlackBoxFunc::VariableBaseScalarMul => "variable_base_scalar_mul", BlackBoxFunc::EmbeddedCurveAdd => "embedded_curve_add", BlackBoxFunc::AND => "and", BlackBoxFunc::XOR => "xor", @@ -112,6 +115,7 @@ impl BlackBoxFunc { "ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1), "ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1), "fixed_base_scalar_mul" => Some(BlackBoxFunc::FixedBaseScalarMul), + "variable_base_scalar_mul" => Some(BlackBoxFunc::VariableBaseScalarMul), "embedded_curve_add" => Some(BlackBoxFunc::EmbeddedCurveAdd), "and" => Some(BlackBoxFunc::AND), "xor" => Some(BlackBoxFunc::XOR), diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 405cd0cef007..5858eb554cc2 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -85,6 +85,13 @@ pub enum BlackBoxFuncCall { high: FunctionInput, outputs: (Witness, Witness), }, + VariableBaseScalarMul { + point_x: FunctionInput, + point_y: FunctionInput, + low: FunctionInput, + high: FunctionInput, + outputs: (Witness, Witness), + }, EmbeddedCurveAdd { input1_x: FunctionInput, input1_y: FunctionInput, @@ -189,6 +196,7 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::EcdsaSecp256k1 { .. } => BlackBoxFunc::EcdsaSecp256k1, BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1, BlackBoxFuncCall::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul, + BlackBoxFuncCall::VariableBaseScalarMul { .. } => BlackBoxFunc::VariableBaseScalarMul, BlackBoxFuncCall::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd, BlackBoxFuncCall::Keccak256 { .. } => BlackBoxFunc::Keccak256, BlackBoxFuncCall::Keccakf1600 { .. } => BlackBoxFunc::Keccakf1600, @@ -232,6 +240,7 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::BigIntDiv { .. } | BlackBoxFuncCall::BigIntToLeBytes { .. } => Vec::new(), BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], + BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, .. } => vec![*point_x, *point_y, *low, *high], BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, .. } => vec![*input1_x, *input1_y, *input2_x, *input2_y], @@ -329,6 +338,7 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::PedersenHash { output, .. } | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output], BlackBoxFuncCall::FixedBaseScalarMul { outputs, .. } + | BlackBoxFuncCall::VariableBaseScalarMul { outputs, .. } | BlackBoxFuncCall::PedersenCommitment { outputs, .. } | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => vec![outputs.0, outputs.1], BlackBoxFuncCall::RANGE { .. } diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index c5912b61cf15..9db55f05995e 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -85,6 +85,8 @@ fn fixed_base_scalar_mul_circuit() { assert_eq!(bytes, expected_serialization) } +// TODO(benesjan): variable_base_scalar_mul_circuit test + #[test] fn pedersen_circuit() { let pedersen = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::PedersenCommitment { diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts b/noir/noir-repo/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts index 259c51ed1c62..f6287c2ae8a1 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/browser/execute_circuit.test.ts @@ -103,6 +103,16 @@ it('successfully executes a FixedBaseScalarMul opcode', async () => { expect(solvedWitness).to.be.deep.eq(expectedWitnessMap); }); +it('successfully executes a VariableBaseScalarMul opcode', async () => { + const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/variable_base_scalar_mul'); + + const solvedWitness: WitnessMap = await executeCircuit(bytecode, initialWitnessMap, () => { + throw Error('unexpected oracle'); + }); + + expect(solvedWitness).to.be.deep.eq(expectedWitnessMap); +}); + it('successfully executes a SchnorrVerify opcode', async () => { const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/schnorr_verify'); diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/node/execute_circuit.test.ts b/noir/noir-repo/acvm-repo/acvm_js/test/node/execute_circuit.test.ts index 32487f8bbbac..f9fd5c10b3ee 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/node/execute_circuit.test.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/node/execute_circuit.test.ts @@ -100,6 +100,16 @@ it('successfully executes a FixedBaseScalarMul opcode', async () => { expect(solvedWitness).to.be.deep.eq(expectedWitnessMap); }); +it('successfully executes a VariableBaseScalarMul opcode', async () => { + const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/variable_base_scalar_mul'); + + const solvedWitness: WitnessMap = await executeCircuit(bytecode, initialWitnessMap, () => { + throw Error('unexpected oracle'); + }); + + expect(solvedWitness).to.be.deep.eq(expectedWitnessMap); +}); + it('successfully executes a SchnorrVerify opcode', async () => { const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/schnorr_verify'); diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index a3d13984d5d2..d8d2283a65c3 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -92,6 +92,15 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::FixedBaseScalarMul)) } + fn variable_base_scalar_mul( + &self, + _point_x: &FieldElement, + _point_y: &FieldElement, + _low: &FieldElement, + _high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + Err(Self::fail(BlackBoxFunc::VariableBaseScalarMul)) + } fn ec_add( &self, _input1_x: &FieldElement, diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 38713c775eee..2765e57d94e4 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -148,7 +148,7 @@ pub(crate) fn evaluate_black_box( let point_y = memory.read(*point_y).try_into().unwrap(); let low = memory.read(*low).try_into().unwrap(); let high = memory.read(*high).try_into().unwrap(); - let (x, y) = solver.fixed_base_scalar_mul(&low, &high)?; + let (x, y) = solver.variable_base_scalar_mul(&point_x, &point_y, &low, &high)?; memory.write_slice(memory.read_ref(result.pointer), &[point_x.into(), point_y.into(), x.into(), y.into()]); Ok(()) } From 08f7786b947795e391cd19f7f2f2f7cfe4fe6ed6 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 11:26:40 +0000 Subject: [PATCH 04/32] re-generating codegen/acir.cpp --- .../noir-repo/acvm-repo/acir/codegen/acir.cpp | 128 +++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 0ad193fedf65..3f9f446e0d52 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -145,6 +145,18 @@ namespace Program { static FixedBaseScalarMul bincodeDeserialize(std::vector); }; + struct VariableBaseScalarMul { + Program::FunctionInput point_x; + Program::FunctionInput point_y; + Program::FunctionInput low; + Program::FunctionInput high; + std::array outputs; + + friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); + std::vector bincodeSerialize() const; + static VariableBaseScalarMul bincodeDeserialize(std::vector); + }; + struct EmbeddedCurveAdd { Program::FunctionInput input1_x; Program::FunctionInput input1_y; @@ -266,7 +278,7 @@ namespace Program { static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); std::vector bincodeSerialize() const; @@ -729,6 +741,18 @@ namespace Program { static FixedBaseScalarMul bincodeDeserialize(std::vector); }; + struct VariableBaseScalarMul { + Program::MemoryAddress point_x; + Program::MemoryAddress point_y; + Program::MemoryAddress low; + Program::MemoryAddress high; + Program::HeapArray result; + + friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); + std::vector bincodeSerialize() const; + static VariableBaseScalarMul bincodeDeserialize(std::vector); + }; + struct EmbeddedCurveAdd { Program::MemoryAddress input1_x; Program::MemoryAddress input1_y; @@ -820,7 +844,7 @@ namespace Program { static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; @@ -2690,6 +2714,56 @@ Program::BlackBoxFuncCall::FixedBaseScalarMul serde::Deserializable BlackBoxFuncCall::VariableBaseScalarMul::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::VariableBaseScalarMul BlackBoxFuncCall::VariableBaseScalarMul::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlackBoxFuncCall::VariableBaseScalarMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.point_x, serializer); + serde::Serializable::serialize(obj.point_y, serializer); + serde::Serializable::serialize(obj.low, serializer); + serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.outputs, serializer); +} + +template <> +template +Program::BlackBoxFuncCall::VariableBaseScalarMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::BlackBoxFuncCall::VariableBaseScalarMul obj; + obj.point_x = serde::Deserializable::deserialize(deserializer); + obj.point_y = serde::Deserializable::deserialize(deserializer); + obj.low = serde::Deserializable::deserialize(deserializer); + obj.high = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Program { inline bool operator==(const BlackBoxFuncCall::EmbeddedCurveAdd &lhs, const BlackBoxFuncCall::EmbeddedCurveAdd &rhs) { @@ -3750,6 +3824,56 @@ Program::BlackBoxOp::FixedBaseScalarMul serde::Deserializable BlackBoxOp::VariableBaseScalarMul::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::VariableBaseScalarMul BlackBoxOp::VariableBaseScalarMul::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BlackBoxOp::VariableBaseScalarMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.point_x, serializer); + serde::Serializable::serialize(obj.point_y, serializer); + serde::Serializable::serialize(obj.low, serializer); + serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Program::BlackBoxOp::VariableBaseScalarMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::BlackBoxOp::VariableBaseScalarMul obj; + obj.point_x = serde::Deserializable::deserialize(deserializer); + obj.point_y = serde::Deserializable::deserialize(deserializer); + obj.low = serde::Deserializable::deserialize(deserializer); + obj.high = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Program { inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd &lhs, const BlackBoxOp::EmbeddedCurveAdd &rhs) { From a7a5e391123c740e37545bde1626497136e7c178 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 11:53:46 +0000 Subject: [PATCH 05/32] It compiles! --- .../dsl/acir_format/acir_to_constraint_buf.hpp | 4 ++-- .../noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs | 2 +- .../src/fixed_base_scalar_mul.rs | 2 +- .../acvm-repo/bn254_blackbox_solver/src/lib.rs | 12 +++++++++++- .../src/brillig/brillig_ir/debug_show.rs | 2 +- noir/noir-repo/tooling/lsp/src/solver.rs | 10 ++++++++++ 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp index e82a1ec38d03..b14f27620745 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp @@ -319,8 +319,8 @@ void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg, Aci }); } else if constexpr (std::is_same_v) { af.variable_base_scalar_mul_constraints.push_back(VariableBaseScalarMul{ - .point_x = arg.low.witness.point_x, - .point_y = arg.low.witness.point_y, + .point_x = arg.point_x.witness.value, + .point_y = arg.point_y.witness.value, .low = arg.low.witness.value, .high = arg.high.witness.value, .pub_key_x = arg.outputs[0].value, diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 9673ba3467be..29cd9dca6e27 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -20,7 +20,7 @@ mod pedersen; mod range; mod signature; -use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul}; +use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul, variable_base_scalar_mul}; // Hash functions should eventually be exposed for external consumers. use hash::{solve_generic_256_hash_opcode, solve_sha_256_permutation_opcode}; use logic::{and, xor}; diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 90be1a79bb45..725a8d00bc79 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -66,7 +66,7 @@ pub fn variable_base_scalar_mul( low: &FieldElement, high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - let point1 = create_point(point_x, point_y) + let point1 = create_point(*point_x, *point_y) .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; let low: u128 = low.try_into_u128().ok_or_else(|| { diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs index 25b10252a784..8db97a434241 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -9,7 +9,7 @@ mod fixed_base_scalar_mul; mod poseidon2; mod wasm; -pub use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul}; +pub use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul, variable_base_scalar_mul}; pub use poseidon2::poseidon2_permutation; use wasm::Barretenberg; @@ -97,6 +97,16 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { fixed_base_scalar_mul(low, high) } + fn variable_base_scalar_mul( + &self, + point_x: &FieldElement, + point_y: &FieldElement, + low: &FieldElement, + high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + variable_base_scalar_mul(point_x, point_y, low, high) + } + fn ec_add( &self, input1_x: &FieldElement, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 5a2a9eeeaf44..fb8cfee685ef 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -327,7 +327,7 @@ impl DebugShow { BlackBoxOp::VariableBaseScalarMul { point_x, point_y, low, high, result } => { debug_println!( self.enable_debug_trace, - " VARIABLE_BASE_SCALAR_MUL {} {} -> {}", + " VARIABLE_BASE_SCALAR_MUL ({} {}) ({} {}) -> {}", point_x, point_y, low, diff --git a/noir/noir-repo/tooling/lsp/src/solver.rs b/noir/noir-repo/tooling/lsp/src/solver.rs index 0fea9b16b54a..9bbb203a136c 100644 --- a/noir/noir-repo/tooling/lsp/src/solver.rs +++ b/noir/noir-repo/tooling/lsp/src/solver.rs @@ -32,6 +32,16 @@ impl BlackBoxFunctionSolver for WrapperSolver { self.0.fixed_base_scalar_mul(low, high) } + fn variable_base_scalar_mul( + &self, + point_x: &acvm::FieldElement, + point_y: &acvm::FieldElement, + low: &acvm::FieldElement, + high: &acvm::FieldElement, + ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { + self.0.variable_base_scalar_mul(point_x, point_y, low, high) + } + fn pedersen_hash( &self, inputs: &[acvm::FieldElement], From e3183a0f5a352eac0ddf49783da50465ad9ac0ae Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 11:58:23 +0000 Subject: [PATCH 06/32] cargo fmt --- .../src/circuit/opcodes/black_box_function_call.rs | 4 +++- noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs | 10 +++++++++- .../bn254_blackbox_solver/src/fixed_base_scalar_mul.rs | 6 ++---- .../acvm-repo/bn254_blackbox_solver/src/lib.rs | 4 +++- noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs | 5 ++++- .../src/ssa/acir_gen/acir_ir/generated_acir.rs | 4 +++- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 5858eb554cc2..195aff6bc0ff 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -240,7 +240,9 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::BigIntDiv { .. } | BlackBoxFuncCall::BigIntToLeBytes { .. } => Vec::new(), BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], - BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, .. } => vec![*point_x, *point_y, *low, *high], + BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, .. } => { + vec![*point_x, *point_y, *low, *high] + } BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, .. } => vec![*input1_x, *input1_y, *input2_x, *input2_y], diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 29cd9dca6e27..f4a59e094159 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -159,7 +159,15 @@ pub(crate) fn solve( fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs) } BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, outputs } => { - variable_base_scalar_mul(backend, initial_witness, *point_x, *point_y, *low, *high, *outputs) + variable_base_scalar_mul( + backend, + initial_witness, + *point_x, + *point_y, + *low, + *high, + *outputs, + ) } BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, outputs } => { embedded_curve_add( diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 725a8d00bc79..28b131f54f96 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -67,7 +67,7 @@ pub fn variable_base_scalar_mul( high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { let point1 = create_point(*point_x, *point_y) - .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; + .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; let low: u128 = low.try_into_u128().ok_or_else(|| { BlackBoxResolutionError::Failed( @@ -96,9 +96,7 @@ pub fn variable_base_scalar_mul( )); } - let result = grumpkin::SWAffine::from( - point1.mul_bigint(grumpkin_integer.to_u64_digits()), - ); + let result = grumpkin::SWAffine::from(point1.mul_bigint(grumpkin_integer.to_u64_digits())); if let Some((res_x, res_y)) = result.xy() { Ok((FieldElement::from_repr(*res_x), FieldElement::from_repr(*res_y))) } else { diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs index 8db97a434241..9395260fe36a 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -9,7 +9,9 @@ mod fixed_base_scalar_mul; mod poseidon2; mod wasm; -pub use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul, variable_base_scalar_mul}; +pub use fixed_base_scalar_mul::{ + embedded_curve_add, fixed_base_scalar_mul, variable_base_scalar_mul, +}; pub use poseidon2::poseidon2_permutation; use wasm::Barretenberg; diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 2765e57d94e4..c40462105b9e 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -149,7 +149,10 @@ pub(crate) fn evaluate_black_box( let low = memory.read(*low).try_into().unwrap(); let high = memory.read(*high).try_into().unwrap(); let (x, y) = solver.variable_base_scalar_mul(&point_x, &point_y, &low, &high)?; - memory.write_slice(memory.read_ref(result.pointer), &[point_x.into(), point_y.into(), x.into(), y.into()]); + memory.write_slice( + memory.read_ref(result.pointer), + &[point_x.into(), point_y.into(), x.into(), y.into()], + ); Ok(()) } BlackBoxOp::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, result } => { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index e761e483e7ff..3597d2500d90 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -734,7 +734,9 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { // Output of operations over the embedded curve // will be 2 field elements representing the point. - BlackBoxFunc::FixedBaseScalarMul | BlackBoxFunc::VariableBaseScalarMul | BlackBoxFunc::EmbeddedCurveAdd => Some(2), + BlackBoxFunc::FixedBaseScalarMul + | BlackBoxFunc::VariableBaseScalarMul + | BlackBoxFunc::EmbeddedCurveAdd => Some(2), // Big integer operations return a big integer BlackBoxFunc::BigIntAdd From a1aadbce344a8899726846126936fb991a006c25 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 12:10:28 +0000 Subject: [PATCH 07/32] test: variable_base_scalar_mul_circuit --- .../acir/tests/test_program_serialization.rs | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index 9db55f05995e..97804d77a4ab 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -85,7 +85,37 @@ fn fixed_base_scalar_mul_circuit() { assert_eq!(bytes, expected_serialization) } -// TODO(benesjan): variable_base_scalar_mul_circuit test +#[test] +fn variable_base_scalar_mul_circuit() { + let variable_base_scalar_mul = + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::VariableBaseScalarMul { + point_x: FunctionInput { witness: Witness(1), num_bits: 128 }, + point_y: FunctionInput { witness: Witness(2), num_bits: 128 }, + low: FunctionInput { witness: Witness(3), num_bits: 128 }, + high: FunctionInput { witness: Witness(4), num_bits: 128 }, + outputs: (Witness(5), Witness(6)), + }); + + let circuit = Circuit { + current_witness_index: 7, + opcodes: vec![variable_base_scalar_mul], + private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3), Witness(4)]), + return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(5), Witness(6)])), + ..Circuit::default() + }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; + + let bytes = Program::serialize_program(&program); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 139, 65, 10, 0, 32, 8, 4, 213, 172, 46, 61, 186, + 167, 103, 52, 65, 185, 176, 140, 44, 142, 202, 73, 143, 42, 247, 230, 128, 51, 106, 176, + 64, 135, 53, 218, 112, 252, 113, 141, 223, 187, 9, 155, 36, 231, 203, 2, 176, 218, 19, 62, + 137, 0, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} #[test] fn pedersen_circuit() { From e57e66329997159375352a4879c534c54c57edff Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 12:29:42 +0000 Subject: [PATCH 08/32] added missing initializers --- .../cpp/src/barretenberg/dsl/acir_format/acir_format.hpp | 1 + .../src/barretenberg/dsl/acir_format/acir_format.test.cpp | 6 ++++++ .../barretenberg/dsl/acir_format/bigint_constraint.test.cpp | 5 +++++ .../barretenberg/dsl/acir_format/block_constraint.test.cpp | 1 + .../src/barretenberg/dsl/acir_format/ec_operations.test.cpp | 1 + .../barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp | 3 +++ .../barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp | 4 ++++ .../dsl/acir_format/poseidon2_constraint.test.cpp | 1 + .../dsl/acir_format/recursion_constraint.test.cpp | 2 ++ .../barretenberg/dsl/acir_format/sha256_constraint.test.cpp | 1 + 10 files changed, 25 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index a6ddd729ac24..a7f5b4757375 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -84,6 +84,7 @@ struct AcirFormat { pedersen_hash_constraints, poseidon2_constraints, fixed_base_scalar_mul_constraints, + variable_base_scalar_mul_constraints, ec_add_constraints, recursion_constraints, poly_triple_constraints, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index c7d44e319413..7de0f847b1f7 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -48,6 +48,7 @@ TEST_F(AcirFormatTests, TestASingleConstraintNoPubInputs) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -164,6 +165,7 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -232,6 +234,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -327,6 +330,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -441,6 +445,7 @@ TEST_F(AcirFormatTests, TestVarKeccak) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -488,6 +493,7 @@ TEST_F(AcirFormatTests, TestKeccakPermutation) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp index 584f7ef62a56..3b32c7f26950 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp @@ -185,6 +185,7 @@ TEST_F(BigIntTests, TestBigIntConstraintMultiple) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -253,6 +254,7 @@ TEST_F(BigIntTests, TestBigIntConstraintSimple) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = { from_le_bytes_constraint_bigint1 }, @@ -306,6 +308,7 @@ TEST_F(BigIntTests, TestBigIntConstraintReuse) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -363,6 +366,7 @@ TEST_F(BigIntTests, TestBigIntConstraintReuse2) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -441,6 +445,7 @@ TEST_F(BigIntTests, TestBigIntDIV) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = { from_le_bytes_constraint_bigint1, from_le_bytes_constraint_bigint2 }, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 20f9e8072bba..75b9150d335c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -127,6 +127,7 @@ TEST_F(UltraPlonkRAM, TestBlockConstraint) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp index 92c76e3d7a37..bdda21409a17 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp @@ -67,6 +67,7 @@ TEST_F(EcOperations, TestECOperations) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = { ec_add_constraint }, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index 0a11adb97be2..c494cc13e798 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -107,6 +107,7 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintSucceed) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -156,6 +157,7 @@ TEST_F(ECDSASecp256k1, TestECDSACompilesForVerifier) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -200,6 +202,7 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintFail) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp index 6cf542bc2d6e..6728445d2371 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp @@ -141,6 +141,7 @@ TEST(ECDSASecp256r1, test_hardcoded) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -192,6 +193,7 @@ TEST(ECDSASecp256r1, TestECDSAConstraintSucceed) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -241,6 +243,7 @@ TEST(ECDSASecp256r1, TestECDSACompilesForVerifier) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -285,6 +288,7 @@ TEST(ECDSASecp256r1, TestECDSAConstraintFail) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp index f509c262782a..f672505b4d70 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp @@ -47,6 +47,7 @@ TEST_F(Poseidon2Tests, TestPoseidon2Permutation) .pedersen_hash_constraints = {}, .poseidon2_constraints = { poseidon2_constraint }, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp index bbf7768abc91..97e53d30c627 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp @@ -99,6 +99,7 @@ Builder create_inner_circuit() .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, @@ -256,6 +257,7 @@ Builder create_outer_circuit(std::vector& inner_circuits) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = recursion_constraints, .bigint_from_le_bytes_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp index 6266253ee552..aa520806b2b7 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp @@ -49,6 +49,7 @@ TEST_F(Sha256Tests, TestSha256Compression) .pedersen_hash_constraints = {}, .poseidon2_constraints = {}, .fixed_base_scalar_mul_constraints = {}, + .variable_base_scalar_mul_constraints = {}, .ec_add_constraints = {}, .recursion_constraints = {}, .bigint_from_le_bytes_constraints = {}, From fe04f76f2fdcefe2e01a40ad5cbc2fa9e0414d84 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 12:43:33 +0000 Subject: [PATCH 09/32] test: variable_base_matches_fixed_base_for_generator_on_input --- .../src/fixed_base_scalar_mul.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 28b131f54f96..2d520cb91ee9 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -193,7 +193,22 @@ mod grumpkin_fixed_base_scalar_mul { ); } - // TODO(benesjan): variable_base_scalar_mul tests + #[test] + fn variable_base_matches_fixed_base_for_generator_on_input( + ) -> Result<(), BlackBoxResolutionError> { + let low = FieldElement::one(); + let high = FieldElement::from(2u128); + + let generator = grumpkin::SWAffine::generator(); + let generator_x = FieldElement::from_repr(*generator.x().unwrap()); + let generator_y = FieldElement::from_repr(*generator.y().unwrap()); + + let fixed_res = fixed_base_scalar_mul(&low, &high)?; + let variable_res = variable_base_scalar_mul(&generator_x, &generator_y, &low, &high)?; + + assert_eq!(fixed_res, variable_res); + Ok(()) + } #[test] fn rejects_addition_of_points_not_in_curve() { From e7d1aeba8f347acd5eb071f6a04b2abe030fc233 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 13:27:50 +0000 Subject: [PATCH 10/32] making fixed_base_scalar_mul call variable_base_scalar_mul --- .../src/pwg/blackbox/fixed_base_scalar_mul.rs | 2 +- .../src/fixed_base_scalar_mul.rs | 46 ++++--------------- 2 files changed, 9 insertions(+), 39 deletions(-) diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs index 52adb35e9ced..9fad5f216602 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -1,3 +1,4 @@ +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6058): rename this file to something more generic use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, @@ -24,7 +25,6 @@ pub(super) fn fixed_base_scalar_mul( Ok(()) } -// TODO(benesjan): rename this file to something more generic? pub(super) fn variable_base_scalar_mul( backend: &impl BlackBoxFunctionSolver, initial_witness: &mut WitnessMap, diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 2d520cb91ee9..44dd649415ff 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -1,3 +1,4 @@ +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6058): rename this file to something more generic use ark_ec::AffineRepr; use ark_ff::MontConfig; use num_bigint::BigUint; @@ -6,45 +7,16 @@ use acir::{BlackBoxFunc, FieldElement}; use crate::BlackBoxResolutionError; +/// Performs fixed-base scalar multiplication by calling variable_base_scalar_mul with a predefined generator point. pub fn fixed_base_scalar_mul( low: &FieldElement, high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - let low: u128 = low.try_into_u128().ok_or_else(|| { - BlackBoxResolutionError::Failed( - BlackBoxFunc::FixedBaseScalarMul, - format!("Limb {} is not less than 2^128", low.to_hex()), - ) - })?; + let generator = grumpkin::SWAffine::generator(); + let generator_x = FieldElement::from_repr(*generator.x().unwrap()); + let generator_y = FieldElement::from_repr(*generator.y().unwrap()); - let high: u128 = high.try_into_u128().ok_or_else(|| { - BlackBoxResolutionError::Failed( - BlackBoxFunc::FixedBaseScalarMul, - format!("Limb {} is not less than 2^128", high.to_hex()), - ) - })?; - - let mut bytes = high.to_be_bytes().to_vec(); - bytes.extend_from_slice(&low.to_be_bytes()); - - // Check if this is smaller than the grumpkin modulus - let grumpkin_integer = BigUint::from_bytes_be(&bytes); - - if grumpkin_integer >= grumpkin::FrConfig::MODULUS.into() { - return Err(BlackBoxResolutionError::Failed( - BlackBoxFunc::FixedBaseScalarMul, - format!("{} is not a valid grumpkin scalar", grumpkin_integer.to_str_radix(16)), - )); - } - - let result = grumpkin::SWAffine::from( - grumpkin::SWAffine::generator().mul_bigint(grumpkin_integer.to_u64_digits()), - ); - if let Some((res_x, res_y)) = result.xy() { - Ok((FieldElement::from_repr(*res_x), FieldElement::from_repr(*res_y))) - } else { - Ok((FieldElement::zero(), FieldElement::zero())) - } + variable_base_scalar_mul(&generator_x, &generator_y, low, high) } fn create_point(x: FieldElement, y: FieldElement) -> Result { @@ -58,8 +30,6 @@ fn create_point(x: FieldElement, y: FieldElement) -> Result Date: Fri, 26 Apr 2024 14:23:04 +0000 Subject: [PATCH 11/32] better naming --- .../acir_format/acir_to_constraint_buf.hpp | 8 ++--- .../dsl/acir_format/serde/acir.hpp | 32 +++++++++---------- .../acir_format/variable_base_scalar_mul.cpp | 10 +++--- .../acir_format/variable_base_scalar_mul.hpp | 10 +++--- noir/noir-repo/acvm-repo/acir/README.md | 2 +- .../noir-repo/acvm-repo/acir/codegen/acir.cpp | 32 +++++++++---------- .../opcodes/black_box_function_call.rs | 14 +++++--- .../acir/tests/test_program_serialization.rs | 4 +-- .../src/pwg/blackbox/fixed_base_scalar_mul.rs | 15 +++++---- .../acvm-repo/acvm/src/pwg/blackbox/mod.rs | 26 ++++++++------- .../src/curve_specific_solver.rs | 8 ++--- .../src/fixed_base_scalar_mul.rs | 16 +++++----- .../acvm-repo/brillig/src/black_box.rs | 4 +-- .../acvm-repo/brillig_vm/src/black_box.rs | 11 ++++--- .../brillig/brillig_gen/brillig_black_box.rs | 6 ++-- .../src/brillig/brillig_ir/debug_show.rs | 12 +++++-- .../ssa/acir_gen/acir_ir/generated_acir.rs | 4 +-- noir/noir-repo/tooling/lsp/src/solver.rs | 6 ++-- 18 files changed, 119 insertions(+), 101 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp index b14f27620745..f31fc73c806a 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp @@ -321,10 +321,10 @@ void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg, Aci af.variable_base_scalar_mul_constraints.push_back(VariableBaseScalarMul{ .point_x = arg.point_x.witness.value, .point_y = arg.point_y.witness.value, - .low = arg.low.witness.value, - .high = arg.high.witness.value, - .pub_key_x = arg.outputs[0].value, - .pub_key_y = arg.outputs[1].value, + .scalar_low = arg.scalar_low.witness.value, + .scalar_high = arg.scalar_high.witness.value, + .out_point_x = arg.outputs[0].value, + .out_point_y = arg.outputs[1].value, }); } else if constexpr (std::is_same_v) { af.ec_add_constraints.push_back(EcAdd{ diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index 1cdc8a7a7330..bdfb6605ad24 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -148,8 +148,8 @@ struct BlackBoxFuncCall { struct VariableBaseScalarMul { Program::FunctionInput point_x; Program::FunctionInput point_y; - Program::FunctionInput low; - Program::FunctionInput high; + Program::FunctionInput scalar_low; + Program::FunctionInput scalar_high; std::array outputs; friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); @@ -769,8 +769,8 @@ struct BlackBoxOp { struct VariableBaseScalarMul { Program::MemoryAddress point_x; Program::MemoryAddress point_y; - Program::MemoryAddress low; - Program::MemoryAddress high; + Program::MemoryAddress scalar_low; + Program::MemoryAddress scalar_high; Program::HeapArray result; friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); @@ -3103,10 +3103,10 @@ inline bool operator==(const BlackBoxFuncCall::VariableBaseScalarMul& lhs, if (!(lhs.point_y == rhs.point_y)) { return false; } - if (!(lhs.low == rhs.low)) { + if (!(lhs.scalar_low == rhs.scalar_low)) { return false; } - if (!(lhs.high == rhs.high)) { + if (!(lhs.scalar_high == rhs.scalar_high)) { return false; } if (!(lhs.outputs == rhs.outputs)) { @@ -3142,8 +3142,8 @@ void serde::Serializable::seri { serde::Serializable::serialize(obj.point_x, serializer); serde::Serializable::serialize(obj.point_y, serializer); - serde::Serializable::serialize(obj.low, serializer); - serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.scalar_low, serializer); + serde::Serializable::serialize(obj.scalar_high, serializer); serde::Serializable::serialize(obj.outputs, serializer); } @@ -3155,8 +3155,8 @@ Program::BlackBoxFuncCall::VariableBaseScalarMul serde::Deserializable< Program::BlackBoxFuncCall::VariableBaseScalarMul obj; obj.point_x = serde::Deserializable::deserialize(deserializer); obj.point_y = serde::Deserializable::deserialize(deserializer); - obj.low = serde::Deserializable::deserialize(deserializer); - obj.high = serde::Deserializable::deserialize(deserializer); + obj.scalar_low = serde::Deserializable::deserialize(deserializer); + obj.scalar_high = serde::Deserializable::deserialize(deserializer); obj.outputs = serde::Deserializable::deserialize(deserializer); return obj; } @@ -4547,10 +4547,10 @@ inline bool operator==(const BlackBoxOp::VariableBaseScalarMul& lhs, const Black if (!(lhs.point_y == rhs.point_y)) { return false; } - if (!(lhs.low == rhs.low)) { + if (!(lhs.scalar_low == rhs.scalar_low)) { return false; } - if (!(lhs.high == rhs.high)) { + if (!(lhs.scalar_high == rhs.scalar_high)) { return false; } if (!(lhs.result == rhs.result)) { @@ -4586,8 +4586,8 @@ void serde::Serializable::serialize( { serde::Serializable::serialize(obj.point_x, serializer); serde::Serializable::serialize(obj.point_y, serializer); - serde::Serializable::serialize(obj.low, serializer); - serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.scalar_low, serializer); + serde::Serializable::serialize(obj.scalar_high, serializer); serde::Serializable::serialize(obj.result, serializer); } @@ -4599,8 +4599,8 @@ Program::BlackBoxOp::VariableBaseScalarMul serde::Deserializable< Program::BlackBoxOp::VariableBaseScalarMul obj; obj.point_x = serde::Deserializable::deserialize(deserializer); obj.point_y = serde::Deserializable::deserialize(deserializer); - obj.low = serde::Deserializable::deserialize(deserializer); - obj.high = serde::Deserializable::deserialize(deserializer); + obj.scalar_low = serde::Deserializable::deserialize(deserializer); + obj.scalar_high = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp index 9137cb0fc28f..6446b68158c4 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.cpp @@ -18,16 +18,16 @@ template void create_variable_base_constraint(Builder& builde cycle_group_ct input_point(point_x, point_y, false); // We reconstruct the scalar from the low and high limbs - field_ct low_as_field = field_ct::from_witness_index(&builder, input.low); - field_ct high_as_field = field_ct::from_witness_index(&builder, input.high); - cycle_scalar_ct scalar(low_as_field, high_as_field); + field_ct scalar_low_as_field = field_ct::from_witness_index(&builder, input.scalar_low); + field_ct scalar_high_as_field = field_ct::from_witness_index(&builder, input.scalar_high); + cycle_scalar_ct scalar(scalar_low_as_field, scalar_high_as_field); // We multiply the scalar with input point/variable base to get the result auto result = input_point * scalar; // Finally we add the constraints - builder.assert_equal(result.x.get_witness_index(), input.pub_key_x); - builder.assert_equal(result.y.get_witness_index(), input.pub_key_y); + builder.assert_equal(result.x.get_witness_index(), input.out_point_x); + builder.assert_equal(result.y.get_witness_index(), input.out_point_y); } template void create_variable_base_constraint(UltraCircuitBuilder& builder, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp index 91b433b4bcc1..d903df2cb322 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/variable_base_scalar_mul.hpp @@ -8,13 +8,13 @@ namespace acir_format { struct VariableBaseScalarMul { uint32_t point_x; uint32_t point_y; - uint32_t low; - uint32_t high; - uint32_t pub_key_x; - uint32_t pub_key_y; + uint32_t scalar_low; + uint32_t scalar_high; + uint32_t out_point_x; + uint32_t out_point_y; // for serialization, update with any new fields - MSGPACK_FIELDS(point_x, point_y, low, high, pub_key_x, pub_key_y); + MSGPACK_FIELDS(point_x, point_y, scalar_low, scalar_high, out_point_x, out_point_y); friend bool operator==(VariableBaseScalarMul const& lhs, VariableBaseScalarMul const& rhs) = default; }; diff --git a/noir/noir-repo/acvm-repo/acir/README.md b/noir/noir-repo/acvm-repo/acir/README.md index ae219023e08d..e72f7ea178d8 100644 --- a/noir/noir-repo/acvm-repo/acir/README.md +++ b/noir/noir-repo/acvm-repo/acir/README.md @@ -149,7 +149,7 @@ $a=low+high*2^{128},$ with $low, high < 2^{128}$ **VariableBaseScalarMul**: scalar multiplication with a variable base/input point (P) of the embedded curve - input: point_x, point_y representing x and y coordinates of input point P - low, high are 2 (field , 254), representing the low and high part of the input scalar. For Barretenberg, they must both be less than 128 bits. + scalar_low, scalar_high are 2 (field , 254), representing the low and high part of the input scalar. For Barretenberg, they must both be less than 128 bits. - output: x and y coordinates of $low*P+high*2^{128}*P$, where P is the input point P Because the Grumpkin scalar field is bigger than the ACIR field, we provide 2 ACIR fields representing the low and high parts of the Grumpkin scalar $a$: diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 3f9f446e0d52..1e5207c01cbb 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -148,8 +148,8 @@ namespace Program { struct VariableBaseScalarMul { Program::FunctionInput point_x; Program::FunctionInput point_y; - Program::FunctionInput low; - Program::FunctionInput high; + Program::FunctionInput scalar_low; + Program::FunctionInput scalar_high; std::array outputs; friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); @@ -744,8 +744,8 @@ namespace Program { struct VariableBaseScalarMul { Program::MemoryAddress point_x; Program::MemoryAddress point_y; - Program::MemoryAddress low; - Program::MemoryAddress high; + Program::MemoryAddress scalar_low; + Program::MemoryAddress scalar_high; Program::HeapArray result; friend bool operator==(const VariableBaseScalarMul&, const VariableBaseScalarMul&); @@ -2719,8 +2719,8 @@ namespace Program { inline bool operator==(const BlackBoxFuncCall::VariableBaseScalarMul &lhs, const BlackBoxFuncCall::VariableBaseScalarMul &rhs) { if (!(lhs.point_x == rhs.point_x)) { return false; } if (!(lhs.point_y == rhs.point_y)) { return false; } - if (!(lhs.low == rhs.low)) { return false; } - if (!(lhs.high == rhs.high)) { return false; } + if (!(lhs.scalar_low == rhs.scalar_low)) { return false; } + if (!(lhs.scalar_high == rhs.scalar_high)) { return false; } if (!(lhs.outputs == rhs.outputs)) { return false; } return true; } @@ -2747,8 +2747,8 @@ template void serde::Serializable::serialize(const Program::BlackBoxFuncCall::VariableBaseScalarMul &obj, Serializer &serializer) { serde::Serializable::serialize(obj.point_x, serializer); serde::Serializable::serialize(obj.point_y, serializer); - serde::Serializable::serialize(obj.low, serializer); - serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.scalar_low, serializer); + serde::Serializable::serialize(obj.scalar_high, serializer); serde::Serializable::serialize(obj.outputs, serializer); } @@ -2758,8 +2758,8 @@ Program::BlackBoxFuncCall::VariableBaseScalarMul serde::Deserializable::deserialize(deserializer); obj.point_y = serde::Deserializable::deserialize(deserializer); - obj.low = serde::Deserializable::deserialize(deserializer); - obj.high = serde::Deserializable::deserialize(deserializer); + obj.scalar_low = serde::Deserializable::deserialize(deserializer); + obj.scalar_high = serde::Deserializable::deserialize(deserializer); obj.outputs = serde::Deserializable::deserialize(deserializer); return obj; } @@ -3829,8 +3829,8 @@ namespace Program { inline bool operator==(const BlackBoxOp::VariableBaseScalarMul &lhs, const BlackBoxOp::VariableBaseScalarMul &rhs) { if (!(lhs.point_x == rhs.point_x)) { return false; } if (!(lhs.point_y == rhs.point_y)) { return false; } - if (!(lhs.low == rhs.low)) { return false; } - if (!(lhs.high == rhs.high)) { return false; } + if (!(lhs.scalar_low == rhs.scalar_low)) { return false; } + if (!(lhs.scalar_high == rhs.scalar_high)) { return false; } if (!(lhs.result == rhs.result)) { return false; } return true; } @@ -3857,8 +3857,8 @@ template void serde::Serializable::serialize(const Program::BlackBoxOp::VariableBaseScalarMul &obj, Serializer &serializer) { serde::Serializable::serialize(obj.point_x, serializer); serde::Serializable::serialize(obj.point_y, serializer); - serde::Serializable::serialize(obj.low, serializer); - serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.scalar_low, serializer); + serde::Serializable::serialize(obj.scalar_high, serializer); serde::Serializable::serialize(obj.result, serializer); } @@ -3868,8 +3868,8 @@ Program::BlackBoxOp::VariableBaseScalarMul serde::Deserializable::deserialize(deserializer); obj.point_y = serde::Deserializable::deserialize(deserializer); - obj.low = serde::Deserializable::deserialize(deserializer); - obj.high = serde::Deserializable::deserialize(deserializer); + obj.scalar_low = serde::Deserializable::deserialize(deserializer); + obj.scalar_high = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 195aff6bc0ff..5715019937c2 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -88,8 +88,8 @@ pub enum BlackBoxFuncCall { VariableBaseScalarMul { point_x: FunctionInput, point_y: FunctionInput, - low: FunctionInput, - high: FunctionInput, + scalar_low: FunctionInput, + scalar_high: FunctionInput, outputs: (Witness, Witness), }, EmbeddedCurveAdd { @@ -240,8 +240,14 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::BigIntDiv { .. } | BlackBoxFuncCall::BigIntToLeBytes { .. } => Vec::new(), BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], - BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, .. } => { - vec![*point_x, *point_y, *low, *high] + BlackBoxFuncCall::VariableBaseScalarMul { + point_x, + point_y, + scalar_low, + scalar_high, + .. + } => { + vec![*point_x, *point_y, *scalar_low, *scalar_high] } BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, .. diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index 97804d77a4ab..2ad082410a1b 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -91,8 +91,8 @@ fn variable_base_scalar_mul_circuit() { Opcode::BlackBoxFuncCall(BlackBoxFuncCall::VariableBaseScalarMul { point_x: FunctionInput { witness: Witness(1), num_bits: 128 }, point_y: FunctionInput { witness: Witness(2), num_bits: 128 }, - low: FunctionInput { witness: Witness(3), num_bits: 128 }, - high: FunctionInput { witness: Witness(4), num_bits: 128 }, + scalar_low: FunctionInput { witness: Witness(3), num_bits: 128 }, + scalar_high: FunctionInput { witness: Witness(4), num_bits: 128 }, outputs: (Witness(5), Witness(6)), }); diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs index 9fad5f216602..aea02a5b5a34 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -30,19 +30,20 @@ pub(super) fn variable_base_scalar_mul( initial_witness: &mut WitnessMap, point_x: FunctionInput, point_y: FunctionInput, - low: FunctionInput, - high: FunctionInput, + scalar_low: FunctionInput, + scalar_high: FunctionInput, outputs: (Witness, Witness), ) -> Result<(), OpcodeResolutionError> { let point_x = witness_to_value(initial_witness, point_x.witness)?; let point_y = witness_to_value(initial_witness, point_y.witness)?; - let low = witness_to_value(initial_witness, low.witness)?; - let high = witness_to_value(initial_witness, high.witness)?; + let scalar_low = witness_to_value(initial_witness, scalar_low.witness)?; + let scalar_high = witness_to_value(initial_witness, scalar_high.witness)?; - let (pub_x, pub_y) = backend.variable_base_scalar_mul(point_x, point_y, low, high)?; + let (out_point_x, out_point_y) = + backend.variable_base_scalar_mul(point_x, point_y, scalar_low, scalar_high)?; - insert_value(&outputs.0, pub_x, initial_witness)?; - insert_value(&outputs.1, pub_y, initial_witness)?; + insert_value(&outputs.0, out_point_x, initial_witness)?; + insert_value(&outputs.1, out_point_y, initial_witness)?; Ok(()) } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index f4a59e094159..eb86c11d1c3a 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -158,17 +158,21 @@ pub(crate) fn solve( BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => { fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs) } - BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, low, high, outputs } => { - variable_base_scalar_mul( - backend, - initial_witness, - *point_x, - *point_y, - *low, - *high, - *outputs, - ) - } + BlackBoxFuncCall::VariableBaseScalarMul { + point_x, + point_y, + scalar_low: low, + scalar_high: high, + outputs, + } => variable_base_scalar_mul( + backend, + initial_witness, + *point_x, + *point_y, + *low, + *high, + *outputs, + ), BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, outputs } => { embedded_curve_add( backend, diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index d8d2283a65c3..a809e21e2ca9 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -33,8 +33,8 @@ pub trait BlackBoxFunctionSolver { &self, point_x: &FieldElement, point_y: &FieldElement, - low: &FieldElement, - high: &FieldElement, + scalar_low: &FieldElement, + scalar_high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; fn ec_add( &self, @@ -96,8 +96,8 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { &self, _point_x: &FieldElement, _point_y: &FieldElement, - _low: &FieldElement, - _high: &FieldElement, + _scalar_low: &FieldElement, + _scalar_high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::VariableBaseScalarMul)) } diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 44dd649415ff..7d1c9bf648c7 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -33,28 +33,28 @@ fn create_point(x: FieldElement, y: FieldElement) -> Result Result<(FieldElement, FieldElement), BlackBoxResolutionError> { let point1 = create_point(*point_x, *point_y) .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; - let low: u128 = low.try_into_u128().ok_or_else(|| { + let scalar_low: u128 = scalar_low.try_into_u128().ok_or_else(|| { BlackBoxResolutionError::Failed( BlackBoxFunc::VariableBaseScalarMul, - format!("Limb {} is not less than 2^128", low.to_hex()), + format!("Limb {} is not less than 2^128", scalar_low.to_hex()), ) })?; - let high: u128 = high.try_into_u128().ok_or_else(|| { + let scalar_high: u128 = scalar_high.try_into_u128().ok_or_else(|| { BlackBoxResolutionError::Failed( BlackBoxFunc::VariableBaseScalarMul, - format!("Limb {} is not less than 2^128", high.to_hex()), + format!("Limb {} is not less than 2^128", scalar_high.to_hex()), ) })?; - let mut bytes = high.to_be_bytes().to_vec(); - bytes.extend_from_slice(&low.to_be_bytes()); + let mut bytes = scalar_high.to_be_bytes().to_vec(); + bytes.extend_from_slice(&scalar_low.to_be_bytes()); // Check if this is smaller than the grumpkin modulus let grumpkin_integer = BigUint::from_bytes_be(&bytes); diff --git a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs index 5744321d2433..f31a434c7725 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs @@ -76,8 +76,8 @@ pub enum BlackBoxOp { VariableBaseScalarMul { point_x: MemoryAddress, point_y: MemoryAddress, - low: MemoryAddress, - high: MemoryAddress, + scalar_low: MemoryAddress, + scalar_high: MemoryAddress, result: HeapArray, }, /// Performs addition over the embedded curve. diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index c40462105b9e..9bfd6b3345eb 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -143,15 +143,16 @@ pub(crate) fn evaluate_black_box( memory.write_slice(memory.read_ref(result.pointer), &[x.into(), y.into()]); Ok(()) } - BlackBoxOp::VariableBaseScalarMul { point_x, point_y, low, high, result } => { + BlackBoxOp::VariableBaseScalarMul { point_x, point_y, scalar_low, scalar_high, result } => { let point_x = memory.read(*point_x).try_into().unwrap(); let point_y = memory.read(*point_y).try_into().unwrap(); - let low = memory.read(*low).try_into().unwrap(); - let high = memory.read(*high).try_into().unwrap(); - let (x, y) = solver.variable_base_scalar_mul(&point_x, &point_y, &low, &high)?; + let scalar_low = memory.read(*scalar_low).try_into().unwrap(); + let scalar_high = memory.read(*scalar_high).try_into().unwrap(); + let (out_point_x, out_point_y) = + solver.variable_base_scalar_mul(&point_x, &point_y, &scalar_low, &scalar_high)?; memory.write_slice( memory.read_ref(result.pointer), - &[point_x.into(), point_y.into(), x.into(), y.into()], + &[point_x.into(), point_y.into(), out_point_x.into(), out_point_y.into()], ); Ok(()) } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index 68233c6e4a3d..e794e6aac92b 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -207,15 +207,15 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::VariableBaseScalarMul => { if let ( - [BrilligVariable::SingleAddr(point_x), BrilligVariable::SingleAddr(point_y), BrilligVariable::SingleAddr(low), BrilligVariable::SingleAddr(high)], + [BrilligVariable::SingleAddr(point_x), BrilligVariable::SingleAddr(point_y), BrilligVariable::SingleAddr(scalar_low), BrilligVariable::SingleAddr(scalar_high)], [BrilligVariable::BrilligArray(result_array)], ) = (function_arguments, function_results) { brillig_context.black_box_op_instruction(BlackBoxOp::VariableBaseScalarMul { point_x: point_x.address, point_y: point_y.address, - low: low.address, - high: high.address, + scalar_low: scalar_low.address, + scalar_high: scalar_high.address, result: result_array.to_heap_array(), }); } else { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index fb8cfee685ef..8b00939b3a71 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -324,14 +324,20 @@ impl DebugShow { result ); } - BlackBoxOp::VariableBaseScalarMul { point_x, point_y, low, high, result } => { + BlackBoxOp::VariableBaseScalarMul { + point_x, + point_y, + scalar_low, + scalar_high, + result, + } => { debug_println!( self.enable_debug_trace, " VARIABLE_BASE_SCALAR_MUL ({} {}) ({} {}) -> {}", point_x, point_y, - low, - high, + scalar_low, + scalar_high, result ); } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 3597d2500d90..2f4f4f9f6cc7 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -286,8 +286,8 @@ impl GeneratedAcir { BlackBoxFunc::VariableBaseScalarMul => BlackBoxFuncCall::VariableBaseScalarMul { point_x: inputs[0][0], point_y: inputs[1][0], - low: inputs[2][0], - high: inputs[3][0], + scalar_low: inputs[2][0], + scalar_high: inputs[3][0], outputs: (outputs[0], outputs[1]), }, BlackBoxFunc::EmbeddedCurveAdd => BlackBoxFuncCall::EmbeddedCurveAdd { diff --git a/noir/noir-repo/tooling/lsp/src/solver.rs b/noir/noir-repo/tooling/lsp/src/solver.rs index 9bbb203a136c..b47c30af5f68 100644 --- a/noir/noir-repo/tooling/lsp/src/solver.rs +++ b/noir/noir-repo/tooling/lsp/src/solver.rs @@ -36,10 +36,10 @@ impl BlackBoxFunctionSolver for WrapperSolver { &self, point_x: &acvm::FieldElement, point_y: &acvm::FieldElement, - low: &acvm::FieldElement, - high: &acvm::FieldElement, + scalar_low: &acvm::FieldElement, + scalar_high: &acvm::FieldElement, ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { - self.0.variable_base_scalar_mul(point_x, point_y, low, high) + self.0.variable_base_scalar_mul(point_x, point_y, scalar_low, scalar_high) } fn pedersen_hash( From e7746c1f178050296b667f0b95ff6d152bce5b93 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 14:29:59 +0000 Subject: [PATCH 12/32] cleanup --- .../acvm-repo/acvm/src/pwg/blackbox/mod.rs | 8 +++---- .../src/fixed_base_scalar_mul.rs | 22 +++++++++---------- noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 8 +++---- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index eb86c11d1c3a..2487d511b502 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -161,16 +161,16 @@ pub(crate) fn solve( BlackBoxFuncCall::VariableBaseScalarMul { point_x, point_y, - scalar_low: low, - scalar_high: high, + scalar_low, + scalar_high, outputs, } => variable_base_scalar_mul( backend, initial_witness, *point_x, *point_y, - *low, - *high, + *scalar_low, + *scalar_high, *outputs, ), BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, outputs } => { diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 7d1c9bf648c7..7191d97a3b39 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -19,17 +19,6 @@ pub fn fixed_base_scalar_mul( variable_base_scalar_mul(&generator_x, &generator_y, low, high) } -fn create_point(x: FieldElement, y: FieldElement) -> Result { - let point = grumpkin::SWAffine::new_unchecked(x.into_repr(), y.into_repr()); - if !point.is_on_curve() { - return Err(format!("Point ({}, {}) is not on curve", x.to_hex(), y.to_hex())); - }; - if !point.is_in_correct_subgroup_assuming_on_curve() { - return Err(format!("Point ({}, {}) is not in correct subgroup", x.to_hex(), y.to_hex())); - }; - Ok(point) -} - pub fn variable_base_scalar_mul( point_x: &FieldElement, point_y: &FieldElement, @@ -95,6 +84,17 @@ pub fn embedded_curve_add( } } +fn create_point(x: FieldElement, y: FieldElement) -> Result { + let point = grumpkin::SWAffine::new_unchecked(x.into_repr(), y.into_repr()); + if !point.is_on_curve() { + return Err(format!("Point ({}, {}) is not on curve", x.to_hex(), y.to_hex())); + }; + if !point.is_in_correct_subgroup_assuming_on_curve() { + return Err(format!("Point ({}, {}) is not in correct subgroup", x.to_hex(), y.to_hex())); + }; + Ok(point) +} + #[cfg(test)] mod grumpkin_fixed_base_scalar_mul { use ark_ff::BigInteger; diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index 7f63a028755f..ed4645427b87 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -26,8 +26,8 @@ impl Add for EmbeddedCurvePoint { #[foreign(fixed_base_scalar_mul)] // docs:start:fixed_base_embedded_curve pub fn fixed_base_embedded_curve( - low: Field, - high: Field + low: Field, // low limb of the scalar + high: Field // high limb of the scalar ) -> [Field; 2] // docs:end:fixed_base_embedded_curve {} @@ -35,8 +35,8 @@ pub fn fixed_base_embedded_curve( #[foreign(variable_base_scalar_mul)] pub fn variable_base_embedded_curve( point: EmbeddedCurvePoint, // point to multiply the scalar with - low: Field, // low limb of the scalar - high: Field // high limb of the scalar + scalar_low: Field, // low limb of the scalar + scalar_high: Field // high limb of the scalar ) -> [Field; 2] {} From fae4540c016e9e3a652fbc3fc1f3a2186fe84a6d Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 14:49:16 +0000 Subject: [PATCH 13/32] exposing new functionality in grumpkin_scalar_mul.nr --- .../crates/types/src/grumpkin_point.nr | 1 + noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr | 7 ++++++- noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr b/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr index 965654ac144e..189f9de1602e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr @@ -3,6 +3,7 @@ use dep::std::cmp::Eq; global GRUMPKIN_POINT_SERIALIZED_LEN: Field = 2; +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061) struct GrumpkinPoint { x: Field, y: Field, diff --git a/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr index 06d30d623321..222f69cf68ae 100644 --- a/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr @@ -1,7 +1,12 @@ use crate::grumpkin_scalar::GrumpkinScalar; -use crate::scalar_mul::fixed_base_embedded_curve; +use crate::scalar_mul::{fixed_base_embedded_curve, variable_base_embedded_curve}; pub fn grumpkin_fixed_base(scalar: GrumpkinScalar) -> [Field; 2] { // TODO: this should use both the low and high limbs to do the scalar multiplication fixed_base_embedded_curve(scalar.low, scalar.high) } + +pub fn grumpkin_variable_base(point_x: Field, point_y: Field, scalar: GrumpkinScalar) -> [Field; 2] { + // TODO: this should use both the low and high limbs to do the scalar multiplication + variable_base_embedded_curve(point_x, point_y, scalar.low, scalar.high) +} \ No newline at end of file diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index ed4645427b87..d68553238ef7 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -1,5 +1,6 @@ use crate::ops::Add; +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061) struct EmbeddedCurvePoint { x: Field, y: Field, @@ -32,9 +33,11 @@ pub fn fixed_base_embedded_curve( // docs:end:fixed_base_embedded_curve {} +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061): use a point struct instead of two fields #[foreign(variable_base_scalar_mul)] pub fn variable_base_embedded_curve( - point: EmbeddedCurvePoint, // point to multiply the scalar with + point_x: Field, // x coordinate of a point to multiply the scalar with + point_y: Field, // y coordinate of a point to multiply the scalar with scalar_low: Field, // low limb of the scalar scalar_high: Field // high limb of the scalar ) -> [Field; 2] From 6ea6718b82a24e05ee31541e395242783d9b707d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Fri, 26 Apr 2024 20:06:42 +0200 Subject: [PATCH 14/32] Apply suggestions from code review Co-authored-by: Maxim Vezenov --- .../bn254_blackbox_solver/src/fixed_base_scalar_mul.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 7191d97a3b39..b08a922c8e64 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -16,7 +16,11 @@ pub fn fixed_base_scalar_mul( let generator_x = FieldElement::from_repr(*generator.x().unwrap()); let generator_y = FieldElement::from_repr(*generator.y().unwrap()); - variable_base_scalar_mul(&generator_x, &generator_y, low, high) + variable_base_scalar_mul(&generator_x, &generator_y, low, high).map_err(|err| match err { + BlackBoxResolutionError::Failed(_, message) => { + BlackBoxResolutionError::Failed(BlackBoxFunc::FixedBaseScalarMul, message) + } + } } pub fn variable_base_scalar_mul( @@ -134,7 +138,7 @@ mod grumpkin_fixed_base_scalar_mul { let invalid_limb = max_limb + FieldElement::one(); let expected_error = Err(BlackBoxResolutionError::Failed( - BlackBoxFunc::VariableBaseScalarMul, + BlackBoxFunc::FixedBaseScalarMul, "Limb 0000000000000000000000000000000100000000000000000000000000000000 is not less than 2^128".into(), )); From 0d09ea11c58276076ce367cdb416daefc24a18e3 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 18:07:45 +0000 Subject: [PATCH 15/32] nuking stale TODOs --- noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr | 2 -- 1 file changed, 2 deletions(-) diff --git a/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr index 222f69cf68ae..9c983583094f 100644 --- a/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr @@ -2,11 +2,9 @@ use crate::grumpkin_scalar::GrumpkinScalar; use crate::scalar_mul::{fixed_base_embedded_curve, variable_base_embedded_curve}; pub fn grumpkin_fixed_base(scalar: GrumpkinScalar) -> [Field; 2] { - // TODO: this should use both the low and high limbs to do the scalar multiplication fixed_base_embedded_curve(scalar.low, scalar.high) } pub fn grumpkin_variable_base(point_x: Field, point_y: Field, scalar: GrumpkinScalar) -> [Field; 2] { - // TODO: this should use both the low and high limbs to do the scalar multiplication variable_base_embedded_curve(point_x, point_y, scalar.low, scalar.high) } \ No newline at end of file From 44164b206ae72161e1b4a9c16dbdbab38f7bfb04 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 26 Apr 2024 18:25:19 +0000 Subject: [PATCH 16/32] invalid point test + fixes --- .../src/fixed_base_scalar_mul.rs | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index b08a922c8e64..5161497452b4 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -17,10 +17,10 @@ pub fn fixed_base_scalar_mul( let generator_y = FieldElement::from_repr(*generator.y().unwrap()); variable_base_scalar_mul(&generator_x, &generator_y, low, high).map_err(|err| match err { - BlackBoxResolutionError::Failed(_, message) => { - BlackBoxResolutionError::Failed(BlackBoxFunc::FixedBaseScalarMul, message) - } - } + BlackBoxResolutionError::Failed(_, message) => { + BlackBoxResolutionError::Failed(BlackBoxFunc::FixedBaseScalarMul, message) + } + }) } pub fn variable_base_scalar_mul( @@ -30,7 +30,7 @@ pub fn variable_base_scalar_mul( scalar_high: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { let point1 = create_point(*point_x, *point_y) - .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; + .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::VariableBaseScalarMul, e))?; let scalar_low: u128 = scalar_low.try_into_u128().ok_or_else(|| { BlackBoxResolutionError::Failed( @@ -184,6 +184,29 @@ mod grumpkin_fixed_base_scalar_mul { Ok(()) } + #[test] + fn variable_base_scalar_mul_rejects_invalid_point() { + let invalid_point_x = FieldElement::one(); + let invalid_point_y = FieldElement::one(); + let valid_scalar_low = FieldElement::zero(); + let valid_scalar_high = FieldElement::zero(); + + let res = variable_base_scalar_mul( + &invalid_point_x, + &invalid_point_y, + &valid_scalar_low, + &valid_scalar_high, + ); + + assert_eq!( + res, + Err(BlackBoxResolutionError::Failed( + BlackBoxFunc::VariableBaseScalarMul, + "Point (0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000001) is not on curve".into(), + )) + ); + } + #[test] fn rejects_addition_of_points_not_in_curve() { let x = FieldElement::from(1u128); From 2a3070be4e474e2e30adf79e89291543ab0589d1 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 06:40:05 +0000 Subject: [PATCH 17/32] test fix --- .../bn254_blackbox_solver/src/fixed_base_scalar_mul.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 5161497452b4..14c23c09f976 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -161,7 +161,7 @@ mod grumpkin_fixed_base_scalar_mul { assert_eq!( res, Err(BlackBoxResolutionError::Failed( - BlackBoxFunc::VariableBaseScalarMul, + BlackBoxFunc::FixedBaseScalarMul, "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 is not a valid grumpkin scalar".into(), )) ); From 91020e734a942f46ec7985620ca5d63359330906 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 07:50:50 +0000 Subject: [PATCH 18/32] fix --- .../compiler/noirc_evaluator/src/brillig/brillig_ir.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index ded41e02bdae..b4ed59de59d9 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -175,6 +175,16 @@ pub(crate) mod tests { Ok((4_u128.into(), 5_u128.into())) } + fn variable_base_scalar_mul( + &self, + _point_x: &FieldElement, + _point_y: &FieldElement, + _scalar_low: &FieldElement, + _scalar_high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + Ok((7_u128.into(), 8_u128.into())) + } + fn ec_add( &self, _input1_x: &FieldElement, From 11a549b5e729d20e76e99608d1101ebd58ff7ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Mon, 29 Apr 2024 12:26:51 +0200 Subject: [PATCH 19/32] Apply suggestions from code review --- .../bn254_blackbox_solver/src/fixed_base_scalar_mul.rs | 2 +- noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 14c23c09f976..8ec5298a5067 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -7,7 +7,7 @@ use acir::{BlackBoxFunc, FieldElement}; use crate::BlackBoxResolutionError; -/// Performs fixed-base scalar multiplication by calling variable_base_scalar_mul with a predefined generator point. +/// Performs fixed-base scalar multiplication using the curve's generator point. pub fn fixed_base_scalar_mul( low: &FieldElement, high: &FieldElement, diff --git a/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr index 9c983583094f..c1195073ef6d 100644 --- a/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/grumpkin_scalar_mul.nr @@ -3,8 +3,4 @@ use crate::scalar_mul::{fixed_base_embedded_curve, variable_base_embedded_curve} pub fn grumpkin_fixed_base(scalar: GrumpkinScalar) -> [Field; 2] { fixed_base_embedded_curve(scalar.low, scalar.high) -} - -pub fn grumpkin_variable_base(point_x: Field, point_y: Field, scalar: GrumpkinScalar) -> [Field; 2] { - variable_base_embedded_curve(point_x, point_y, scalar.low, scalar.high) } \ No newline at end of file From b60575ed567a081693c951769f10fa7a98f2e8dd Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 10:36:22 +0000 Subject: [PATCH 20/32] updated issue --- .../noir-protocol-circuits/crates/types/src/grumpkin_point.nr | 2 +- .../acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs | 2 +- .../bn254_blackbox_solver/src/fixed_base_scalar_mul.rs | 2 +- noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr b/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr index 189f9de1602e..ec334d78b50f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/grumpkin_point.nr @@ -3,7 +3,7 @@ use dep::std::cmp::Eq; global GRUMPKIN_POINT_SERIALIZED_LEN: Field = 2; -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061) +// TODO(https://github.com/noir-lang/noir/issues/4931) struct GrumpkinPoint { x: Field, y: Field, diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs index aea02a5b5a34..79e33ae8de53 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -1,4 +1,4 @@ -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6058): rename this file to something more generic +// TODO(https://github.com/noir-lang/noir/issues/4932): rename this file to something more generic use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 8ec5298a5067..2d7ffe1cf1c8 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -1,4 +1,4 @@ -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6058): rename this file to something more generic +// TODO(https://github.com/noir-lang/noir/issues/4932): rename this file to something more generic use ark_ec::AffineRepr; use ark_ff::MontConfig; use num_bigint::BigUint; diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index d68553238ef7..6ac0fa8872d9 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -1,6 +1,6 @@ use crate::ops::Add; -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061) +// TODO(https://github.com/noir-lang/noir/issues/4931) struct EmbeddedCurvePoint { x: Field, y: Field, @@ -33,7 +33,7 @@ pub fn fixed_base_embedded_curve( // docs:end:fixed_base_embedded_curve {} -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061): use a point struct instead of two fields +// TODO(https://github.com/noir-lang/noir/issues/4931): use a point struct instead of two fields #[foreign(variable_base_scalar_mul)] pub fn variable_base_embedded_curve( point_x: Field, // x coordinate of a point to multiply the scalar with From 98cfd05675cc1b0105acc82f2760baa33ddd8544 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 12:27:02 +0000 Subject: [PATCH 21/32] variable_base_scalar_mul integration test --- .../Nargo.toml | 2 +- .../Prover.toml | 0 .../src/main.nr | 0 .../variable_base_scalar_mul/Nargo.toml | 6 ++++++ .../variable_base_scalar_mul/Prover.toml | 4 ++++ .../variable_base_scalar_mul/src/main.nr | 19 +++++++++++++++++++ 6 files changed, 30 insertions(+), 1 deletion(-) rename noir/noir-repo/test_programs/execution_success/{scalar_mul => fixed_base_scalar_mul}/Nargo.toml (63%) rename noir/noir-repo/test_programs/execution_success/{scalar_mul => fixed_base_scalar_mul}/Prover.toml (100%) rename noir/noir-repo/test_programs/execution_success/{scalar_mul => fixed_base_scalar_mul}/src/main.nr (100%) create mode 100644 noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Nargo.toml create mode 100644 noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Prover.toml create mode 100644 noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr diff --git a/noir/noir-repo/test_programs/execution_success/scalar_mul/Nargo.toml b/noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/Nargo.toml similarity index 63% rename from noir/noir-repo/test_programs/execution_success/scalar_mul/Nargo.toml rename to noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/Nargo.toml index 926114ec3745..a8e45c9b5ade 100644 --- a/noir/noir-repo/test_programs/execution_success/scalar_mul/Nargo.toml +++ b/noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "scalar_mul" +name = "fixed_base_scalar_mul" type = "bin" authors = [""] diff --git a/noir/noir-repo/test_programs/execution_success/scalar_mul/Prover.toml b/noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/Prover.toml similarity index 100% rename from noir/noir-repo/test_programs/execution_success/scalar_mul/Prover.toml rename to noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/Prover.toml diff --git a/noir/noir-repo/test_programs/execution_success/scalar_mul/src/main.nr b/noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/src/main.nr similarity index 100% rename from noir/noir-repo/test_programs/execution_success/scalar_mul/src/main.nr rename to noir/noir-repo/test_programs/execution_success/fixed_base_scalar_mul/src/main.nr diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Nargo.toml b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Nargo.toml new file mode 100644 index 000000000000..66712ab503cb --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "variable_base_scalar_mul" +type = "bin" +authors = [""] + +[dependencies] diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Prover.toml b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Prover.toml new file mode 100644 index 000000000000..51d6fc9b96c5 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/Prover.toml @@ -0,0 +1,4 @@ +point_x = "0x0000000000000000000000000000000000000000000000000000000000000001" +point_y = "0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c" +scalar_low = "0x0000000000000000000000000000000000000000000000000000000000000003" +scalar_high = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr new file mode 100644 index 000000000000..330101f9e2ac --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr @@ -0,0 +1,19 @@ +use dep::std; + +fn main( + point_x: pub Field, + point_y: pub Field, + scalar_low: pub Field, + scalar_high: pub Field +) { + // We multiply the point by 3 + let res = std::scalar_mul::variable_base_embedded_curve(point_x, point_y, scalar_low, scalar_high); + + let point = std::scalar_mul::EmbeddedCurvePoint { x: point_x, y: point_y }; + + let double = std::scalar_mul::embedded_curve_add(point, point); + let triple = std::scalar_mul::embedded_curve_add(point, double); + + assert(triple.x == res[0]); + assert(triple.y == res[1]); +} From ab81133f3eb5ea8c690cf2160e5c71d31b43d0c9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 12:46:56 +0000 Subject: [PATCH 22/32] docs --- .../cryptographic_primitives/scalar.mdx | 30 +++++++++++++++---- noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 8 +++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx b/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx index c2946b2b73b3..b835236a03e4 100644 --- a/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx +++ b/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx @@ -1,6 +1,6 @@ --- title: Scalar multiplication -description: See how you can perform scalar multiplications over a fixed base in Noir +description: See how you can perform scalar multiplications over a fixed and variable bases in Noir keywords: [cryptographic primitives, Noir project, scalar multiplication] sidebar_position: 1 --- @@ -9,17 +9,35 @@ import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; ## scalar_mul::fixed_base_embedded_curve -Performs scalar multiplication over the embedded curve whose coordinates are defined by the -configured noir field. For the BN254 scalar field, this is BabyJubJub or Grumpkin. +Performs scalar multiplication of a fixed base/generator over the embedded curve whose coordinates are defined +by the configured noir field. For the BN254 scalar field, this is BabyJubJub or Grumpkin. Suffixes `_low` and +`_high` denote low and high limbs of the input scalar. #include_code fixed_base_embedded_curve noir_stdlib/src/scalar_mul.nr rust example ```rust -fn main(x : Field) { - let scal = std::scalar_mul::fixed_base_embedded_curve(x); - println(scal); +fn main(scalar_low: Field, scalar_high: Field) { + let point = std::scalar_mul::fixed_base_embedded_curve(scalar_low, scalar_high); + println(point); +} +``` + +## scalar_mul::variable_base_embedded_curve + +Performs scalar multiplication of a variable base/input point over the embedded curve whose coordinates are defined +by the configured noir field. For the BN254 scalar field, this is BabyJubJub or Grumpkin. Suffixes `_low` and +`_high` denote low and high limbs of the input scalar. + +#include_code variable_base_embedded_curve noir_stdlib/src/scalar_mul.nr rust + +example + +```rust +fn main(point_x: Field, point_y: Field, scalar_low: Field, scalar_high: Field) { + let resulting_point = std::scalar_mul::fixed_base_embedded_curve(point_x, point_y, scalar_low, scalar_high); + println(resulting_point); } ``` diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index 6ac0fa8872d9..457b7b7791c8 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -33,14 +33,22 @@ pub fn fixed_base_embedded_curve( // docs:end:fixed_base_embedded_curve {} +// Computes a variable base scalar multiplication over the embedded curve. +// For bn254, We have Grumpkin and Baby JubJub. +// For bls12-381, we have JubJub and Bandersnatch. +// +// The embedded curve being used is decided by the +// underlying proof system. // TODO(https://github.com/noir-lang/noir/issues/4931): use a point struct instead of two fields #[foreign(variable_base_scalar_mul)] +// docs:start:variable_base_embedded_curve pub fn variable_base_embedded_curve( point_x: Field, // x coordinate of a point to multiply the scalar with point_y: Field, // y coordinate of a point to multiply the scalar with scalar_low: Field, // low limb of the scalar scalar_high: Field // high limb of the scalar ) -> [Field; 2] +// docs:end:variable_base_embedded_curve {} // This is a hack as returning an `EmbeddedCurvePoint` from a foreign function in brillig returns a [BrilligVariable::SingleAddr; 2] rather than BrilligVariable::BrilligArray From 22bac7201084a859644d061047cf3948a60bea9a Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 13:09:51 +0000 Subject: [PATCH 23/32] comment --- .../execution_success/variable_base_scalar_mul/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr index 330101f9e2ac..051a6a977a69 100644 --- a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr @@ -6,7 +6,7 @@ fn main( scalar_low: pub Field, scalar_high: pub Field ) { - // We multiply the point by 3 + // We multiply the point by 3 and check it matches result out of embedded_curve_add func let res = std::scalar_mul::variable_base_embedded_curve(point_x, point_y, scalar_low, scalar_high); let point = std::scalar_mul::EmbeddedCurvePoint { x: point_x, y: point_y }; From b10ca039fd9c9780065229a5f5608c8daa6a75b6 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 13:17:08 +0000 Subject: [PATCH 24/32] more tests --- .../execution_success/variable_base_scalar_mul/src/main.nr | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr index 051a6a977a69..12a86333663d 100644 --- a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr @@ -16,4 +16,9 @@ fn main( assert(triple.x == res[0]); assert(triple.y == res[1]); + + // Multiplying the point by 1 should return the same point + let res = std::scalar_mul::variable_base_embedded_curve(point_x, point_y, 1, 0); + assert(point_x == res[0]); + assert(point_y == res[1]); } From d2dd0c8cd708b1328f1287e8b4799fd944b1e5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Mon, 29 Apr 2024 16:29:53 +0200 Subject: [PATCH 25/32] Update noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs Co-authored-by: Maxim Vezenov --- noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 9bfd6b3345eb..9557cdae7b91 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -152,7 +152,7 @@ pub(crate) fn evaluate_black_box( solver.variable_base_scalar_mul(&point_x, &point_y, &scalar_low, &scalar_high)?; memory.write_slice( memory.read_ref(result.pointer), - &[point_x.into(), point_y.into(), out_point_x.into(), out_point_y.into()], + &[out_point_x.into(), out_point_y.into()], ); Ok(()) } From 1cbdb3af474c7e70f83c6d99feef209a44d9a4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Mon, 29 Apr 2024 16:30:54 +0200 Subject: [PATCH 26/32] Update noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs Co-authored-by: Maxim Vezenov --- .../src/brillig/brillig_gen/brillig_black_box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index e794e6aac92b..a0bdb1cfeb52 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -220,7 +220,7 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: VariableBaseScalarMul expects one register argument and one array result" + "ICE: VariableBaseScalarMul expects four register arguments and one array result" ) } } From 460f9bef0b0bbf934144a2e440c189f4cd77f707 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 14:34:39 +0000 Subject: [PATCH 27/32] error message fix --- .../src/brillig/brillig_gen/brillig_black_box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index a0bdb1cfeb52..210e56b2ecba 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -201,7 +201,7 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: FixedBaseScalarMul expects one register argument and one array result" + "ICE: FixedBaseScalarMul expects two register arguments and one array result" ) } } From e7edbf0d66b61ec4336dd7a2083ea5b44547b62b Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 14:34:55 +0000 Subject: [PATCH 28/32] testing brillig --- noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 2 +- .../variable_base_scalar_mul/src/main.nr | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index 457b7b7791c8..f9086c32bdba 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -53,7 +53,7 @@ pub fn variable_base_embedded_curve( // This is a hack as returning an `EmbeddedCurvePoint` from a foreign function in brillig returns a [BrilligVariable::SingleAddr; 2] rather than BrilligVariable::BrilligArray // as is defined in the brillig bytecode format. This is a workaround which allows us to fix this without modifying the serialization format. -fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { +pub fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { let point_array = embedded_curve_add_array_return(point1, point2); let x = point_array[0]; let y = point_array[1]; diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr index 12a86333663d..18c1b53bcaa0 100644 --- a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr @@ -1,11 +1,6 @@ use dep::std; -fn main( - point_x: pub Field, - point_y: pub Field, - scalar_low: pub Field, - scalar_high: pub Field -) { +fn main(point_x: pub Field, point_y: pub Field, scalar_low: pub Field, scalar_high: pub Field) { // We multiply the point by 3 and check it matches result out of embedded_curve_add func let res = std::scalar_mul::variable_base_embedded_curve(point_x, point_y, scalar_low, scalar_high); @@ -17,8 +12,22 @@ fn main( assert(triple.x == res[0]); assert(triple.y == res[1]); + // We test that brillig gives us the same result + let brillig_res = get_brillig_result(point_x, point_y, scalar_low, scalar_high); + assert(res[0] == brillig_res[0]); + assert(res[1] == brillig_res[1]); + // Multiplying the point by 1 should return the same point let res = std::scalar_mul::variable_base_embedded_curve(point_x, point_y, 1, 0); assert(point_x == res[0]); assert(point_y == res[1]); } + +unconstrained fn get_brillig_result( + point_x: Field, + point_y: Field, + scalar_low: Field, + scalar_high: Field +) -> [Field; 2] { + std::scalar_mul::variable_base_embedded_curve(point_x, point_y, scalar_low, scalar_high) +} From 2505489dca3388e6885015cf53db014061bd3bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Mon, 29 Apr 2024 16:54:23 +0200 Subject: [PATCH 29/32] Update noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --- .../execution_success/variable_base_scalar_mul/src/main.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr index 18c1b53bcaa0..4914ad017771 100644 --- a/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/variable_base_scalar_mul/src/main.nr @@ -6,8 +6,8 @@ fn main(point_x: pub Field, point_y: pub Field, scalar_low: pub Field, scalar_hi let point = std::scalar_mul::EmbeddedCurvePoint { x: point_x, y: point_y }; - let double = std::scalar_mul::embedded_curve_add(point, point); - let triple = std::scalar_mul::embedded_curve_add(point, double); + let double = point.double(); + let triple = point + double; assert(triple.x == res[0]); assert(triple.y == res[1]); From 969c22479157b0a00ce954afcc993ea2ead6bd16 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 29 Apr 2024 14:56:00 +0000 Subject: [PATCH 30/32] un-exposing embedded_curve_add --- noir/noir-repo/noir_stdlib/src/scalar_mul.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr index f9086c32bdba..457b7b7791c8 100644 --- a/noir/noir-repo/noir_stdlib/src/scalar_mul.nr +++ b/noir/noir-repo/noir_stdlib/src/scalar_mul.nr @@ -53,7 +53,7 @@ pub fn variable_base_embedded_curve( // This is a hack as returning an `EmbeddedCurvePoint` from a foreign function in brillig returns a [BrilligVariable::SingleAddr; 2] rather than BrilligVariable::BrilligArray // as is defined in the brillig bytecode format. This is a workaround which allows us to fix this without modifying the serialization format. -pub fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { +fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { let point_array = embedded_curve_add_array_return(point1, point2); let x = point_array[0]; let y = point_array[1]; From 587973ff94368b5ae6247f04c26fd0ef6a933b51 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 30 Apr 2024 08:03:26 +0000 Subject: [PATCH 31/32] acvm_js test fix --- .../test/shared/variable_base_scalar_mul.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 noir/noir-repo/acvm-repo/acvm_js/test/shared/variable_base_scalar_mul.ts diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/variable_base_scalar_mul.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/variable_base_scalar_mul.ts new file mode 100644 index 000000000000..400f7bf4e614 --- /dev/null +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/variable_base_scalar_mul.ts @@ -0,0 +1,21 @@ +// See `variable_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, 139, 65, 10, 0, 32, 8, 4, 213, 172, 46, 61, 186, 167, 103, 52, 65, 185, 176, + 140, 44, 142, 202, 73, 143, 42, 247, 230, 128, 51, 106, 176, 64, 135, 53, 218, 112, 252, 113, 141, 223, 187, 9, 155, + 36, 231, 203, 2, 176, 218, 19, 62, 137, 0, 0, 0, +]); +export const initialWitnessMap = new Map([ + [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [2, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], + [3, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [4, '0x0000000000000000000000000000000000000000000000000000000000000000'], +]); + +export const expectedWitnessMap = new Map([ + [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [2, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], + [3, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [4, '0x0000000000000000000000000000000000000000000000000000000000000000'], + [5, '0x0000000000000000000000000000000000000000000000000000000000000001'], + [6, '0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c'], +]); From fdb0ff40ca961dfe56a09cd572e7ddbff11a3701 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 30 Apr 2024 10:03:22 +0000 Subject: [PATCH 32/32] bumping timeout on state vars e2e --- yarn-project/end-to-end/src/e2e_state_vars.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 8a6ed6dc23ea..8d63cafea4f9 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -22,7 +22,7 @@ describe('e2e_state_vars', () => { beforeAll(async () => { ({ teardown, wallet, pxe } = await setup(2)); contract = await DocsExampleContract.deploy(wallet).send().deployed(); - }, 30_000); + }, 60_000); afterAll(() => teardown());