diff --git a/include/mcl/bn.h b/include/mcl/bn.h index f18c6da..68b8721 100644 --- a/include/mcl/bn.h +++ b/include/mcl/bn.h @@ -281,7 +281,10 @@ MCLBN_DLL_API int mclBnFp_isValid(const mclBnFp *x); MCLBN_DLL_API int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y); MCLBN_DLL_API int mclBnFp_isZero(const mclBnFp *x); MCLBN_DLL_API int mclBnFp_isOne(const mclBnFp *x); + MCLBN_DLL_API int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y); +MCLBN_DLL_API int mclBnFp2_isZero(const mclBnFp2 *x); +MCLBN_DLL_API int mclBnFp2_isOne(const mclBnFp2 *x); #ifndef MCL_DONT_USE_CSRPNG // return 0 if success @@ -325,6 +328,14 @@ MCLBN_DLL_API void mclBnFp_sub(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); MCLBN_DLL_API void mclBnFp_mul(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); MCLBN_DLL_API void mclBnFp_div(mclBnFp *z, const mclBnFp *x, const mclBnFp *y); +MCLBN_DLL_API void mclBnFp2_neg(mclBnFp2 *y, const mclBnFp2 *x); +MCLBN_DLL_API void mclBnFp2_inv(mclBnFp2 *y, const mclBnFp2 *x); +MCLBN_DLL_API void mclBnFp2_sqr(mclBnFp2 *y, const mclBnFp2 *x); +MCLBN_DLL_API void mclBnFp2_add(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); +MCLBN_DLL_API void mclBnFp2_sub(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); +MCLBN_DLL_API void mclBnFp2_mul(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); +MCLBN_DLL_API void mclBnFp2_div(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y); + // y is one of square root of x // return 0 if success else -1 MCLBN_DLL_API int mclBnFr_squareRoot(mclBnFr *y, const mclBnFr *x); diff --git a/include/mcl/impl/bn_c_impl.hpp b/include/mcl/impl/bn_c_impl.hpp index ce67455..c02ab79 100644 --- a/include/mcl/impl/bn_c_impl.hpp +++ b/include/mcl/impl/bn_c_impl.hpp @@ -269,6 +269,35 @@ void mclBnFp_div(mclBnFp *z, const mclBnFp *x, const mclBnFp *y) Fp::div(*cast(z),*cast(x), *cast(y)); } +void mclBnFp2_neg(mclBnFp2 *y, const mclBnFp2 *x) +{ + Fp2::neg(*cast(y), *cast(x)); +} +void mclBnFp2_inv(mclBnFp2 *y, const mclBnFp2 *x) +{ + Fp2::inv(*cast(y), *cast(x)); +} +void mclBnFp2_sqr(mclBnFp2 *y, const mclBnFp2 *x) +{ + Fp2::sqr(*cast(y), *cast(x)); +} +void mclBnFp2_add(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y) +{ + Fp2::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnFp2_sub(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y) +{ + Fp2::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnFp2_mul(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y) +{ + Fp2::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnFp2_div(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y) +{ + Fp2::div(*cast(z),*cast(x), *cast(y)); +} + int mclBnFr_squareRoot(mclBnFr *y, const mclBnFr *x) { return Fr::squareRoot(*cast(y), *cast(x)) ? 0 : -1; @@ -714,6 +743,14 @@ int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y) { return *cast(x) == *cast(y); } +int mclBnFp2_isZero(const mclBnFp2 *x) +{ + return cast(x)->isZero(); +} +int mclBnFp2_isOne(const mclBnFp2 *x) +{ + return cast(x)->isOne(); +} int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x) { diff --git a/test/bn_c_test.hpp b/test/bn_c_test.hpp index 62d7871..953c5a4 100644 --- a/test/bn_c_test.hpp +++ b/test/bn_c_test.hpp @@ -755,9 +755,34 @@ CYBOZU_TEST_AUTO(Fp2) n = mclBnFp2_deserialize(&x2, buf, n); CYBOZU_TEST_ASSERT(n > 0); CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&x1, &x2)); + + mclBnFp2 y, z; + mclBnFp2_add(&y, &x1, &x2); + for (int i = 0; i < 2; i++) { + mclBnFp t; + mclBnFp_add(&t, &x1.d[i], &x2.d[i]); + CYBOZU_TEST_ASSERT(mclBnFp_isEqual(&y.d[i], &t)); + } + mclBnFp2_sub(&y, &y, &x2); + CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&y, &x1)); + mclBnFp2_mul(&y, &x1, &x2); + mclBnFp2_div(&y, &y, &x1); + CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&y, &x2)); + mclBnFp2_inv(&y, &x1); + mclBnFp2_mul(&y, &y, &x1); + CYBOZU_TEST_ASSERT(mclBnFp2_isOne(&y)); + mclBnFp2_sqr(&y, &x1); + mclBnFp2_mul(&z, &x1, &x1); + CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&y, &z)); + mclBnFp2_sub(&y, &x1, &x2); + mclBnFp2_sub(&z, &x2, &x1); + mclBnFp2_neg(&z, &z); + CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&y, &z)); + mclBnFp2_clear(&x1); memset(&x2, 0, sizeof(x2)); CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&x1, &x2)); + CYBOZU_TEST_ASSERT(mclBnFp2_isZero(&x1)); } CYBOZU_TEST_AUTO(squareRootFr)