reduce exception

dev
MITSUNARI Shigeo 7 years ago
parent e280cc5443
commit b33f6fdaa0
  1. 2
      Makefile
  2. 67
      include/mcl/fp.hpp
  3. 9
      include/mcl/op.hpp
  4. 3
      sample/bench.cpp
  5. 190
      src/conversion.hpp
  6. 82
      src/fp.cpp
  7. 57
      test/conversion_test.cpp
  8. 38
      test/fp_util_test.cpp

@ -3,7 +3,7 @@ LIB_DIR=lib
OBJ_DIR=obj
EXE_DIR=bin
SRC_SRC=fp.cpp bn_c256.cpp bn_c384.cpp bn_c512.cpp she_c256.cpp
TEST_SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal_test.cpp fp_tower_test.cpp gmp_test.cpp bn_test.cpp bn384_test.cpp glv_test.cpp paillier_test.cpp she_test.cpp vint_test.cpp bn512_test.cpp ecdsa_test.cpp
TEST_SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal_test.cpp fp_tower_test.cpp gmp_test.cpp bn_test.cpp bn384_test.cpp glv_test.cpp paillier_test.cpp she_test.cpp vint_test.cpp bn512_test.cpp ecdsa_test.cpp conversion_test.cpp
TEST_SRC+=bn_c256_test.cpp bn_c384_test.cpp bn_c512_test.cpp she_c256_test.cpp she_c384_test.cpp
TEST_SRC+=aggregate_sig_test.cpp
TEST_SRC+=bls12_test.cpp

@ -92,6 +92,23 @@ void loadWord(std::string& s, InputStream& is)
}
}
template<class InputStream>
size_t loadWord(char *buf, size_t bufSize, InputStream& is)
{
if (bufSize == 0) return 0;
char c;
if (!skipSpace(&c, is)) return 0;
size_t pos = 0;
buf[pos++] = c;
for (;;) {
if (!cybozu::readChar(&c, is)) break;
if (isSpace(c)) break;
if (pos == bufSize) return 0;
buf[pos++] = c;
}
return pos;
}
} // local
} // mcl::fp
@ -243,46 +260,72 @@ public:
if (isMont()) op_.fromMont(v_, v_);
}
template<class InputStream>
void load(InputStream& is, int ioMode = IoSerialize)
void load(InputStream& is, int ioMode, bool *pb)
{
bool isMinus = false;
*pb = false;
if (ioMode & (IoArray | IoArrayRaw | IoSerialize)) {
const size_t n = getByteSize();
v_[op_.N - 1] = 0;
if (cybozu::readSome(v_, n, is) != n) throw cybozu::Exception("FpT:load:can't read") << n;
if (cybozu::readSome(v_, n, is) != n) {
return;
}
} else {
std::string str;
fp::local::loadWord(str, is);
fp::strToArray(&isMinus, v_, op_.N, str, ioMode);
char buf[1024];
size_t n = fp::local::loadWord(buf, sizeof(buf), is);
if (n == 0 || !fp::strToArray(&isMinus, v_, op_.N, buf, n, ioMode)) {
return;
}
}
if (fp::isGreaterOrEqualArray(v_, op_.p, op_.N)) {
return;
}
if (fp::isGreaterOrEqualArray(v_, op_.p, op_.N)) throw cybozu::Exception("FpT:load:large value");
if (isMinus) {
neg(*this, *this);
}
if (!(ioMode & IoArrayRaw)) {
toMont();
}
*pb = true;
}
template<class OutputStream>
void save(OutputStream& os, int ioMode = IoSerialize) const
void save(OutputStream& os, int ioMode, bool *pb) const
{
const size_t n = getByteSize();
if (ioMode & (IoArray | IoArrayRaw | IoSerialize)) {
if (ioMode & IoArrayRaw) {
cybozu::write(os, v_, n);
cybozu::write(os, v_, n, pb);
} else {
fp::Block b;
getBlock(b);
cybozu::write(os, b.p, n);
cybozu::write(os, b.p, n, pb);
}
return;
}
fp::Block b;
getBlock(b);
std::string str;
// use low 8-bit ioMode for Fp
fp::arrayToStr(str, b.p, b.n, ioMode & 255);
cybozu::write(os, str.c_str(), str.size());
char buf[2048];
size_t len = fp::arrayToStr(buf, sizeof(buf), b.p, b.n, ioMode & 255);
if (len == 0) {
*pb = false;
return;
}
cybozu::write(os, buf + sizeof(buf) - len, len, pb);
}
template<class OutputStream>
void save(OutputStream& os, int ioMode = IoSerialize) const
{
bool b;
save(os, ioMode, &b);
if (!b) throw cybozu::Exception("fp:save") << ioMode;
}
template<class InputStream>
void load(InputStream& is, int ioMode = IoSerialize)
{
bool b;
load(is, ioMode, &b);
if (!b) throw cybozu::Exception("fp:load") << ioMode;
}
/*
throw exception if x >= p

@ -323,9 +323,14 @@ private:
/*
conevrt string to array according to ioMode,
*/
void strToArray(bool *pIsMinus, Unit *x, size_t xN, const std::string& str, int ioMode);
bool strToArray(bool *pIsMinus, Unit *x, size_t xN, const std::string& str, int ioMode);
bool strToArray(bool *pIsMinus, Unit *x, size_t xN, const char *buf, size_t bufSize, int ioMode);
void arrayToStr(std::string& str, const Unit *x, size_t n, int ioMode);
/*
return retavl is written size if success else 0
REMARK : the top of string is buf + bufSize - retval
*/
size_t arrayToStr(char *buf, size_t bufSize, const Unit *x, size_t n, int ioMode);
inline const char* getIoSeparator(int ioMode)
{

@ -146,9 +146,10 @@ void benchToStr16()
};
Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
char buf[128];
std::string str;
Fp x(tbl[i]);
CYBOZU_BENCH("fp::toStr16", mcl::fp::toStr16, str, x.getUnit(), x.getUnitSize(), 16);
CYBOZU_BENCH("fp::arrayToHex", mcl::fp::arrayToHex, buf, sizeof(buf), x.getUnit(), x.getUnitSize(), true);
mpz_class y(tbl[i]);
CYBOZU_BENCH("gmp:getStr ", mcl::gmp::getStr, str, y, 16);
}

@ -14,11 +14,13 @@
namespace mcl { namespace fp {
/*
convert x[0..n) to hex string
convert little endian x[0, xn) to buf
return written size if success else 0
data is buf[bufSize - retval, bufSize)
start "0x" if withPrefix
*/
template<class T>
void toStr16(std::string& str, const T *x, size_t n, bool withPrefix = false)
size_t arrayToHex(char *buf, size_t bufSize, const T *x, size_t n, bool withPrefix = false)
{
size_t fullN = 0;
if (n > 1) {
@ -33,23 +35,28 @@ void toStr16(std::string& str, const T *x, size_t n, bool withPrefix = false)
const size_t topLen = cybozu::getHexLength(v);
const size_t startPos = withPrefix ? 2 : 0;
const size_t lenT = sizeof(T) * 2;
str.resize(startPos + fullN * lenT + topLen);
const size_t totalSize = startPos + fullN * lenT + topLen;
if (totalSize > bufSize) return 0;
char *const top = buf + bufSize - totalSize;
if (withPrefix) {
str[0] = '0';
str[1] = 'x';
top[0] = '0';
top[1] = 'x';
}
cybozu::itohex(&str[startPos], topLen, v, false);
cybozu::itohex(&top[startPos], topLen, v, false);
for (size_t i = 0; i < fullN; i++) {
cybozu::itohex(&str[startPos + topLen + i * lenT], lenT, x[fullN - 1 - i], false);
cybozu::itohex(&top[startPos + topLen + i * lenT], lenT, x[fullN - 1 - i], false);
}
return totalSize;
}
/*
convert x[0..n) to bin string
convert little endian x[0, xn) to buf
return written size if success else 0
data is buf[bufSize - retval, bufSize)
start "0b" if withPrefix
*/
template<class T>
void toStr2(std::string& str, const T *x, size_t n, bool withPrefix)
size_t arrayToBin(char *buf, size_t bufSize, const T *x, size_t n, bool withPrefix)
{
size_t fullN = 0;
if (n > 1) {
@ -64,15 +71,18 @@ void toStr2(std::string& str, const T *x, size_t n, bool withPrefix)
const size_t topLen = cybozu::getBinLength(v);
const size_t startPos = withPrefix ? 2 : 0;
const size_t lenT = sizeof(T) * 8;
str.resize(startPos + fullN * lenT + topLen);
const size_t totalSize = startPos + fullN * lenT + topLen;
if (totalSize > bufSize) return 0;
char *const top = buf + bufSize - totalSize;
if (withPrefix) {
str[0] = '0';
str[1] = 'b';
top[0] = '0';
top[1] = 'b';
}
cybozu::itobin(&str[startPos], topLen, v);
cybozu::itobin(&top[startPos], topLen, v);
for (size_t i = 0; i < fullN; i++) {
cybozu::itobin(&str[startPos + topLen + i * lenT], lenT, x[fullN - 1 - i]);
cybozu::itobin(&top[startPos + topLen + i * lenT], lenT, x[fullN - 1 - i]);
}
return totalSize;
}
/*
@ -101,5 +111,155 @@ void fromStr16(T *x, size_t xn, const char *str, size_t strLen)
for (size_t i = requireSize; i < xn; i++) x[i] = 0;
}
namespace local {
} } // mcl::fp
/*
q = x[] / x
@retval r = x[] % x
@note accept q == x
*/
inline uint32_t divU32(uint32_t *q, const uint32_t *x, size_t xn, uint32_t y)
{
if (xn == 0) return 0;
uint32_t r = 0;
for (int i = (int)xn - 1; i >= 0; i--) {
uint64_t t = (uint64_t(r) << 32) | x[i];
q[i] = uint32_t(t / y);
r = uint32_t(t % y);
}
return r;
}
/*
z[0, xn) = x[0, xn) * y
return z[xn]
@note accept z == x
*/
inline uint32_t mulU32(uint32_t *z, const uint32_t *x, size_t xn, uint32_t y)
{
uint32_t H = 0;
for (size_t i = 0; i < xn; i++) {
uint32_t t = H;
uint64_t v = uint64_t(x[i]) * y;
uint32_t L = uint32_t(v);
H = uint32_t(v >> 32);
z[i] = t + L;
if (z[i] < t) {
H++;
}
}
return H;
}
/*
x[0, xn) += y
return 1 if overflow else 0
*/
inline uint32_t addU32(uint32_t *x, size_t xn, uint32_t y)
{
uint32_t t = x[0] + y;
x[0] = t;
if (t >= y) return 0;
for (size_t i = 1; i < xn; i++) {
t = x[i] + 1;
x[i] = t;
if (t != 0) return 0;
}
return 1;
}
inline uint32_t decToU32(const char *p, size_t size, bool *pb)
{
assert(0 < size && size <= 9);
uint32_t x = 0;
for (size_t i = 0; i < size; i++) {
char c = p[i];
if (c < '0' || c > '9') {
*pb = false;
return 0;
}
x = x * 10 + uint32_t(c - '0');
}
*pb = true;
return x;
}
} // mcl::fp::local
/*
little endian x[0, xn) to buf
return written size if success else 0
data is buf[bufSize - retval, bufSize)
*/
template<class UT>
inline size_t arrayToDec(char *buf, size_t bufSize, const UT *x, size_t xn)
{
const size_t maxN = 64;
uint32_t t[maxN];
if (sizeof(UT) == 8) {
xn *= 2;
}
if (xn > maxN) return 0;
memcpy(t, x, xn * sizeof(t[0]));
const size_t width = 9;
const uint32_t i1e9 = 1000000000U;
size_t pos = 0;
for (;;) {
uint32_t r = local::divU32(t, t, xn, i1e9);
while (xn > 0 && t[xn - 1] == 0) xn--;
size_t len = cybozu::itoa_local::uintToDec(buf, bufSize - pos, r);
if (len == 0) return 0;
assert(0 < len && len <= width);
if (xn == 0) return pos + len;
// fill (width - len) '0'
for (size_t j = 0; j < width - len; j++) {
buf[bufSize - pos - width + j] = '0';
}
pos += width;
}
}
/*
convert buf[0, bufSize) to x[0, num)
return written num if success else 0
*/
template<class UT>
inline size_t convertDecToArray(UT *_x, size_t xSize, const char *buf, size_t bufSize)
{
assert(sizeof(UT) == 4 || sizeof(UT) == 8);
const size_t width = 9;
const uint32_t i1e9 = 1000000000U;
if (xSize == 0) return 0;
if (sizeof(UT) == 8) {
xSize *= 2;
}
uint32_t *x = reinterpret_cast<uint32_t*>(_x);
size_t xn = 1;
x[0] = 0;
while (bufSize > 0) {
size_t n = bufSize % width;
if (n == 0) n = width;
bool b;
uint32_t v = local::decToU32(buf, n, &b);
if (!b) return 0;
uint32_t H = local::mulU32(x, x, xn, i1e9);
if (H > 0) {
if (xn == xSize) return 0;
x[xn++] = H;
}
H = local::addU32(x, xn, v);
if (H > 0) {
if (xn == xSize) return 0;
x[xn++] = H;
}
buf += n;
bufSize -= n;
}
if (sizeof(UT) == 8 && (xn & 1)) {
x[xn++] = 0;
}
return xn / (sizeof(UT) / 4);
}
} } // mcp::fp

@ -63,35 +63,39 @@ inline Unit getUnitAsLE(const void *p)
#endif
}
const char *verifyStr(bool *isMinus, int *base, const std::string& str)
bool parsePrefix(size_t *readSize, bool *isMinus, int *base, const char *buf, size_t bufSize)
{
const char *p = str.c_str();
if (*p == '-') {
if (bufSize == 0) return false;
size_t pos = 0;
if (*buf == '-') {
if (bufSize == 1) return false;
*isMinus = true;
p++;
buf++;
pos++;
} else {
*isMinus = false;
}
if (p[0] == '0') {
if (p[1] == 'x') {
if (buf[0] == '0') {
if (bufSize > 1 && buf[1] == 'x') {
if (*base == 0 || *base == 16 || *base == (16 | IoPrefix)) {
*base = 16;
p += 2;
pos += 2;
} else {
throw cybozu::Exception("fp:verifyStr:0x conflicts with") << *base;
return false;
}
} else if (p[1] == 'b') {
} else if (bufSize > 1 && buf[1] == 'b') {
if (*base == 0 || *base == 2 || *base == (2 | IoPrefix)) {
*base = 2;
p += 2;
pos += 2;
} else {
throw cybozu::Exception("fp:verifyStr:0b conflicts with") << *base;
return false;
}
}
}
if (*base == 0) *base = 10;
if (*p == '\0') throw cybozu::Exception("fp:verifyStr:str is empty");
return p;
if (pos == bufSize) return false;
*readSize = pos;
return true;
}
const char *ModeToStr(Mode mode)
@ -442,13 +446,17 @@ void Op::init(const std::string& mstr, size_t maxBitSize, Mode mode, size_t mclM
{ // set mp and p
bool isMinus = false;
int base = 0;
const char *pstr = verifyStr(&isMinus, &base, mstr);
if (isMinus) throw cybozu::Exception("Op:init:mstr is minus") << mstr;
size_t readSize;
if (!parsePrefix(&readSize, &isMinus, &base, mstr.c_str(), mstr.size())) {
throw cybozu::Exception("fp:parsePrefix");
}
const char *pstr = mstr.c_str() + readSize;
if (!gmp::setStr(mp, pstr, base)) {
throw cybozu::Exception("Op:init:bad str") << mstr;
}
if (mp == 0) throw cybozu::Exception("Op:init:mstr is zero") << mstr;
if (isMinus) throw cybozu::Exception("Op:init:mstr is minus") << mstr;
}
if (mp == 0) throw cybozu::Exception("Op:init:mstr is zero") << mstr;
gmp::getArray(p, (maxBitSize + fp::UnitBitSize - 1) / fp::UnitBitSize, mp);
bitSize = gmp::getBitSize(mp);
pmod4 = gmp::getUnit(mp, 0) % 4;
@ -571,27 +579,20 @@ void Op::init(const std::string& mstr, size_t maxBitSize, Mode mode, size_t mclM
}
}
void arrayToStr(std::string& str, const Unit *x, size_t n, int ioMode)
size_t arrayToStr(char *buf, size_t bufSize, const Unit *x, size_t n, int ioMode)
{
int base = ioMode & ~IoPrefix;
bool withPrefix = (ioMode & IoPrefix) != 0;
switch (base) {
case 0:
case 10:
{
mpz_class t;
gmp::setArray(t, x, n);
gmp::getStr(str, t, 10);
}
return;
return mcl::fp::arrayToDec(buf, bufSize, x, n);
case 16:
mcl::fp::toStr16(str, x, n, withPrefix);
return;
return mcl::fp::arrayToHex(buf, bufSize, x, n, withPrefix);
case 2:
mcl::fp::toStr2(str, x, n, withPrefix);
return;
return mcl::fp::arrayToBin(buf, bufSize, x, n, withPrefix);
default:
throw cybozu::Exception("fp:arrayToStr:bad base") << base;
return 0;
}
}
@ -639,17 +640,22 @@ int detectIoMode(int ioMode, const std::ios_base& ios)
return ioMode;
}
void strToArray(bool *pIsMinus, Unit *x, size_t xN, const std::string& str, int ioMode)
bool strToArray(bool *pIsMinus, Unit *x, size_t xN, const char *buf, size_t bufSize, int ioMode)
{
assert(!(ioMode & (IoArray | IoArrayRaw | IoSerialize)));
// use low 8-bit ioMode for Fp
ioMode &= 0xff;
const char *p = verifyStr(pIsMinus, &ioMode, str);
size_t readSize;
if (!parsePrefix(&readSize, pIsMinus, &ioMode, buf, bufSize)) return false;
#if 0
#else
mpz_class mx;
if (!gmp::setStr(mx, p, ioMode)) {
throw cybozu::Exception("fp:strToArray:bad format") << ioMode << str;
if (!gmp::setStr(mx, std::string(buf + readSize, bufSize - readSize), ioMode)) {
return false;
}
gmp::getArray(x, xN, mx);
#endif
return true;
}
void copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, MaskMode maskMode)
@ -704,11 +710,7 @@ uint64_t getUint64(bool *pb, const fp::Block& b)
if (pb) *pb = true;
return v;
}
if (!pb) {
std::string str;
arrayToStr(str, b.p, b.n, 10);
throw cybozu::Exception("fp::getUint64:large value") << str;
}
if (!pb) throw cybozu::Exception("fp::getUint64:large value");
*pb = false;
return 0;
}
@ -743,11 +745,7 @@ int64_t getInt64(bool *pb, fp::Block& b, const fp::Op& op)
}
}
}
if (!pb) {
std::string str;
arrayToStr(str, b.p, b.n, 10);
throw cybozu::Exception("fp::getInt64:large value") << str << isNegative;
}
if (!pb) throw cybozu::Exception("fp::getInt64:large value");
*pb = false;
return 0;
}

@ -0,0 +1,57 @@
#include <cybozu/test.hpp>
#include "../src/conversion.hpp"
CYBOZU_TEST_AUTO(arrayToDec)
{
const struct {
uint32_t x[5];
size_t xn;
const char *s;
} tbl[] = {
{ { 0, 0, 0, 0, 0 }, 1, "0" },
{ { 9, 0, 0, 0, 0 }, 1, "9" },
{ { 123456789, 0, 0, 0, 0 }, 1, "123456789" },
{ { 2147483647, 0, 0, 0, 0 }, 1, "2147483647" },
{ { 0xffffffff, 0, 0, 0, 0 }, 1, "4294967295" },
{ { 0x540be400, 0x2, 0, 0, 0 }, 2, "10000000000" },
{ { 0xffffffff, 0xffffffff, 0, 0, 0 }, 2, "18446744073709551615" },
{ { 0x89e80001, 0x8ac72304, 0, 0, 0 }, 2, "10000000000000000001" },
{ { 0xc582ca00, 0x8ac72304, 0, 0, 0 }, 2, "10000000001000000000" },
{ { 0, 0, 1, 0, 0 }, 3, "18446744073709551616" },
{ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 }, 4, "340282366920938463463374607431768211455" },
{ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, 5, "1461501637330902918203684832716283019655932542975" },
{ { 0x3b9aca00, 0x5e3f3700, 0x1cbfa532, 0x04f6433a, 0xd83ff078 }, 5, "1234567901234560000000000000000000000001000000000" },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
const size_t bufSize = 128;
char buf[bufSize] = {};
const char *str = tbl[i].s;
const uint32_t *x = tbl[i].x;
const size_t strLen = strlen(str);
size_t n = mcl::fp::arrayToDec(buf, bufSize, x, tbl[i].xn);
CYBOZU_TEST_EQUAL(n, strLen);
CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n);
const size_t maxN = 32;
uint32_t xx[maxN] = {};
size_t xn = mcl::fp::convertDecToArray(xx, maxN, str, strLen);
CYBOZU_TEST_EQUAL(xn, tbl[i].xn);
CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn);
}
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
const size_t bufSize = 128;
char buf[bufSize] = {};
const char *str = tbl[i].s;
const size_t strLen = strlen(str);
uint64_t x[8] = {};
size_t xn = (tbl[i].xn + 1) / 2;
memcpy(x, tbl[i].x, tbl[i].xn * sizeof(uint32_t));
size_t n = mcl::fp::arrayToDec(buf, bufSize, x, xn);
CYBOZU_TEST_EQUAL(n, strLen);
CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n);
const size_t maxN = 32;
uint64_t xx[maxN] = {};
size_t xxn = mcl::fp::convertDecToArray(xx, maxN, str, strLen);
CYBOZU_TEST_EQUAL(xxn, xn);
CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn);
}
}

@ -4,7 +4,7 @@
#include <mcl/gmp_util.hpp>
#include <mcl/fp.hpp>
CYBOZU_TEST_AUTO(toStr16)
CYBOZU_TEST_AUTO(arrayToHex)
{
const struct {
uint32_t x[4];
@ -18,15 +18,39 @@ CYBOZU_TEST_AUTO(toStr16)
{ { 1, 2, 0xffffffff, 0x123abc }, 4, "123abcffffffff0000000200000001" },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
std::string str;
mcl::fp::toStr16(str, tbl[i].x, tbl[i].n, false);
CYBOZU_TEST_EQUAL(str, tbl[i].str);
mcl::fp::toStr16(str, tbl[i].x, tbl[i].n, true);
CYBOZU_TEST_EQUAL(str, std::string("0x") + tbl[i].str);
char buf[64];
size_t n = mcl::fp::arrayToHex(buf, sizeof(buf), tbl[i].x, tbl[i].n, false);
CYBOZU_TEST_ASSERT(n > 0);
CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, tbl[i].str, n);
n = mcl::fp::arrayToHex(buf, sizeof(buf), tbl[i].x, tbl[i].n, true);
CYBOZU_TEST_ASSERT(n > 0);
CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, (std::string("0x") + tbl[i].str).c_str(), n);
}
}
// CYBOZU_TEST_AUTO(toStr2) // QQQ
CYBOZU_TEST_AUTO(arrayToBin)
{
const struct {
uint32_t x[4];
size_t n;
const char *str;
} tbl[] = {
{ { 0, 0, 0, 0 }, 0, "0" },
{ { 0x123, 0, 0, 0 }, 1, "100100011" },
{ { 0x12345678, 0xaabbcc, 0, 0 }, 2, "10101010101110111100110000010010001101000101011001111000" },
{ { 0, 0x12, 0x234a, 0 }, 3, "100011010010100000000000000000000000000001001000000000000000000000000000000000" },
{ { 1, 2, 0xffffffff, 0x123abc }, 4, "100100011101010111100111111111111111111111111111111110000000000000000000000000000001000000000000000000000000000000001" },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
char buf[512];
size_t n = mcl::fp::arrayToBin(buf, sizeof(buf), tbl[i].x, tbl[i].n, false);
CYBOZU_TEST_ASSERT(n > 0);
CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, tbl[i].str, n);
n = mcl::fp::arrayToBin(buf, sizeof(buf), tbl[i].x, tbl[i].n, true);
CYBOZU_TEST_ASSERT(n > 0);
CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, (std::string("0b") + tbl[i].str).c_str(), n);
}
}
// CYBOZU_TEST_AUTO(verifyStr) // QQQ
CYBOZU_TEST_AUTO(fromStr16)

Loading…
Cancel
Save