diff --git a/include/mcl/bn.h b/include/mcl/bn.h index 68053cb..da2fe2f 100644 --- a/include/mcl/bn.h +++ b/include/mcl/bn.h @@ -245,6 +245,14 @@ MCLBN_DLL_API void mclBnFr_setInt32(mclBnFr *y, int x); MCLBN_DLL_API int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize); MCLBN_DLL_API int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize); +/* + write a value as little endian + return written size if success else 0 + @note buf[0] = 0 and return 1 if the value is zero +*/ +MCLBN_DLL_API mclSize mclBnFr_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFr *x); +MCLBN_DLL_API mclSize mclBnFp_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFp *x); + // set (buf mod r) to x // return 0 if bufSize <= (byte size of Fr * 2) else -1 MCLBN_DLL_API int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize); diff --git a/include/mcl/impl/bn_c_impl.hpp b/include/mcl/impl/bn_c_impl.hpp index 7c14f63..2df034d 100644 --- a/include/mcl/impl/bn_c_impl.hpp +++ b/include/mcl/impl/bn_c_impl.hpp @@ -144,6 +144,10 @@ int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize) cast(x)->setArrayMask((const char *)buf, bufSize); return 0; } +mclSize mclBnFr_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFr *x) +{ + return cast(x)->getLittleEndian(buf, maxBufSize); +} int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize) { bool b; @@ -595,6 +599,11 @@ int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize) cast(x)->setArray(&b, (const char *)buf, bufSize, mcl::fp::Mod); return b ? 0 : -1; } + +mclSize mclBnFp_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFp *x) +{ + return cast(x)->getLittleEndian(buf, maxBufSize); +} int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y) { return *cast(x) == *cast(y); diff --git a/test/bn_c_test.hpp b/test/bn_c_test.hpp index 8db329d..cc8ceab 100644 --- a/test/bn_c_test.hpp +++ b/test/bn_c_test.hpp @@ -664,6 +664,37 @@ CYBOZU_TEST_AUTO(mapToG2) CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&P1, &P2)); } +CYBOZU_TEST_AUTO(getLittleEndian) +{ + const struct { + const char *in; + uint8_t out[16]; + size_t size; + } tbl[] = { + { "0", { 0 }, 1 }, + { "1", { 1 }, 1 }, + { "0x1200", { 0x00, 0x12 }, 2 }, + { "0x123400", { 0x00, 0x34, 0x12 }, 3 }, + { "0x1234567890123456ab", { 0xab, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12 }, 9 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + size_t n; + mclBnFr x; + CYBOZU_TEST_ASSERT(!mclBnFr_setStr(&x, tbl[i].in, strlen(tbl[i].in), 0)); + uint8_t buf[128]; + n = mclBnFr_getLittleEndian(buf, tbl[i].size, &x); + CYBOZU_TEST_EQUAL(n, tbl[i].size); + CYBOZU_TEST_EQUAL_ARRAY(buf, tbl[i].out, n); + + n = mclBnFr_getLittleEndian(buf, tbl[i].size + 1, &x); + CYBOZU_TEST_EQUAL(n, tbl[i].size); + CYBOZU_TEST_EQUAL_ARRAY(buf, tbl[i].out, n); + + n = mclBnFr_getLittleEndian(buf, tbl[i].size - 1, &x); + CYBOZU_TEST_EQUAL(n, 0); + } +} + void G1onlyTest(int curve) { printf("curve=%d\n", curve);