fix field pow. fix eq vs enforce_eq

This commit is contained in:
collin 2020-04-30 11:36:35 -07:00
parent e5513d7bcf
commit f071764548
5 changed files with 44 additions and 14 deletions

View File

@ -1,5 +1,4 @@
function main() -> (u32) {
a = 2;
a **= 3;
function main() -> (fe) {
a = 2fe ** 3;
return a
}

View File

@ -136,6 +136,10 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
}
}
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ResolvedValue<F> {
ResolvedValue::Boolean(Boolean::Constant(left.eq(&right)))
}
pub(crate) fn enforce_boolean_eq(
&mut self,
cs: &mut CS,

View File

@ -96,7 +96,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
(ResolvedValue::FieldElement(fe1), ResolvedValue::FieldElement(fe2)) => {
self.enforce_field_div(fe1, fe2)
}
(val1, val2) => unimplemented!("cannot multiply {} * {}", val1, val2),
(val1, val2) => unimplemented!("cannot divide {} / {}", val1, val2),
}
}
fn enforce_pow_expression(
@ -109,14 +109,35 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
(ResolvedValue::U32(num1), ResolvedValue::U32(num2)) => {
Self::enforce_u32_pow(cs, num1, num2)
}
(ResolvedValue::FieldElement(fe1), ResolvedValue::FieldElement(fe2)) => {
self.enforce_field_pow(fe1, fe2)
(ResolvedValue::FieldElement(fe1), ResolvedValue::U32(num2)) => {
self.enforce_field_pow(fe1, num2)
}
(val1, val2) => unimplemented!("cannot multiply {} * {}", val1, val2),
(_, ResolvedValue::FieldElement(num2)) => {
unimplemented!("exponent power must be an integer, got field {}", num2)
}
(val1, val2) => unimplemented!("cannot enforce exponentiation {} * {}", val1, val2),
}
}
/// Enforce Boolean operations
/// Evaluate Boolean operations
fn evaluate_eq_expression(
&mut self,
left: ResolvedValue<F>,
right: ResolvedValue<F>,
) -> ResolvedValue<F> {
match (left, right) {
(ResolvedValue::Boolean(bool1), ResolvedValue::Boolean(bool2)) => {
Self::boolean_eq(bool1, bool2)
}
(ResolvedValue::U32(num1), ResolvedValue::U32(num2)) => Self::u32_eq(num1, num2),
(ResolvedValue::FieldElement(fe1), ResolvedValue::FieldElement(fe2)) => {
Self::field_eq(fe1, fe2)
}
(val1, val2) => unimplemented!("cannot enforce equality between {} == {}", val1, val2),
}
}
/// Enforce Boolean operations, returns true on success
fn enforce_eq_expression(
&mut self,
cs: &mut CS,
@ -411,7 +432,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
let resolved_right =
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), *right);
self.enforce_eq_expression(cs, resolved_left, resolved_right)
self.evaluate_eq_expression(resolved_left, resolved_right)
}
Expression::Geq(left, right) => {
unimplemented!("expression {} >= {} unimplemented", left, right)

View File

@ -4,6 +4,7 @@ use crate::constraints::{ResolvedProgram, ResolvedValue};
use crate::{new_variable_from_variable, Parameter, Variable};
use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::gadgets::utilities::uint32::UInt32;
use snarkos_models::gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean};
// use std::ops::{Add, Div, Mul, Neg, Sub};
@ -86,9 +87,12 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
// parameter_variable
}
pub(crate) fn enforce_field_eq(&mut self, fe1: F, fe2: F) -> ResolvedValue<F> {
pub(crate) fn field_eq(fe1: F, fe2: F) -> ResolvedValue<F> {
ResolvedValue::Boolean(Boolean::Constant(fe1.eq(&fe2)))
}
pub(crate) fn enforce_field_eq(&mut self, _fe1: F, _fe2: F) -> ResolvedValue<F> {
unimplemented!("field equality enforcement not implemented")
}
pub(crate) fn enforce_field_add(&mut self, fe1: F, fe2: F) -> ResolvedValue<F> {
ResolvedValue::FieldElement(fe1.add(&fe2))
@ -106,9 +110,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
ResolvedValue::FieldElement(fe1.div(&fe2))
}
pub(crate) fn enforce_field_pow(&mut self, _fe1: F, _fe2: F) -> ResolvedValue<F> {
unimplemented!("field element exponentiation not supported")
// ResolvedValue::FieldElement(fe1.pow(&fe2))
pub(crate) fn enforce_field_pow(&mut self, fe1: F, num: UInt32) -> ResolvedValue<F> {
ResolvedValue::FieldElement(fe1.pow(&[num.value.unwrap() as u64]))
}
}

View File

@ -95,6 +95,10 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
}
}
pub(crate) fn u32_eq(left: UInt32, right: UInt32) -> ResolvedValue<F> {
ResolvedValue::Boolean(Boolean::Constant(left.eq(&right)))
}
pub(crate) fn enforce_u32_eq(cs: &mut CS, left: UInt32, right: UInt32) -> ResolvedValue<F> {
left.conditional_enforce_equal(
cs.ns(|| format!("enforce field equal")),