Skip to content

Commit

Permalink
add mclBn{Fp,Fr}_pow
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Sep 10, 2024
1 parent 6879251 commit 66b8d9c
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/mcl/bn.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,10 @@ MCLBN_DLL_API int mclBnFr_squareRoot(mclBnFr *y, const mclBnFr *x);
MCLBN_DLL_API int mclBnFp_squareRoot(mclBnFp *y, const mclBnFp *x);
MCLBN_DLL_API int mclBnFp2_squareRoot(mclBnFp2 *y, const mclBnFp2 *x);

// z = x^y[0:ySize] : y[] is little endian
// return 0 if ySize <= 64 (This value may be changed) else -1
MCLBN_DLL_API int mclBnFr_pow(mclBnFr *z, const mclBnFr *x, const uint8_t *y, mclSize ySize);
MCLBN_DLL_API int mclBnFp_pow(mclBnFp *z, const mclBnFp *x, const uint8_t *y, mclSize ySize);
////////////////////////////////////////////////
// set zero
MCLBN_DLL_API void mclBnG1_clear(mclBnG1 *x);
Expand Down
25 changes: 25 additions & 0 deletions include/mcl/impl/bn_c_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,3 +883,28 @@ int mclBnG1_getBasePoint(mclBnG1 *x)
return 0;
}

template<class F>
static int F_pow(F& z, const F& x, const uint8_t *_y, mclSize ySize)
{
if (ySize == 0) {
z = 1;
return 0;
}
const size_t maxSize = 64;
if (ySize > maxSize) return -1;
const size_t yN = maxSize / sizeof(mcl::Unit);
mcl::Unit y[yN];
if (!mcl::fp::convertArrayAsLE(y, yN, _y, ySize)) return -1;
mcl::fp::powUnit(z, x, y, yN);
return 0;
}

int mclBnFr_pow(mclBnFr *z, const mclBnFr *x, const uint8_t *y, mclSize ySize)
{
return F_pow(*cast(z), *cast(x), y, ySize);
}

int mclBnFp_pow(mclBnFp *z, const mclBnFp *x, const uint8_t *y, mclSize ySize)
{
return F_pow(*cast(z), *cast(x), y, ySize);
}
4 changes: 4 additions & 0 deletions include/mcl/operator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ inline size_t argminWforPow(size_t size)
template<class F>
void powUnit(F& z, const F& x, const Unit *y, size_t yn)
{
if (yn == 0) {
z = 1;
return;
}
yn = bint::getRealSize(y, yn);
if (yn == 1) {
switch (y[0]) {
Expand Down
72 changes: 72 additions & 0 deletions test/bn_c_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,78 @@ CYBOZU_TEST_AUTO(Fr)
CYBOZU_TEST_EQUAL(mclBnFr_cmp(&y, &x), 1);
}

CYBOZU_TEST_AUTO(Fr_pow)
{
mclBnFr x, z1, z2;
const char *s = "123456789123456789123";
CYBOZU_TEST_ASSERT(!mclBnFr_setStr(&x, s, strlen(s), 10));
mclBnFr_setInt(&z1, 1);
// small pow
for (uint8_t i = 0; i < 100; i++) {
CYBOZU_TEST_ASSERT(!mclBnFr_pow(&z2, &x, &i, 1));
CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&z1, &z2));
mclBnFr_mul(&z1, &z1, &x);
}
mclBnFr one, negOne;
mclBnFr_setInt(&one, 1);
mclBnFr_setInt(&negOne, -1); // p-1
// large pow
mclBnFr y = z1;
for (int i = 0; i < 100; i++) {
uint8_t yBuf[64];
size_t yn = mclBnFr_getLittleEndian(yBuf, sizeof(yBuf), &y);
CYBOZU_TEST_ASSERT(yn > 0);
mclBnFr_pow(&z1, &x, yBuf, yn); // z1 = x^{y}
mclBnFr_sub(&y, &negOne, &y); // y = p-1-y
yn = mclBnFr_getLittleEndian(yBuf, sizeof(yBuf), &y);
mclBnFr_pow(&z2, &x, yBuf, yn); // z2 = x^{p-1-y}
mclBnFr_mul(&z1, &z1, &z2);
// x^{p-1} = 1 mod p
CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&z1, &one));
}
// err
{
uint8_t buf[100] = {};
CYBOZU_TEST_ASSERT(mclBnFr_pow(&x, &x, buf, sizeof(buf)) < 0);
}
}

CYBOZU_TEST_AUTO(Fp_pow)
{
mclBnFp x, z1, z2;
const char *s = "123456789123456789123";
CYBOZU_TEST_ASSERT(!mclBnFp_setStr(&x, s, strlen(s), 10));
mclBnFp_setInt(&z1, 1);
// small pow
for (uint8_t i = 0; i < 100; i++) {
CYBOZU_TEST_ASSERT(!mclBnFp_pow(&z2, &x, &i, 1));
CYBOZU_TEST_ASSERT(mclBnFp_isEqual(&z1, &z2));
mclBnFp_mul(&z1, &z1, &x);
}
mclBnFp one, negOne;
mclBnFp_setInt(&one, 1);
mclBnFp_setInt(&negOne, -1); // p-1
// large pow
mclBnFp y = z1;
for (int i = 0; i < 100; i++) {
uint8_t yBuf[64];
size_t yn = mclBnFp_getLittleEndian(yBuf, sizeof(yBuf), &y);
CYBOZU_TEST_ASSERT(yn > 0);
mclBnFp_pow(&z1, &x, yBuf, yn); // z1 = x^{y}
mclBnFp_sub(&y, &negOne, &y); // y = p-1-y
yn = mclBnFp_getLittleEndian(yBuf, sizeof(yBuf), &y);
mclBnFp_pow(&z2, &x, yBuf, yn); // z2 = x^{p-1-y}
mclBnFp_mul(&z1, &z1, &z2);
// x^{p-1} = 1 mod p
CYBOZU_TEST_ASSERT(mclBnFp_isEqual(&z1, &one));
}
// err
{
uint8_t buf[100] = {};
CYBOZU_TEST_ASSERT(mclBnFp_pow(&x, &x, buf, sizeof(buf)) < 0);
}
}

void G1test()
{
mclBnG1 x, y, z;
Expand Down

0 comments on commit 66b8d9c

Please sign in to comment.