Skip to content

Commit

Permalink
Fix for informational issue (ZKS.11) Mixing Constant and Variable Lim…
Browse files Browse the repository at this point in the history
…bs Is Not Supported
  • Loading branch information
Rumata888 committed Oct 30, 2024
1 parent e91601f commit b2513fd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,35 @@ template <typename Builder> class stdlib_bigfield : public testing::Test {
typedef typename bn254::witness_ct witness_ct;

public:
static void test_add_to_lower_limb_regression()
{
auto builder = Builder();
fq_ct constant = fq_ct(1);
fq_ct var = fq_ct::create_from_u512_as_witness(&builder, 1);
fr_ct small_var = witness_ct(&builder, fr(1));
fq_ct mixed = fq_ct(1).add_to_lower_limb(small_var, 1);
fq_ct r;

r = mixed + mixed;
r = mixed - mixed;
r = mixed + var;
r = mixed + constant;
r = mixed - var;
r = mixed - constant;
r = var - mixed;

r = var * constant;
r = constant / var;
r = constant * constant;
r = constant / constant;

r = mixed * var;
r = mixed / var;
r = mixed * mixed;
r = mixed * constant;
bool result = CircuitChecker::check(builder);
EXPECT_EQ(result, true);
}
// The bug happens when we are applying the CRT formula to a*b < r, which can happen when using the division
// operator
static void test_division_formula_bug()
Expand Down Expand Up @@ -1201,6 +1230,10 @@ TYPED_TEST(stdlib_bigfield, assert_not_equal_regression)
TestFixture::test_assert_not_equal_regression();
}

TYPED_TEST(stdlib_bigfield, add_to_lower_limb_regression)
{
TestFixture::test_add_to_lower_limb_regression();
}
TYPED_TEST(stdlib_bigfield, badmul)
{
TestFixture::test_bad_mul();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,25 @@ bigfield<Builder, T> bigfield<Builder, T>::add_to_lower_limb(const field_t<Build
if (is_constant() && other.is_constant()) {
return bigfield(ctx, uint256_t((get_value() + uint256_t(other.get_value())) % modulus_u512));
}
bigfield result = *this;

bigfield result;
// If the original value is constant, we have to reinitialize the higher limbs to be witnesses when adding a witness
if (is_constant()) {
auto context = other.context;
for (size_t i = 1; i < 4; i++) {
// Construct a witness element from the original constant limb
result.binary_basis_limbs[i] =
Limb(field_t<Builder>::from_witness(context, binary_basis_limbs[i].element.get_value()),
binary_basis_limbs[i].maximum_value);
// Ensure it is fixed
result.binary_basis_limbs[i].element.fix_witness();
result.context = ctx;
}
} else {

// if this element is a witness, then all limbs will be witnesses
result = *this;
}
result.binary_basis_limbs[0].maximum_value = binary_basis_limbs[0].maximum_value + other_maximum_value;

result.binary_basis_limbs[0].element = binary_basis_limbs[0].element + other;
Expand Down

0 comments on commit b2513fd

Please sign in to comment.