mirror of
https://github.com/status-im/c-kzg-4844.git
synced 2025-01-11 02:35:53 +00:00
Simplify fr_batch_inv
and reject zero inputs (#215)
This commit is contained in:
parent
2ba8f35dc4
commit
903a13fb98
@ -254,6 +254,20 @@ static bool fr_is_one(const fr_t *p) {
|
|||||||
return a[0] == 1 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
return a[0] == 1 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the operand is zero in the finite field.
|
||||||
|
*
|
||||||
|
* @param[in] p The field element to be checked
|
||||||
|
*
|
||||||
|
* @retval true The element is zero
|
||||||
|
* @retval false The element is not zero
|
||||||
|
*/
|
||||||
|
static bool fr_is_zero(const fr_t *p) {
|
||||||
|
uint64_t a[4];
|
||||||
|
blst_uint64_from_fr(a, p);
|
||||||
|
return a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether two field elements are equal.
|
* Test whether two field elements are equal.
|
||||||
*
|
*
|
||||||
@ -332,42 +346,43 @@ static void fr_from_uint64(fr_t *out, uint64_t n) {
|
|||||||
/**
|
/**
|
||||||
* Montgomery batch inversion in finite field.
|
* Montgomery batch inversion in finite field.
|
||||||
*
|
*
|
||||||
|
* @remark Return C_KZG_BADARGS if a zero is found in the input.
|
||||||
|
*
|
||||||
* @remark This function does not support in-place computation (i.e. `a` MUST
|
* @remark This function does not support in-place computation (i.e. `a` MUST
|
||||||
* NOT point to the same place as `out`)
|
* NOT point to the same place as `out`)
|
||||||
*
|
*
|
||||||
|
* @remark This function only supports len > 0.
|
||||||
|
*
|
||||||
* @param[out] out The inverses of @p a, length @p len
|
* @param[out] out The inverses of @p a, length @p len
|
||||||
* @param[in] a A vector of field elements, length @p len
|
* @param[in] a A vector of field elements, length @p len
|
||||||
* @param[in] len The number of field elements
|
* @param[in] len The number of field elements
|
||||||
*/
|
*/
|
||||||
static C_KZG_RET fr_batch_inv(fr_t *out, const fr_t *a, size_t len) {
|
static C_KZG_RET fr_batch_inv(fr_t *out, const fr_t *a, int len) {
|
||||||
C_KZG_RET ret;
|
int i;
|
||||||
fr_t *prod = NULL;
|
|
||||||
fr_t inv;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
assert(a != out);
|
assert(a != out);
|
||||||
|
|
||||||
ret = new_fr_array(&prod, len);
|
fr_t accumulator = FR_ONE;
|
||||||
if (ret != C_KZG_OK) goto out;
|
|
||||||
|
|
||||||
prod[0] = a[0];
|
for (i = 0; i < len; i++) {
|
||||||
|
out[i] = accumulator;
|
||||||
for (i = 1; i < len; i++) {
|
blst_fr_mul(&accumulator, &accumulator, &a[i]);
|
||||||
blst_fr_mul(&prod[i], &a[i], &prod[i - 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blst_fr_eucl_inverse(&inv, &prod[len - 1]);
|
/* Bail on any zero input */
|
||||||
|
if (fr_is_zero(&accumulator)) {
|
||||||
for (i = len - 1; i > 0; i--) {
|
return C_KZG_BADARGS;
|
||||||
blst_fr_mul(&out[i], &inv, &prod[i - 1]);
|
|
||||||
blst_fr_mul(&inv, &a[i], &inv);
|
|
||||||
}
|
}
|
||||||
out[0] = inv;
|
|
||||||
|
|
||||||
out:
|
blst_fr_eucl_inverse(&accumulator, &accumulator);
|
||||||
c_kzg_free(prod);
|
|
||||||
return ret;
|
for (i = len - 1; i >= 0; i--) {
|
||||||
|
blst_fr_mul(&out[i], &out[i], &accumulator);
|
||||||
|
blst_fr_mul(&accumulator, &accumulator, &a[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -287,6 +287,7 @@ static void test_fr_batch_inv__test_consistent(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Make sure that batch inverse doesn't support zeroes */
|
||||||
static void test_fr_batch_inv__test_zero(void) {
|
static void test_fr_batch_inv__test_zero(void) {
|
||||||
C_KZG_RET ret;
|
C_KZG_RET ret;
|
||||||
fr_t a[32], batch_inverses[32];
|
fr_t a[32], batch_inverses[32];
|
||||||
@ -298,12 +299,7 @@ static void test_fr_batch_inv__test_zero(void) {
|
|||||||
a[5] = FR_ZERO;
|
a[5] = FR_ZERO;
|
||||||
|
|
||||||
ret = fr_batch_inv(batch_inverses, a, 32);
|
ret = fr_batch_inv(batch_inverses, a, 32);
|
||||||
ASSERT_EQUALS(ret, C_KZG_OK);
|
ASSERT_EQUALS(ret, C_KZG_BADARGS);
|
||||||
|
|
||||||
for (size_t i = 0; i < 32; i++) {
|
|
||||||
bool ok = fr_equal(&batch_inverses[i], &FR_ZERO);
|
|
||||||
ASSERT_EQUALS(ok, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user