Skip to content

Commit

Permalink
feat!: expose pedersen hash in acir and bb solver (#3269)
Browse files Browse the repository at this point in the history
Co-authored-by: kevaundray <kevtheappdev@gmail.com>
  • Loading branch information
sirasistant and kevaundray authored Oct 25, 2023
1 parent 0ecf0d5 commit 0108b6c
Show file tree
Hide file tree
Showing 209 changed files with 530 additions and 84 deletions.
156 changes: 132 additions & 24 deletions acvm-repo/acir/codegen/acir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,24 @@ namespace Circuit {
static SchnorrVerify bincodeDeserialize(std::vector<uint8_t>);
};

struct Pedersen {
struct PedersenCommitment {
std::vector<Circuit::FunctionInput> inputs;
uint32_t domain_separator;
std::array<Circuit::Witness, 2> outputs;

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

struct PedersenHash {
std::vector<Circuit::FunctionInput> inputs;
uint32_t domain_separator;
Circuit::Witness output;

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

struct HashToField128Security {
Expand Down Expand Up @@ -167,7 +177,7 @@ namespace Circuit {
static RecursiveAggregation bincodeDeserialize(std::vector<uint8_t>);
};

std::variant<AND, XOR, RANGE, SHA256, Blake2s, SchnorrVerify, Pedersen, HashToField128Security, EcdsaSecp256k1, EcdsaSecp256r1, FixedBaseScalarMul, Keccak256, Keccak256VariableLength, RecursiveAggregation> value;
std::variant<AND, XOR, RANGE, SHA256, Blake2s, SchnorrVerify, PedersenCommitment, PedersenHash, HashToField128Security, EcdsaSecp256k1, EcdsaSecp256r1, FixedBaseScalarMul, Keccak256, Keccak256VariableLength, RecursiveAggregation> value;

friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&);
std::vector<uint8_t> bincodeSerialize() const;
Expand Down Expand Up @@ -443,14 +453,24 @@ namespace Circuit {
static SchnorrVerify bincodeDeserialize(std::vector<uint8_t>);
};

struct Pedersen {
struct PedersenCommitment {
Circuit::HeapVector inputs;
Circuit::RegisterIndex domain_separator;
Circuit::HeapArray output;

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

struct PedersenHash {
Circuit::HeapVector inputs;
Circuit::RegisterIndex domain_separator;
Circuit::RegisterIndex output;

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

struct FixedBaseScalarMul {
Expand All @@ -463,7 +483,7 @@ namespace Circuit {
static FixedBaseScalarMul bincodeDeserialize(std::vector<uint8_t>);
};

std::variant<Sha256, Blake2s, Keccak256, HashToField128Security, EcdsaSecp256k1, EcdsaSecp256r1, SchnorrVerify, Pedersen, FixedBaseScalarMul> value;
std::variant<Sha256, Blake2s, Keccak256, HashToField128Security, EcdsaSecp256k1, EcdsaSecp256r1, SchnorrVerify, PedersenCommitment, PedersenHash, FixedBaseScalarMul> value;

friend bool operator==(const BlackBoxOp&, const BlackBoxOp&);
std::vector<uint8_t> bincodeSerialize() const;
Expand Down Expand Up @@ -1871,22 +1891,22 @@ Circuit::BlackBoxFuncCall::SchnorrVerify serde::Deserializable<Circuit::BlackBox

namespace Circuit {

inline bool operator==(const BlackBoxFuncCall::Pedersen &lhs, const BlackBoxFuncCall::Pedersen &rhs) {
inline bool operator==(const BlackBoxFuncCall::PedersenCommitment &lhs, const BlackBoxFuncCall::PedersenCommitment &rhs) {
if (!(lhs.inputs == rhs.inputs)) { return false; }
if (!(lhs.domain_separator == rhs.domain_separator)) { return false; }
if (!(lhs.outputs == rhs.outputs)) { return false; }
return true;
}

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

inline BlackBoxFuncCall::Pedersen BlackBoxFuncCall::Pedersen::bincodeDeserialize(std::vector<uint8_t> input) {
inline BlackBoxFuncCall::PedersenCommitment BlackBoxFuncCall::PedersenCommitment::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BlackBoxFuncCall::Pedersen>::deserialize(deserializer);
auto value = serde::Deserializable<BlackBoxFuncCall::PedersenCommitment>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
Expand All @@ -1897,22 +1917,66 @@ namespace Circuit {

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BlackBoxFuncCall::Pedersen>::serialize(const Circuit::BlackBoxFuncCall::Pedersen &obj, Serializer &serializer) {
void serde::Serializable<Circuit::BlackBoxFuncCall::PedersenCommitment>::serialize(const Circuit::BlackBoxFuncCall::PedersenCommitment &obj, Serializer &serializer) {
serde::Serializable<decltype(obj.inputs)>::serialize(obj.inputs, serializer);
serde::Serializable<decltype(obj.domain_separator)>::serialize(obj.domain_separator, serializer);
serde::Serializable<decltype(obj.outputs)>::serialize(obj.outputs, serializer);
}

template <>
template <typename Deserializer>
Circuit::BlackBoxFuncCall::Pedersen serde::Deserializable<Circuit::BlackBoxFuncCall::Pedersen>::deserialize(Deserializer &deserializer) {
Circuit::BlackBoxFuncCall::Pedersen obj;
Circuit::BlackBoxFuncCall::PedersenCommitment serde::Deserializable<Circuit::BlackBoxFuncCall::PedersenCommitment>::deserialize(Deserializer &deserializer) {
Circuit::BlackBoxFuncCall::PedersenCommitment obj;
obj.inputs = serde::Deserializable<decltype(obj.inputs)>::deserialize(deserializer);
obj.domain_separator = serde::Deserializable<decltype(obj.domain_separator)>::deserialize(deserializer);
obj.outputs = serde::Deserializable<decltype(obj.outputs)>::deserialize(deserializer);
return obj;
}

namespace Circuit {

inline bool operator==(const BlackBoxFuncCall::PedersenHash &lhs, const BlackBoxFuncCall::PedersenHash &rhs) {
if (!(lhs.inputs == rhs.inputs)) { return false; }
if (!(lhs.domain_separator == rhs.domain_separator)) { return false; }
if (!(lhs.output == rhs.output)) { return false; }
return true;
}

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

inline BlackBoxFuncCall::PedersenHash BlackBoxFuncCall::PedersenHash::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BlackBoxFuncCall::PedersenHash>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
return value;
}

} // end of namespace Circuit

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BlackBoxFuncCall::PedersenHash>::serialize(const Circuit::BlackBoxFuncCall::PedersenHash &obj, Serializer &serializer) {
serde::Serializable<decltype(obj.inputs)>::serialize(obj.inputs, serializer);
serde::Serializable<decltype(obj.domain_separator)>::serialize(obj.domain_separator, serializer);
serde::Serializable<decltype(obj.output)>::serialize(obj.output, serializer);
}

template <>
template <typename Deserializer>
Circuit::BlackBoxFuncCall::PedersenHash serde::Deserializable<Circuit::BlackBoxFuncCall::PedersenHash>::deserialize(Deserializer &deserializer) {
Circuit::BlackBoxFuncCall::PedersenHash obj;
obj.inputs = serde::Deserializable<decltype(obj.inputs)>::deserialize(deserializer);
obj.domain_separator = serde::Deserializable<decltype(obj.domain_separator)>::deserialize(deserializer);
obj.output = serde::Deserializable<decltype(obj.output)>::deserialize(deserializer);
return obj;
}

namespace Circuit {

inline bool operator==(const BlackBoxFuncCall::HashToField128Security &lhs, const BlackBoxFuncCall::HashToField128Security &rhs) {
Expand Down Expand Up @@ -2594,22 +2658,66 @@ Circuit::BlackBoxOp::SchnorrVerify serde::Deserializable<Circuit::BlackBoxOp::Sc

namespace Circuit {

inline bool operator==(const BlackBoxOp::Pedersen &lhs, const BlackBoxOp::Pedersen &rhs) {
inline bool operator==(const BlackBoxOp::PedersenCommitment &lhs, const BlackBoxOp::PedersenCommitment &rhs) {
if (!(lhs.inputs == rhs.inputs)) { return false; }
if (!(lhs.domain_separator == rhs.domain_separator)) { return false; }
if (!(lhs.output == rhs.output)) { return false; }
return true;
}

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

inline BlackBoxOp::PedersenCommitment BlackBoxOp::PedersenCommitment::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BlackBoxOp::PedersenCommitment>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
return value;
}

} // end of namespace Circuit

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BlackBoxOp::PedersenCommitment>::serialize(const Circuit::BlackBoxOp::PedersenCommitment &obj, Serializer &serializer) {
serde::Serializable<decltype(obj.inputs)>::serialize(obj.inputs, serializer);
serde::Serializable<decltype(obj.domain_separator)>::serialize(obj.domain_separator, serializer);
serde::Serializable<decltype(obj.output)>::serialize(obj.output, serializer);
}

template <>
template <typename Deserializer>
Circuit::BlackBoxOp::PedersenCommitment serde::Deserializable<Circuit::BlackBoxOp::PedersenCommitment>::deserialize(Deserializer &deserializer) {
Circuit::BlackBoxOp::PedersenCommitment obj;
obj.inputs = serde::Deserializable<decltype(obj.inputs)>::deserialize(deserializer);
obj.domain_separator = serde::Deserializable<decltype(obj.domain_separator)>::deserialize(deserializer);
obj.output = serde::Deserializable<decltype(obj.output)>::deserialize(deserializer);
return obj;
}

namespace Circuit {

inline bool operator==(const BlackBoxOp::PedersenHash &lhs, const BlackBoxOp::PedersenHash &rhs) {
if (!(lhs.inputs == rhs.inputs)) { return false; }
if (!(lhs.domain_separator == rhs.domain_separator)) { return false; }
if (!(lhs.output == rhs.output)) { return false; }
return true;
}

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

inline BlackBoxOp::Pedersen BlackBoxOp::Pedersen::bincodeDeserialize(std::vector<uint8_t> input) {
inline BlackBoxOp::PedersenHash BlackBoxOp::PedersenHash::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BlackBoxOp::Pedersen>::deserialize(deserializer);
auto value = serde::Deserializable<BlackBoxOp::PedersenHash>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
Expand All @@ -2620,16 +2728,16 @@ namespace Circuit {

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BlackBoxOp::Pedersen>::serialize(const Circuit::BlackBoxOp::Pedersen &obj, Serializer &serializer) {
void serde::Serializable<Circuit::BlackBoxOp::PedersenHash>::serialize(const Circuit::BlackBoxOp::PedersenHash &obj, Serializer &serializer) {
serde::Serializable<decltype(obj.inputs)>::serialize(obj.inputs, serializer);
serde::Serializable<decltype(obj.domain_separator)>::serialize(obj.domain_separator, serializer);
serde::Serializable<decltype(obj.output)>::serialize(obj.output, serializer);
}

template <>
template <typename Deserializer>
Circuit::BlackBoxOp::Pedersen serde::Deserializable<Circuit::BlackBoxOp::Pedersen>::deserialize(Deserializer &deserializer) {
Circuit::BlackBoxOp::Pedersen obj;
Circuit::BlackBoxOp::PedersenHash serde::Deserializable<Circuit::BlackBoxOp::PedersenHash>::deserialize(Deserializer &deserializer) {
Circuit::BlackBoxOp::PedersenHash obj;
obj.inputs = serde::Deserializable<decltype(obj.inputs)>::deserialize(deserializer);
obj.domain_separator = serde::Deserializable<decltype(obj.domain_separator)>::deserialize(deserializer);
obj.output = serde::Deserializable<decltype(obj.output)>::deserialize(deserializer);
Expand Down
10 changes: 7 additions & 3 deletions acvm-repo/acir/src/circuit/black_box_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ pub enum BlackBoxFunc {
/// [grumpkin]: https://hackmd.io/@aztec-network/ByzgNxBfd#2-Grumpkin---A-curve-on-top-of-BN-254-for-SNARK-efficient-group-operations
SchnorrVerify,
/// Calculates a Pedersen commitment to the inputs.
Pedersen,
PedersenCommitment,
/// Calculates a Pedersen hash to the inputs.
PedersenHash,
/// Hashes a set of inputs and applies the field modulus to the result
/// to return a value which can be represented as a [`FieldElement`][acir_field::FieldElement]
///
Expand Down Expand Up @@ -62,7 +64,8 @@ impl BlackBoxFunc {
BlackBoxFunc::SHA256 => "sha256",
BlackBoxFunc::SchnorrVerify => "schnorr_verify",
BlackBoxFunc::Blake2s => "blake2s",
BlackBoxFunc::Pedersen => "pedersen",
BlackBoxFunc::PedersenCommitment => "pedersen",
BlackBoxFunc::PedersenHash => "pedersen_hash",
BlackBoxFunc::HashToField128Security => "hash_to_field_128_security",
BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1",
BlackBoxFunc::FixedBaseScalarMul => "fixed_base_scalar_mul",
Expand All @@ -79,7 +82,8 @@ impl BlackBoxFunc {
"sha256" => Some(BlackBoxFunc::SHA256),
"schnorr_verify" => Some(BlackBoxFunc::SchnorrVerify),
"blake2s" => Some(BlackBoxFunc::Blake2s),
"pedersen" => Some(BlackBoxFunc::Pedersen),
"pedersen" => Some(BlackBoxFunc::PedersenCommitment),
"pedersen_hash" => Some(BlackBoxFunc::PedersenHash),
"hash_to_field_128_security" => Some(BlackBoxFunc::HashToField128Security),
"ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1),
"ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1),
Expand Down
25 changes: 19 additions & 6 deletions acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,16 @@ pub enum BlackBoxFuncCall {
message: Vec<FunctionInput>,
output: Witness,
},
Pedersen {
PedersenCommitment {
inputs: Vec<FunctionInput>,
domain_separator: u32,
outputs: (Witness, Witness),
},
PedersenHash {
inputs: Vec<FunctionInput>,
domain_separator: u32,
output: Witness,
},
// 128 here specifies that this function
// should have 128 bits of security
HashToField128Security {
Expand Down Expand Up @@ -138,11 +143,16 @@ impl BlackBoxFuncCall {
message: vec![],
output: Witness(0),
},
BlackBoxFunc::Pedersen => BlackBoxFuncCall::Pedersen {
BlackBoxFunc::PedersenCommitment => BlackBoxFuncCall::PedersenCommitment {
inputs: vec![],
domain_separator: 0,
outputs: (Witness(0), Witness(0)),
},
BlackBoxFunc::PedersenHash => BlackBoxFuncCall::PedersenHash {
inputs: vec![],
domain_separator: 0,
output: Witness(0),
},
BlackBoxFunc::HashToField128Security => {
BlackBoxFuncCall::HashToField128Security { inputs: vec![], output: Witness(0) }
}
Expand Down Expand Up @@ -187,7 +197,8 @@ impl BlackBoxFuncCall {
BlackBoxFuncCall::SHA256 { .. } => BlackBoxFunc::SHA256,
BlackBoxFuncCall::Blake2s { .. } => BlackBoxFunc::Blake2s,
BlackBoxFuncCall::SchnorrVerify { .. } => BlackBoxFunc::SchnorrVerify,
BlackBoxFuncCall::Pedersen { .. } => BlackBoxFunc::Pedersen,
BlackBoxFuncCall::PedersenCommitment { .. } => BlackBoxFunc::PedersenCommitment,
BlackBoxFuncCall::PedersenHash { .. } => BlackBoxFunc::PedersenHash,
BlackBoxFuncCall::HashToField128Security { .. } => BlackBoxFunc::HashToField128Security,
BlackBoxFuncCall::EcdsaSecp256k1 { .. } => BlackBoxFunc::EcdsaSecp256k1,
BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1,
Expand All @@ -207,7 +218,8 @@ impl BlackBoxFuncCall {
BlackBoxFuncCall::SHA256 { inputs, .. }
| BlackBoxFuncCall::Blake2s { inputs, .. }
| BlackBoxFuncCall::Keccak256 { inputs, .. }
| BlackBoxFuncCall::Pedersen { inputs, .. }
| BlackBoxFuncCall::PedersenCommitment { inputs, .. }
| BlackBoxFuncCall::PedersenHash { inputs, .. }
| BlackBoxFuncCall::HashToField128Security { inputs, .. } => inputs.to_vec(),
BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => {
vec![*lhs, *rhs]
Expand Down Expand Up @@ -304,9 +316,10 @@ impl BlackBoxFuncCall {
| BlackBoxFuncCall::HashToField128Security { output, .. }
| BlackBoxFuncCall::SchnorrVerify { output, .. }
| BlackBoxFuncCall::EcdsaSecp256k1 { output, .. }
| BlackBoxFuncCall::PedersenHash { output, .. }
| BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output],
BlackBoxFuncCall::FixedBaseScalarMul { outputs, .. }
| BlackBoxFuncCall::Pedersen { outputs, .. } => vec![outputs.0, outputs.1],
| BlackBoxFuncCall::PedersenCommitment { outputs, .. } => vec![outputs.0, outputs.1],
BlackBoxFuncCall::RANGE { .. } => vec![],
BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(),
}
Expand Down Expand Up @@ -395,7 +408,7 @@ impl std::fmt::Display for BlackBoxFuncCall {

// SPECIFIC PARAMETERS
match self {
BlackBoxFuncCall::Pedersen { domain_separator, .. } => {
BlackBoxFuncCall::PedersenCommitment { domain_separator, .. } => {
write!(f, " domain_separator: {domain_separator}")
}
_ => write!(f, ""),
Expand Down
Loading

0 comments on commit 0108b6c

Please sign in to comment.