mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
simplify GroupType trait parameters
This commit is contained in:
parent
5db9b043dc
commit
8852c17857
84
Cargo.lock
generated
84
Cargo.lock
generated
@ -99,13 +99,14 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.7.1"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b77e29dbd0115e43938be2d5128ecf81c0353e00acaa65339a1242586951d9"
|
||||
checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
|
||||
dependencies = [
|
||||
"byte-tools 0.2.0",
|
||||
"byte-tools",
|
||||
"crypto-mac",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -115,9 +116,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools 0.3.1",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.3",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -126,15 +127,9 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools 0.3.1",
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
@ -208,12 +203,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
@ -263,32 +252,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.5.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958"
|
||||
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
dependencies = [
|
||||
"constant_time_eq",
|
||||
"generic-array 0.9.0",
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "1.0.4"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c6d883546668a3e2011b6a716a7330b82eabb0151b138217f632c8243e17135"
|
||||
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||
dependencies = [
|
||||
"generic-array 0.9.0",
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -297,7 +277,7 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -363,15 +343,6 @@ version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
@ -522,6 +493,7 @@ dependencies = [
|
||||
"pest-ast",
|
||||
"pest_derive",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"sha2",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
@ -922,7 +894,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest 0.8.1",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
@ -934,7 +906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest 0.8.1",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
@ -966,8 +938,9 @@ version = "0.8.0"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rayon",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
@ -993,10 +966,10 @@ name = "snarkos-errors"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"failure",
|
||||
"hex",
|
||||
"jsonrpc-core",
|
||||
"rocksdb",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1004,7 +977,7 @@ name = "snarkos-gadgets"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
"snarkos-errors",
|
||||
@ -1017,7 +990,6 @@ name = "snarkos-models"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"failure",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"smallvec",
|
||||
@ -1066,6 +1038,12 @@ dependencies = [
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
|
@ -18,18 +18,16 @@ use sha2::{Digest, Sha256};
|
||||
use std::{fs, marker::PhantomData, path::PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Compiler<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> {
|
||||
pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
|
||||
package_name: String,
|
||||
main_file_path: PathBuf,
|
||||
program: Program<F>,
|
||||
program_inputs: Vec<Option<InputValue<F>>>,
|
||||
output: Option<ConstrainedValue<NativeF, F, GType>>,
|
||||
output: Option<ConstrainedValue<F, G>>,
|
||||
_engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
|
||||
Compiler<NativeF, F, GType>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut program = Self {
|
||||
package_name,
|
||||
@ -66,7 +64,7 @@ impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, CompilerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, CompilerError> {
|
||||
generate_constraints(cs, self.program, self.program_inputs)
|
||||
}
|
||||
|
||||
@ -109,16 +107,13 @@ impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> ConstraintSynthesizer<F>
|
||||
for Compiler<NativeF, F, GType>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _result =
|
||||
generate_constraints::<NativeF, _, GType, _>(cs, self.program, self.program_inputs)
|
||||
.unwrap();
|
||||
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
|
@ -16,20 +16,14 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn bool_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
// Check that the input value is the correct type
|
||||
let bool_value = match input_value {
|
||||
Some(input) => {
|
||||
@ -56,13 +50,13 @@ impl<
|
||||
Ok(ConstrainedValue::Boolean(number))
|
||||
}
|
||||
|
||||
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<NativeF, F, GType> {
|
||||
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(bool)
|
||||
}
|
||||
|
||||
pub(crate) fn evaluate_not(
|
||||
value: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
|
||||
value: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match value {
|
||||
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
||||
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
|
||||
@ -72,9 +66,9 @@ impl<
|
||||
pub(crate) fn enforce_or(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
|
||||
@ -89,9 +83,9 @@ impl<
|
||||
pub(crate) fn enforce_and(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
|
||||
@ -103,7 +97,7 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ConstrainedValue<NativeF, F, GType> {
|
||||
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(Boolean::Constant(left.eq(&right)))
|
||||
}
|
||||
|
||||
|
@ -19,13 +19,7 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
/// Enforce a variable expression by getting the resolved value
|
||||
pub(crate) fn evaluate_identifier(
|
||||
&mut self,
|
||||
@ -33,7 +27,7 @@ impl<
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
unresolved_identifier: Identifier<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Evaluate the identifier name in the current function scope
|
||||
let variable_name = new_scope(function_scope, unresolved_identifier.to_string());
|
||||
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
|
||||
@ -59,9 +53,9 @@ impl<
|
||||
fn enforce_add_expression(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(Self::enforce_integer_add(cs, num_1, num_2)?)
|
||||
@ -90,9 +84,9 @@ impl<
|
||||
fn enforce_sub_expression(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(Self::enforce_integer_sub(cs, num_1, num_2)?)
|
||||
@ -121,9 +115,9 @@ impl<
|
||||
fn enforce_mul_expression(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(Self::enforce_integer_mul(cs, num_1, num_2)?)
|
||||
@ -151,9 +145,9 @@ impl<
|
||||
fn enforce_div_expression(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(Self::enforce_integer_div(cs, num_1, num_2)?)
|
||||
@ -180,9 +174,9 @@ impl<
|
||||
fn enforce_pow_expression(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(Self::enforce_integer_pow(cs, num_1, num_2)?)
|
||||
@ -211,9 +205,9 @@ impl<
|
||||
/// Evaluate Boolean operations
|
||||
fn evaluate_eq_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
|
||||
Ok(Self::boolean_eq(bool_1, bool_2))
|
||||
@ -244,9 +238,9 @@ impl<
|
||||
|
||||
fn evaluate_geq_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_geq(fe_1, fe_2)
|
||||
@ -268,9 +262,9 @@ impl<
|
||||
|
||||
fn evaluate_gt_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_gt(fe_1, fe_2)
|
||||
@ -292,9 +286,9 @@ impl<
|
||||
|
||||
fn evaluate_leq_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_leq(fe_1, fe_2)
|
||||
@ -316,9 +310,9 @@ impl<
|
||||
|
||||
fn evaluate_lt_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_lt(fe_1, fe_2)
|
||||
@ -348,7 +342,7 @@ impl<
|
||||
first: Expression<F>,
|
||||
second: Expression<F>,
|
||||
third: Expression<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let resolved_first = match self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -381,7 +375,7 @@ impl<
|
||||
Ok(ConstrainedValue::Integer(result))
|
||||
}
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
let result = GType::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
|
||||
let result = G::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
|
||||
Ok(ConstrainedValue::Group(result))
|
||||
}
|
||||
(_, _) => {
|
||||
@ -398,7 +392,7 @@ impl<
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
array: Vec<Box<SpreadOrExpression<F>>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Check explicit array type dimension if given
|
||||
let mut expected_types = expected_types.clone();
|
||||
let expected_dimensions = vec![];
|
||||
@ -483,7 +477,7 @@ impl<
|
||||
expected_types: &Vec<Type<F>>,
|
||||
array: Box<Expression<F>>,
|
||||
index: RangeOrExpression<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let array = match self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -523,7 +517,7 @@ impl<
|
||||
function_scope: String,
|
||||
identifier: Identifier<F>,
|
||||
members: Vec<CircuitFieldDefinition<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut program_identifier = new_scope(file_scope.clone(), identifier.to_string());
|
||||
|
||||
if identifier.is_self() {
|
||||
@ -598,7 +592,7 @@ impl<
|
||||
expected_types: &Vec<Type<F>>,
|
||||
circuit_identifier: Box<Expression<F>>,
|
||||
circuit_member: Identifier<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let (circuit_name, members) = match self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -659,7 +653,7 @@ impl<
|
||||
expected_types: &Vec<Type<F>>,
|
||||
circuit_identifier: Box<Expression<F>>,
|
||||
circuit_member: Identifier<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Get defined circuit
|
||||
let circuit = match self.enforce_expression(
|
||||
cs,
|
||||
@ -713,7 +707,7 @@ impl<
|
||||
expected_types: &Vec<Type<F>>,
|
||||
function: Box<Expression<F>>,
|
||||
arguments: Vec<Expression<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let function_value = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -751,7 +745,7 @@ impl<
|
||||
pub(crate) fn enforce_number_implicit(
|
||||
expected_types: &Vec<Type<F>>,
|
||||
value: String,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
if expected_types.len() == 1 {
|
||||
return Ok(ConstrainedValue::from_type(value, &expected_types[0])?);
|
||||
}
|
||||
@ -769,7 +763,7 @@ impl<
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
expression: Expression<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut branch =
|
||||
self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
|
||||
|
||||
@ -787,13 +781,7 @@ impl<
|
||||
expected_types: &Vec<Type<F>>,
|
||||
left: Expression<F>,
|
||||
right: Expression<F>,
|
||||
) -> Result<
|
||||
(
|
||||
ConstrainedValue<NativeF, F, GType>,
|
||||
ConstrainedValue<NativeF, F, GType>,
|
||||
),
|
||||
ExpressionError,
|
||||
> {
|
||||
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
|
||||
let resolved_left = self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -819,7 +807,7 @@ impl<
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
expression: Expression<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match expression {
|
||||
// Variables
|
||||
Expression::Identifier(unresolved_variable) => self.evaluate_identifier(
|
||||
@ -833,7 +821,7 @@ impl<
|
||||
Expression::Integer(integer) => Ok(Self::get_integer_constant(integer)),
|
||||
Expression::FieldElement(fe) => Ok(Self::get_field_element_constant(fe)),
|
||||
Expression::Group(group_affine) => {
|
||||
Ok(ConstrainedValue::Group(GType::constant(group_affine)?))
|
||||
Ok(ConstrainedValue::Group(G::constant(group_affine)?))
|
||||
}
|
||||
Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)),
|
||||
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),
|
||||
|
@ -13,20 +13,14 @@ use snarkos_models::{
|
||||
gadgets::r1cs::{ConstraintSystem, LinearCombination, Variable as R1CSVariable},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn field_element_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let field_option = match input_value {
|
||||
Some(input) => {
|
||||
@ -58,9 +52,7 @@ impl<
|
||||
)))
|
||||
}
|
||||
|
||||
pub(crate) fn get_field_element_constant(
|
||||
fe: FieldElement<F>,
|
||||
) -> ConstrainedValue<NativeF, F, GType> {
|
||||
pub(crate) fn get_field_element_constant(fe: FieldElement<F>) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::FieldElement(fe)
|
||||
}
|
||||
|
||||
@ -133,7 +125,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
fe_1: FieldElement<F>,
|
||||
fe_2: FieldElement<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
Ok(match (fe_1, fe_2) {
|
||||
// if both constants, then return a constant result
|
||||
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
|
||||
@ -210,7 +202,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
fe_1: FieldElement<F>,
|
||||
fe_2: FieldElement<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
Ok(match (fe_1, fe_2) {
|
||||
// if both constants, then return a constant result
|
||||
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
|
||||
@ -287,7 +279,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
fe_1: FieldElement<F>,
|
||||
fe_2: FieldElement<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
Ok(match (fe_1, fe_2) {
|
||||
// if both constants, then return a constant result
|
||||
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
|
||||
@ -364,7 +356,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
fe_1: FieldElement<F>,
|
||||
fe_2: FieldElement<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
Ok(match (fe_1, fe_2) {
|
||||
// if both constants, then return a constant result
|
||||
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
|
||||
@ -452,7 +444,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
fe_1: FieldElement<F>,
|
||||
num: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
Ok(match fe_1 {
|
||||
// if both constants, then return a constant result
|
||||
FieldElement::Constant(fe_1_constant) => ConstrainedValue::FieldElement(
|
||||
|
@ -14,13 +14,7 @@ use snarkos_models::{
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
fn check_arguments_length(expected: usize, actual: usize) -> Result<(), FunctionError> {
|
||||
// Make sure we are given the correct number of arguments
|
||||
if expected != actual {
|
||||
@ -38,7 +32,7 @@ impl<
|
||||
function_name: String,
|
||||
expected_types: Vec<Type<F>>,
|
||||
input: Expression<F>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
// Evaluate the function input value as pass by value from the caller or
|
||||
// evaluate as an expression in the current function scope
|
||||
match input {
|
||||
@ -65,7 +59,7 @@ impl<
|
||||
caller_scope: String,
|
||||
function: Function<F>,
|
||||
inputs: Vec<Expression<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
// Make sure we are given the correct number of inputs
|
||||
@ -127,7 +121,7 @@ impl<
|
||||
array_type: Type<F>,
|
||||
array_dimensions: Vec<usize>,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let expected_length = array_dimensions[0];
|
||||
let mut array_value = vec![];
|
||||
|
||||
@ -180,7 +174,7 @@ impl<
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
match _type {
|
||||
Type::IntegerType(integer_type) => {
|
||||
Ok(self.integer_from_parameter(cs, integer_type, name, private, input_value)?)
|
||||
@ -203,7 +197,7 @@ impl<
|
||||
scope: String,
|
||||
function: Function<F>,
|
||||
inputs: Vec<Option<InputValue<F>>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
// Make sure we are given the correct number of inputs
|
||||
|
@ -4,17 +4,12 @@ use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||
|
||||
pub(crate) fn group_from_input<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
>(
|
||||
pub(crate) fn group_from_input<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, GroupError> {
|
||||
) -> Result<ConstrainedValue<F, G>, GroupError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let group_option = match input_value {
|
||||
Some(input) => {
|
||||
@ -29,11 +24,11 @@ pub(crate) fn group_from_input<
|
||||
|
||||
// Check visibility of parameter
|
||||
let group_value = if private {
|
||||
GType::alloc(cs.ns(|| name), || {
|
||||
G::alloc(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
} else {
|
||||
GType::alloc_input(cs.ns(|| name), || {
|
||||
G::alloc_input(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
};
|
||||
|
@ -15,13 +15,7 @@ use snarkos_models::{
|
||||
use std::env::current_dir;
|
||||
use std::fs;
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn enforce_import(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
@ -73,21 +73,15 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for Integer {
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<NativeF, F, GType> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Integer(integer)
|
||||
}
|
||||
|
||||
pub(crate) fn evaluate_integer_eq(
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(
|
||||
match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => left_u8.eq(&right_u8),
|
||||
@ -112,7 +106,7 @@ impl<
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Check that the input value is the correct type
|
||||
let integer_option = match integer_value {
|
||||
Some(input) => {
|
||||
@ -168,7 +162,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Integer(match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
|
||||
Integer::U8(Self::enforce_u8_add(cs, left_u8, right_u8)?)
|
||||
@ -194,7 +188,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Integer(match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
|
||||
Integer::U8(Self::enforce_u8_sub(cs, left_u8, right_u8)?)
|
||||
@ -220,7 +214,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Integer(match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
|
||||
Integer::U8(Self::enforce_u8_mul(cs, left_u8, right_u8)?)
|
||||
@ -246,7 +240,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Integer(match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
|
||||
Integer::U8(Self::enforce_u8_div(cs, left_u8, right_u8)?)
|
||||
@ -272,7 +266,7 @@ impl<
|
||||
cs: &mut CS,
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Integer(match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
|
||||
Integer::U8(Self::enforce_u8_pow(cs, left_u8, right_u8)?)
|
||||
|
@ -16,20 +16,14 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u128_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Type cast to u128 in rust.
|
||||
// If this fails should we return our own error?
|
||||
let u128_option = integer_option.map(|integer| integer as u128);
|
||||
|
@ -16,20 +16,14 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u16_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Type cast to u16 in rust.
|
||||
// If this fails should we return our own error?
|
||||
let u16_option = integer_option.map(|integer| integer as u16);
|
||||
|
@ -16,20 +16,14 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u32_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Type cast to integers.u32 in rust.
|
||||
// If this fails should we return our own error?
|
||||
let u32_option = integer_option.map(|integer| integer as u32);
|
||||
|
@ -16,20 +16,14 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u64_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Type cast to u64 in rust.
|
||||
// If this fails should we return our own error?
|
||||
let u64_option = integer_option.map(|integer| integer as u64);
|
||||
|
@ -16,20 +16,14 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u8_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Type cast to u8 in rust.
|
||||
// If this fails should we return our own error?
|
||||
let u8_option = integer_option.map(|integer| integer as u8);
|
||||
|
@ -41,16 +41,11 @@ use snarkos_models::{
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
pub fn generate_constraints<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
>(
|
||||
pub fn generate_constraints<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
program: Program<F>,
|
||||
parameters: Vec<Option<InputValue<F>>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, CompilerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, CompilerError> {
|
||||
let mut resolved_program = ConstrainedProgram::new();
|
||||
let program_name = program.get_name();
|
||||
let main_function_name = new_scope(program_name.clone(), "main".into());
|
||||
|
@ -9,13 +9,8 @@ use snarkos_models::{
|
||||
};
|
||||
use std::{collections::HashMap, marker::PhantomData};
|
||||
|
||||
pub struct ConstrainedProgram<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> {
|
||||
pub identifiers: HashMap<String, ConstrainedValue<NativeF, F, GType>>,
|
||||
pub struct ConstrainedProgram<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> {
|
||||
pub identifiers: HashMap<String, ConstrainedValue<F, G>>,
|
||||
pub _cs: PhantomData<CS>,
|
||||
}
|
||||
|
||||
@ -23,13 +18,7 @@ pub fn new_scope(outer: String, inner: String) -> String {
|
||||
format!("{}_{}", outer, inner)
|
||||
}
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
identifiers: HashMap::new(),
|
||||
@ -37,18 +26,15 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<NativeF, F, GType>) {
|
||||
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) {
|
||||
self.identifiers.insert(name, value);
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<NativeF, F, GType>> {
|
||||
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F, G>> {
|
||||
self.identifiers.get(name)
|
||||
}
|
||||
|
||||
pub(crate) fn get_mut(
|
||||
&mut self,
|
||||
name: &String,
|
||||
) -> Option<&mut ConstrainedValue<NativeF, F, GType>> {
|
||||
pub(crate) fn get_mut(&mut self, name: &String) -> Option<&mut ConstrainedValue<F, G>> {
|
||||
self.identifiers.get_mut(name)
|
||||
}
|
||||
}
|
||||
|
@ -16,13 +16,7 @@ use snarkos_models::{
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean, utilities::uint32::UInt32},
|
||||
};
|
||||
|
||||
impl<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
> ConstrainedProgram<NativeF, F, GType, CS>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F>) -> String {
|
||||
match assignee {
|
||||
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
|
||||
@ -36,7 +30,7 @@ impl<
|
||||
fn get_mutable_assignee(
|
||||
&mut self,
|
||||
name: String,
|
||||
) -> Result<&mut ConstrainedValue<NativeF, F, GType>, StatementError> {
|
||||
) -> Result<&mut ConstrainedValue<F, G>, StatementError> {
|
||||
// Check that assignee exists and is mutable
|
||||
Ok(match self.get_mut(&name) {
|
||||
Some(value) => match value {
|
||||
@ -54,7 +48,7 @@ impl<
|
||||
function_scope: String,
|
||||
name: String,
|
||||
range_or_expression: RangeOrExpression<F>,
|
||||
new_value: ConstrainedValue<NativeF, F, GType>,
|
||||
new_value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
// Resolve index so we know if we are assigning to a single value or a range of values
|
||||
match range_or_expression {
|
||||
@ -98,7 +92,7 @@ impl<
|
||||
&mut self,
|
||||
circuit_name: String,
|
||||
object_name: Identifier<F>,
|
||||
new_value: ConstrainedValue<NativeF, F, GType>,
|
||||
new_value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
match self.get_mutable_assignee(circuit_name)? {
|
||||
ConstrainedValue::CircuitExpression(_variable, members) => {
|
||||
@ -177,7 +171,7 @@ impl<
|
||||
&mut self,
|
||||
function_scope: String,
|
||||
variable: Variable<F>,
|
||||
mut value: ConstrainedValue<NativeF, F, GType>,
|
||||
mut value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
// Store with given mutability
|
||||
if variable.mutable {
|
||||
@ -264,7 +258,7 @@ impl<
|
||||
function_scope: String,
|
||||
expressions: Vec<Expression<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, StatementError> {
|
||||
) -> Result<ConstrainedValue<F, G>, StatementError> {
|
||||
// Make sure we return the correct number of values
|
||||
if return_types.len() != expressions.len() {
|
||||
return Err(StatementError::InvalidNumberOfReturns(
|
||||
@ -297,7 +291,7 @@ impl<
|
||||
function_scope: String,
|
||||
statements: Vec<Statement<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let mut res = None;
|
||||
// Evaluate statements and possibly return early
|
||||
for statement in statements.iter() {
|
||||
@ -323,7 +317,7 @@ impl<
|
||||
function_scope: String,
|
||||
statement: ConditionalStatement<F>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let expected_types = vec![Type::Boolean];
|
||||
let condition = match self.enforce_expression(
|
||||
cs,
|
||||
@ -378,7 +372,7 @@ impl<
|
||||
stop: Integer,
|
||||
statements: Vec<Statement<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let mut res = None;
|
||||
|
||||
for i in start.to_usize()..stop.to_usize() {
|
||||
@ -409,8 +403,8 @@ impl<
|
||||
fn enforce_assert_eq_statement(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ConstrainedValue<NativeF, F, GType>,
|
||||
right: ConstrainedValue<NativeF, F, GType>,
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
|
||||
@ -451,7 +445,7 @@ impl<
|
||||
function_scope: String,
|
||||
statement: Statement<F>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let mut res = None;
|
||||
match statement {
|
||||
Statement::Return(expressions) => {
|
||||
|
@ -14,45 +14,37 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct ConstrainedCircuitMember<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
>(pub Identifier<F>, pub ConstrainedValue<NativeF, F, GType>);
|
||||
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: GroupType<F>>(
|
||||
pub Identifier<F>,
|
||||
pub ConstrainedValue<F, G>,
|
||||
);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum ConstrainedValue<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> {
|
||||
pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
|
||||
Integer(Integer),
|
||||
FieldElement(FieldElement<F>),
|
||||
Group(GType),
|
||||
Group(G),
|
||||
Boolean(Boolean),
|
||||
|
||||
Array(Vec<ConstrainedValue<NativeF, F, GType>>),
|
||||
Array(Vec<ConstrainedValue<F, G>>),
|
||||
|
||||
CircuitDefinition(Circuit<F>),
|
||||
CircuitExpression(
|
||||
Identifier<F>,
|
||||
Vec<ConstrainedCircuitMember<NativeF, F, GType>>,
|
||||
),
|
||||
CircuitExpression(Identifier<F>, Vec<ConstrainedCircuitMember<F, G>>),
|
||||
|
||||
Function(Option<Identifier<F>>, Function<F>), // (optional circuit identifier, function definition)
|
||||
Return(Vec<ConstrainedValue<NativeF, F, GType>>),
|
||||
Return(Vec<ConstrainedValue<F, G>>),
|
||||
|
||||
Mutable(Box<ConstrainedValue<NativeF, F, GType>>),
|
||||
Static(Box<ConstrainedValue<NativeF, F, GType>>),
|
||||
Mutable(Box<ConstrainedValue<F, G>>),
|
||||
Static(Box<ConstrainedValue<F, G>>),
|
||||
Unresolved(String),
|
||||
Void(PhantomData<NativeF>),
|
||||
}
|
||||
|
||||
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
|
||||
ConstrainedValue<NativeF, F, GType>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
pub(crate) fn from_other(
|
||||
value: String,
|
||||
other: &ConstrainedValue<NativeF, F, GType>,
|
||||
other: &ConstrainedValue<F, G>,
|
||||
) -> Result<Self, ValueError> {
|
||||
let other_type = other.to_type();
|
||||
|
||||
@ -71,7 +63,7 @@ impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
|
||||
Type::FieldElement => Ok(ConstrainedValue::FieldElement(FieldElement::Constant(
|
||||
F::from_str(&value).unwrap_or_default(),
|
||||
))),
|
||||
Type::Group => Ok(ConstrainedValue::Group(GType::constant(value)?)),
|
||||
Type::Group => Ok(ConstrainedValue::Group(G::constant(value)?)),
|
||||
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(
|
||||
value.parse::<bool>()?,
|
||||
))),
|
||||
@ -107,9 +99,7 @@ impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> fmt::Display
|
||||
for ConstrainedValue<NativeF, F, GType>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConstrainedValue::Integer(ref value) => write!(f, "{}", value),
|
||||
@ -155,14 +145,11 @@ impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> fmt::D
|
||||
ConstrainedValue::Mutable(ref value) => write!(f, "mut {}", value),
|
||||
ConstrainedValue::Static(ref value) => write!(f, "static {}", value),
|
||||
ConstrainedValue::Unresolved(ref value) => write!(f, "unresolved {}", value),
|
||||
ConstrainedValue::Void(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> fmt::Debug
|
||||
for ConstrainedValue<NativeF, F, GType>
|
||||
{
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> fmt::Debug for ConstrainedValue<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use snarkos_curves::edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq};
|
||||
use snarkos_curves::templates::twisted_edwards_extended::GroupAffine;
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
use snarkos_models::curves::{AffineCurve, ModelParameters};
|
||||
use snarkos_models::curves::AffineCurve;
|
||||
use snarkos_models::gadgets::curves::{FpGadget, GroupGadget};
|
||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::alloc::AllocGadget;
|
||||
@ -22,7 +22,7 @@ pub enum EdwardsGroupType {
|
||||
Allocated(EdwardsBlsGadget),
|
||||
}
|
||||
|
||||
impl GroupType<<EdwardsParameters as ModelParameters>::BaseField, Fq> for EdwardsGroupType {
|
||||
impl GroupType<Fq> for EdwardsGroupType {
|
||||
fn constant(string: String) -> Result<Self, GroupError> {
|
||||
let value = Self::edwards_affine_from_str(string)?;
|
||||
|
||||
|
@ -5,11 +5,10 @@ use snarkos_models::gadgets::utilities::alloc::AllocGadget;
|
||||
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||
use snarkos_models::gadgets::utilities::select::CondSelectGadget;
|
||||
use std::fmt::Debug;
|
||||
// use snarkos_models::gadgets::utilities::select::CondSelectGadget;
|
||||
|
||||
pub mod edwards_bls12;
|
||||
|
||||
pub trait GroupType<NativeF: Field, F: Field>:
|
||||
pub trait GroupType<F: Field>:
|
||||
Sized
|
||||
+ Clone
|
||||
+ Debug
|
||||
|
@ -12,15 +12,12 @@ pub mod statement;
|
||||
use leo_compiler::{compiler::Compiler, errors::CompilerError, ConstrainedValue};
|
||||
|
||||
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
||||
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
|
||||
use snarkos_models::curves::ModelParameters;
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use std::env::current_dir;
|
||||
|
||||
pub type EdwardsTestCompiler =
|
||||
Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>;
|
||||
pub type EdwardsConstrainedValue =
|
||||
ConstrainedValue<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>;
|
||||
pub type EdwardsTestCompiler = Compiler<Fq, EdwardsGroupType>;
|
||||
pub type EdwardsConstrainedValue = ConstrainedValue<Fq, EdwardsGroupType>;
|
||||
|
||||
pub(crate) fn get_output(program: EdwardsTestCompiler) -> EdwardsConstrainedValue {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
|
@ -9,8 +9,7 @@ use snarkos_curves::bls12_377::Bls12_377;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
||||
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
|
||||
use snarkos_models::curves::ModelParameters;
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
|
||||
@ -19,10 +18,7 @@ pub struct BuildCommand;
|
||||
|
||||
impl CLI for BuildCommand {
|
||||
type Options = ();
|
||||
type Output = (
|
||||
Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
|
||||
bool,
|
||||
);
|
||||
type Output = (Compiler<Fq, EdwardsGroupType>, bool);
|
||||
|
||||
const NAME: NameType = "build";
|
||||
const ABOUT: AboutType = "Compile the current package as a program";
|
||||
@ -66,11 +62,8 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let program = Compiler::<
|
||||
<EdwardsParameters as ModelParameters>::BaseField,
|
||||
Fq,
|
||||
EdwardsGroupType,
|
||||
>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
|
@ -13,8 +13,7 @@ use snarkos_utilities::bytes::ToBytes;
|
||||
use clap::ArgMatches;
|
||||
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
||||
use rand::thread_rng;
|
||||
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
|
||||
use snarkos_models::curves::ModelParameters;
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::time::Instant;
|
||||
@ -25,7 +24,7 @@ pub struct SetupCommand;
|
||||
impl CLI for SetupCommand {
|
||||
type Options = ();
|
||||
type Output = (
|
||||
Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
|
||||
Compiler<Fq, EdwardsGroupType>,
|
||||
Parameters<Bls12_377>,
|
||||
PreparedVerifyingKey<Bls12_377>,
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user