Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Sync from aztec-packages #6028

Merged
merged 2 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
79995c84e0f88c1ee72876fd21c50c33830597fc
bcec12dbf79b658406dc21083f8fdeef8962085e
7 changes: 6 additions & 1 deletion .github/scripts/cargo-binstall-install.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#!/usr/bin/env bash
set -eu

curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cd $(dirname "$0")

CARGO_BINSTALL_CHECK=$(./command-check.sh cargo-binstall)
if [ $CARGO_BINSTALL_CHECK != "true" ]; then
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
fi
4 changes: 4 additions & 0 deletions .github/scripts/command-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -eu

command -v $1 >/dev/null 2>&1 && echo "true" || { echo >&2 "$1 is not installed" && echo "false"; }
56 changes: 55 additions & 1 deletion acvm-repo/acir/codegen/acir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,16 @@ namespace Program {
static BinaryIntOp bincodeDeserialize(std::vector<uint8_t>);
};

struct Not {
Program::MemoryAddress destination;
Program::MemoryAddress source;
Program::IntegerBitSize bit_size;

friend bool operator==(const Not&, const Not&);
std::vector<uint8_t> bincodeSerialize() const;
static Not bincodeDeserialize(std::vector<uint8_t>);
};

struct Cast {
Program::MemoryAddress destination;
Program::MemoryAddress source;
Expand Down Expand Up @@ -727,7 +737,7 @@ namespace Program {
static Stop bincodeDeserialize(std::vector<uint8_t>);
};

std::variant<BinaryFieldOp, BinaryIntOp, Cast, JumpIfNot, JumpIf, Jump, CalldataCopy, Call, Const, IndirectConst, Return, ForeignCall, Mov, ConditionalMov, Load, Store, BlackBox, Trap, Stop> value;
std::variant<BinaryFieldOp, BinaryIntOp, Not, Cast, JumpIfNot, JumpIf, Jump, CalldataCopy, Call, Const, IndirectConst, Return, ForeignCall, Mov, ConditionalMov, Load, Store, BlackBox, Trap, Stop> value;

friend bool operator==(const BrilligOpcode&, const BrilligOpcode&);
std::vector<uint8_t> bincodeSerialize() const;
Expand Down Expand Up @@ -5110,6 +5120,50 @@ Program::BrilligOpcode::BinaryIntOp serde::Deserializable<Program::BrilligOpcode
return obj;
}

namespace Program {

inline bool operator==(const BrilligOpcode::Not &lhs, const BrilligOpcode::Not &rhs) {
if (!(lhs.destination == rhs.destination)) { return false; }
if (!(lhs.source == rhs.source)) { return false; }
if (!(lhs.bit_size == rhs.bit_size)) { return false; }
return true;
}

inline std::vector<uint8_t> BrilligOpcode::Not::bincodeSerialize() const {
auto serializer = serde::BincodeSerializer();
serde::Serializable<BrilligOpcode::Not>::serialize(*this, serializer);
return std::move(serializer).bytes();
}

inline BrilligOpcode::Not BrilligOpcode::Not::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BrilligOpcode::Not>::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 <typename Serializer>
void serde::Serializable<Program::BrilligOpcode::Not>::serialize(const Program::BrilligOpcode::Not &obj, Serializer &serializer) {
serde::Serializable<decltype(obj.destination)>::serialize(obj.destination, serializer);
serde::Serializable<decltype(obj.source)>::serialize(obj.source, serializer);
serde::Serializable<decltype(obj.bit_size)>::serialize(obj.bit_size, serializer);
}

template <>
template <typename Deserializer>
Program::BrilligOpcode::Not serde::Deserializable<Program::BrilligOpcode::Not>::deserialize(Deserializer &deserializer) {
Program::BrilligOpcode::Not obj;
obj.destination = serde::Deserializable<decltype(obj.destination)>::deserialize(deserializer);
obj.source = serde::Deserializable<decltype(obj.source)>::deserialize(deserializer);
obj.bit_size = serde::Deserializable<decltype(obj.bit_size)>::deserialize(deserializer);
return obj;
}

namespace Program {

inline bool operator==(const BrilligOpcode::Cast &lhs, const BrilligOpcode::Cast &rhs) {
Expand Down
6 changes: 4 additions & 2 deletions acvm-repo/acir/src/circuit/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
mod black_box_function_call;
mod memory_operation;

pub use black_box_function_call::{BlackBoxFuncCall, ConstantOrWitnessEnum, FunctionInput};
pub use black_box_function_call::{
BlackBoxFuncCall, ConstantOrWitnessEnum, FunctionInput, InvalidInputBitSize,
};
pub use memory_operation::{BlockId, MemOp};

#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand All @@ -40,7 +42,7 @@
/// values which define the opcode.
///
/// A general expression of assert-zero opcode is the following:
/// ```
/// ```text
/// \sum_{i,j} {q_M}_{i,j}w_iw_j + \sum_i q_iw_i +q_c = 0
/// ```
///
Expand Down Expand Up @@ -157,7 +159,7 @@

Opcode::BlackBoxFuncCall(g) => write!(f, "{g}"),
Opcode::Directive(Directive::ToLeRadix { a, b, radix: _ }) => {
write!(f, "DIR::TORADIX ")?;

Check warning on line 162 in acvm-repo/acir/src/circuit/opcodes.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (TORADIX)
write!(
f,
// TODO (Note): this assumes that the decomposed bits have contiguous witness indices
Expand Down Expand Up @@ -188,7 +190,7 @@
match databus {
BlockType::Memory => write!(f, "INIT ")?,
BlockType::CallData(id) => write!(f, "INIT CALLDATA {} ", id)?,
BlockType::ReturnData => write!(f, "INIT RETURNDATA ")?,

Check warning on line 193 in acvm-repo/acir/src/circuit/opcodes.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (RETURNDATA)
}
write!(f, "(id: {}, len: {}) ", block_id.0, init.len())
}
Expand Down
36 changes: 31 additions & 5 deletions acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::native_types::Witness;
use crate::BlackBoxFunc;
use crate::{AcirField, BlackBoxFunc};

use serde::{Deserialize, Deserializer, Serialize, Serializer};
use thiserror::Error;

// Note: Some functions will not use all of the witness
// So we need to supply how many bits of the witness is needed
Expand All @@ -13,8 +15,8 @@ pub enum ConstantOrWitnessEnum<F> {

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct FunctionInput<F> {
pub input: ConstantOrWitnessEnum<F>,
pub num_bits: u32,
input: ConstantOrWitnessEnum<F>,
num_bits: u32,
}

impl<F> FunctionInput<F> {
Expand All @@ -25,16 +27,40 @@ impl<F> FunctionInput<F> {
}
}

pub fn input(self) -> ConstantOrWitnessEnum<F> {
self.input
}

pub fn input_ref(&self) -> &ConstantOrWitnessEnum<F> {
&self.input
}

pub fn num_bits(&self) -> u32 {
self.num_bits
}

pub fn witness(witness: Witness, num_bits: u32) -> FunctionInput<F> {
FunctionInput { input: ConstantOrWitnessEnum::Witness(witness), num_bits }
}
}

#[derive(Clone, PartialEq, Eq, Debug, Error)]
#[error("FunctionInput value has too many bits: value: {value}, {value_num_bits} >= {max_bits}")]
pub struct InvalidInputBitSize {
pub value: String,
pub value_num_bits: u32,
pub max_bits: u32,
}

pub fn constant(value: F, num_bits: u32) -> FunctionInput<F> {
FunctionInput { input: ConstantOrWitnessEnum::Constant(value), num_bits }
impl<F: AcirField> FunctionInput<F> {
pub fn constant(value: F, max_bits: u32) -> Result<FunctionInput<F>, InvalidInputBitSize> {
if value.num_bits() <= max_bits {
Ok(FunctionInput { input: ConstantOrWitnessEnum::Constant(value), num_bits: max_bits })
} else {
let value_num_bits = value.num_bits();
let value = format!("{}", value);
Err(InvalidInputBitSize { value, value_num_bits, max_bits })
}
}
}

Expand Down
1 change: 1 addition & 0 deletions acvm-repo/acir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
pub use acir_field::{AcirField, FieldElement};
pub use brillig;
pub use circuit::black_box_functions::BlackBoxFunc;
pub use circuit::opcodes::InvalidInputBitSize;

#[cfg(test)]
mod reflection {
//! Getting test failures? You've probably changed the ACIR serialization format.
//!
//! These tests generate C++ deserializers for [`ACIR bytecode`][super::circuit::Circuit]

Check warning on line 21 in acvm-repo/acir/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (deserializers)
//! and the [`WitnessMap`] structs. These get checked against the C++ files committed to the `codegen` folder
//! to see if changes have been to the serialization format. These are almost always a breaking change!
//!
Expand Down
50 changes: 25 additions & 25 deletions acvm-repo/acir/tests/test_program_serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ fn multi_scalar_mul_circuit() {
let multi_scalar_mul: Opcode<FieldElement> =
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::MultiScalarMul {
points: vec![
FunctionInput::witness(Witness(1), 128),
FunctionInput::witness(Witness(2), 128),
FunctionInput::witness(Witness(1), FieldElement::max_num_bits()),
FunctionInput::witness(Witness(2), FieldElement::max_num_bits()),
FunctionInput::witness(Witness(3), 1),
],
scalars: vec![
FunctionInput::witness(Witness(4), 128),
FunctionInput::witness(Witness(5), 128),
FunctionInput::witness(Witness(4), FieldElement::max_num_bits()),
FunctionInput::witness(Witness(5), FieldElement::max_num_bits()),
],
outputs: (Witness(6), Witness(7), Witness(8)),
});
Expand All @@ -91,10 +91,10 @@ fn multi_scalar_mul_circuit() {
let bytes = Program::serialize_program(&program);

let expected_serialization: Vec<u8> = vec![
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 8, 67, 43, 181, 15, 116, 232,
142, 158, 210, 130, 149, 240, 112, 234, 212, 156, 78, 12, 39, 67, 71, 158, 142, 80, 29, 44,
228, 66, 90, 168, 119, 189, 74, 115, 131, 174, 78, 115, 58, 124, 70, 254, 130, 59, 74, 253,
68, 255, 255, 221, 39, 54, 221, 93, 91, 132, 193, 0, 0, 0,
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 8, 67, 43, 181, 15, 116, 255,
227, 70, 74, 11, 86, 194, 195, 169, 83, 115, 58, 49, 156, 12, 29, 121, 58, 66, 117, 176,
144, 11, 105, 161, 222, 245, 42, 205, 13, 186, 58, 205, 233, 240, 25, 249, 11, 238, 40,
245, 19, 253, 255, 119, 159, 216, 103, 157, 249, 169, 193, 0, 0, 0,
];

assert_eq!(bytes, expected_serialization)
Expand Down Expand Up @@ -214,12 +214,12 @@ fn simple_brillig_foreign_call() {
let bytes = Program::serialize_program(&program);

let expected_serialization: Vec<u8> = vec![
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 49, 10, 128, 48, 12, 108, 196, 138, 224, 230,
75, 226, 15, 252, 140, 131, 139, 131, 136, 239, 111, 161, 9, 28, 165, 205, 210, 28, 132,
36, 119, 16, 114, 9, 133, 130, 53, 7, 73, 29, 37, 107, 143, 80, 238, 148, 204, 99, 56, 200,
111, 22, 227, 190, 83, 93, 16, 146, 193, 112, 22, 225, 34, 168, 205, 142, 174, 241, 218,
206, 179, 121, 49, 188, 109, 57, 84, 191, 159, 255, 122, 63, 235, 199, 189, 190, 197, 237,
13, 45, 1, 20, 245, 146, 30, 92, 2, 0, 0,
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 73, 10, 192, 48, 8, 140, 165, 91, 160, 183,
126, 196, 254, 160, 159, 233, 161, 151, 30, 74, 200, 251, 19, 136, 130, 132, 196, 75, 28,
16, 199, 17, 212, 65, 112, 5, 123, 14, 32, 190, 80, 230, 90, 130, 181, 155, 50, 142, 225,
2, 187, 89, 40, 239, 157, 106, 2, 82, 116, 138, 51, 118, 239, 171, 222, 108, 232, 218, 139,
125, 198, 179, 113, 83, 188, 29, 57, 86, 226, 239, 23, 159, 63, 104, 63, 238, 213, 45, 237,
108, 244, 18, 195, 174, 252, 193, 92, 2, 0, 0,
];

assert_eq!(bytes, expected_serialization)
Expand Down Expand Up @@ -338,17 +338,17 @@ fn complex_brillig_foreign_call() {

let bytes = Program::serialize_program(&program);
let expected_serialization: Vec<u8> = vec![
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 81, 14, 194, 48, 8, 133, 118, 206, 26, 255, 60,
129, 137, 30, 160, 211, 11, 120, 23, 227, 159, 70, 63, 61, 190, 146, 209, 140, 177, 46,
251, 24, 77, 182, 151, 44, 116, 45, 16, 120, 64, 139, 208, 34, 252, 63, 228, 245, 134, 165,
99, 73, 251, 30, 250, 72, 186, 55, 150, 113, 30, 26, 180, 243, 21, 75, 197, 232, 86, 16,
163, 47, 16, 35, 136, 250, 47, 176, 222, 150, 117, 49, 229, 207, 103, 230, 167, 130, 118,
190, 106, 254, 223, 178, 12, 154, 104, 50, 114, 48, 28, 188, 30, 82, 247, 236, 180, 23, 62,
171, 236, 178, 185, 202, 27, 194, 216, 119, 36, 54, 142, 35, 185, 149, 203, 233, 18, 131,
34, 220, 48, 167, 38, 176, 191, 18, 181, 168, 5, 63, 178, 179, 8, 123, 232, 186, 234, 254,
126, 125, 158, 143, 175, 87, 148, 74, 51, 194, 73, 172, 207, 234, 28, 149, 157, 182, 149,
144, 15, 70, 78, 23, 51, 122, 83, 190, 15, 208, 181, 70, 122, 152, 126, 56, 83, 244, 10,
181, 6, 0, 0,
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 81, 14, 194, 48, 8, 133, 118, 186, 53, 241,
207, 11, 152, 232, 1, 58, 189, 128, 119, 49, 254, 105, 244, 211, 227, 59, 50, 154, 49, 214,
100, 31, 163, 201, 246, 146, 133, 174, 5, 10, 15, 72, 17, 122, 52, 221, 135, 188, 222, 177,
116, 44, 105, 223, 195, 24, 73, 247, 206, 50, 46, 67, 139, 118, 190, 98, 169, 24, 221, 6,
98, 244, 5, 98, 4, 81, 255, 21, 214, 219, 178, 46, 166, 252, 249, 204, 252, 84, 208, 207,
215, 158, 255, 107, 150, 141, 38, 154, 140, 28, 76, 7, 111, 132, 212, 61, 65, 201, 116, 86,
217, 101, 115, 11, 226, 62, 99, 223, 145, 88, 56, 205, 228, 102, 127, 239, 53, 6, 69, 184,
97, 78, 109, 96, 127, 37, 106, 81, 11, 126, 100, 103, 17, 14, 48, 116, 213, 227, 243, 254,
190, 158, 63, 175, 40, 149, 102, 132, 179, 88, 95, 212, 57, 42, 59, 109, 43, 33, 31, 140,
156, 46, 102, 244, 230, 124, 31, 97, 104, 141, 244, 48, 253, 1, 180, 46, 168, 159, 181, 6,
0, 0,
];

assert_eq!(bytes, expected_serialization)
Expand Down
42 changes: 28 additions & 14 deletions acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use acir::{
circuit::{
opcodes::{BlackBoxFuncCall, ConstantOrWitnessEnum, FunctionInput},
opcodes::{BlackBoxFuncCall, ConstantOrWitnessEnum},
Circuit, Opcode,
},
native_types::Witness,
Expand Down Expand Up @@ -73,10 +73,13 @@ impl<F: AcirField> RangeOptimizer<F> {
}
}

Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE {
input:
FunctionInput { input: ConstantOrWitnessEnum::Witness(witness), num_bits },
}) => Some((*witness, *num_bits)),
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => {
if let ConstantOrWitnessEnum::Witness(witness) = input.input() {
Some((witness, input.num_bits()))
} else {
None
}
}

_ => None,
}) else {
Expand Down Expand Up @@ -106,17 +109,28 @@ impl<F: AcirField> RangeOptimizer<F> {
let mut new_order_list = Vec::with_capacity(order_list.len());
let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len());
for (idx, opcode) in self.circuit.opcodes.into_iter().enumerate() {
let (witness, num_bits) = match opcode {
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE {
input:
FunctionInput { input: ConstantOrWitnessEnum::Witness(w), num_bits: bits },
}) => (w, bits),
_ => {
// If its not the range opcode, add it to the opcode
// list and continue;
let (witness, num_bits) = {
// If its not the range opcode, add it to the opcode
// list and continue;
let mut push_non_range_opcode = || {
optimized_opcodes.push(opcode.clone());
new_order_list.push(order_list[idx]);
continue;
};

match opcode {
Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => {
match input.input() {
ConstantOrWitnessEnum::Witness(witness) => (witness, input.num_bits()),
_ => {
push_non_range_opcode();
continue;
}
}
}
_ => {
push_non_range_opcode();
continue;
}
}
};
// If we've already applied the range constraint for this witness then skip this opcode.
Expand Down
2 changes: 1 addition & 1 deletion acvm-repo/acvm/src/pwg/blackbox/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl AcvmBigIntSolver {
) -> Result<(), OpcodeResolutionError<F>> {
let bytes = inputs
.iter()
.map(|input| input_to_value(initial_witness, *input).unwrap().to_u128() as u8)
.map(|input| input_to_value(initial_witness, *input, false).unwrap().to_u128() as u8)
.collect::<Vec<u8>>();
self.bigint_solver.bigint_from_bytes(&bytes, modulus, output)?;
Ok(())
Expand Down
16 changes: 8 additions & 8 deletions acvm-repo/acvm/src/pwg/blackbox/embedded_curve_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ pub(super) fn multi_scalar_mul<F: AcirField>(
outputs: (Witness, Witness, Witness),
) -> Result<(), OpcodeResolutionError<F>> {
let points: Result<Vec<_>, _> =
points.iter().map(|input| input_to_value(initial_witness, *input)).collect();
points.iter().map(|input| input_to_value(initial_witness, *input, false)).collect();
let points: Vec<_> = points?.into_iter().collect();

let scalars: Result<Vec<_>, _> =
scalars.iter().map(|input| input_to_value(initial_witness, *input)).collect();
scalars.iter().map(|input| input_to_value(initial_witness, *input, false)).collect();
let mut scalars_lo = Vec::new();
let mut scalars_hi = Vec::new();
for (i, scalar) in scalars?.into_iter().enumerate() {
Expand Down Expand Up @@ -47,12 +47,12 @@ pub(super) fn embedded_curve_add<F: AcirField>(
input2: [FunctionInput<F>; 3],
outputs: (Witness, Witness, Witness),
) -> Result<(), OpcodeResolutionError<F>> {
let input1_x = input_to_value(initial_witness, input1[0])?;
let input1_y = input_to_value(initial_witness, input1[1])?;
let input1_infinite = input_to_value(initial_witness, input1[2])?;
let input2_x = input_to_value(initial_witness, input2[0])?;
let input2_y = input_to_value(initial_witness, input2[1])?;
let input2_infinite = input_to_value(initial_witness, input2[2])?;
let input1_x = input_to_value(initial_witness, input1[0], false)?;
let input1_y = input_to_value(initial_witness, input1[1], false)?;
let input1_infinite = input_to_value(initial_witness, input1[2], false)?;
let input2_x = input_to_value(initial_witness, input2[0], false)?;
let input2_y = input_to_value(initial_witness, input2[1], false)?;
let input2_infinite = input_to_value(initial_witness, input2[2], false)?;
let (res_x, res_y, res_infinite) = backend.ec_add(
&input1_x,
&input1_y,
Expand Down
Loading
Loading