add readHexStr, writeHexStr

dev
MITSUNARI Shigeo 6 years ago
parent 76b13b05ed
commit 093a13335d
  1. 69
      include/mcl/conversion.hpp
  2. 3
      include/mcl/op.hpp
  3. 37
      test/conversion_test.cpp

@ -131,23 +131,31 @@ inline uint32_t decToU32(const char *p, size_t size, bool *pb)
return x; return x;
} }
inline bool hexCharToUint8(uint8_t *v, char _c)
{
uint32_t c = uint8_t(_c); // cast is necessary
if (c - '0' <= '9' - '0') {
c = c - '0';
} else if (c - 'a' <= 'f' - 'a') {
c = (c - 'a') + 10;
} else if (c - 'A' <= 'F' - 'A') {
c = (c - 'A') + 10;
} else {
return false;
}
*v = c;
return true;
}
template<class UT> template<class UT>
bool hexToUint(UT *px, const char *p, size_t size) bool hexToUint(UT *px, const char *p, size_t size)
{ {
assert(0 < size && size <= sizeof(UT) * 2); assert(0 < size && size <= sizeof(UT) * 2);
UT x = 0; UT x = 0;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
UT c = static_cast<uint8_t>(p[i]); uint8_t v;
if (c - 'A' <= 'F' - 'A') { if (!hexCharToUint8(&v, p[i])) return false;
c = (c - 'A') + 10; x = x * 16 + v;
} else if (c - 'a' <= 'f' - 'a') {
c = (c - 'a') + 10;
} else if (c - '0' <= '9' - '0') {
c = c - '0';
} else {
return false;
}
x = x * 16 + c;
} }
*px = x; *px = x;
return true; return true;
@ -438,4 +446,43 @@ size_t strToArray(bool *pIsMinus, UT *x, size_t xN, const char *buf, size_t bufS
} }
} }
/*
convert src[0, n) to (n * 2) byte hex string and write it to os
return true if success else flase
*/
template<class OutputStream>
bool writeHexStr(OutputStream& os, const void *src, size_t n)
{
bool b;
const uint8_t *p = (const uint8_t *)src;
for (size_t i = 0; i < n; i++) {
char hex[2];
cybozu::itohex(hex, sizeof(hex), p[i], false);
cybozu::write(&b, os, hex, sizeof(hex));
if (!b) return false;
}
return true;
}
/*
read hex string from is and convert it to byte array
return written buffer size
*/
template<class InputStream>
inline size_t readHexStr(void *buf, size_t n, InputStream& is)
{
bool b;
uint8_t *dst = (uint8_t *)buf;
for (size_t i = 0; i < n; i++) {
uint8_t L, H;
char c[2];
if (cybozu::readSome(c, sizeof(c), is) != sizeof(c)) return i;
b = local::hexCharToUint8(&H, c[0]);
if (!b) return i;
b = local::hexCharToUint8(&L, c[1]);
if (!b) return i;
dst[i] = (H << 4) | L;
}
return n;
}
} } // mcl::fp } } // mcl::fp

@ -101,7 +101,8 @@ enum IoMode {
IoEcCompY = 256, // 1-bit y representation of elliptic curve IoEcCompY = 256, // 1-bit y representation of elliptic curve
IoSerialize = 512, // use MBS for 1-bit y IoSerialize = 512, // use MBS for 1-bit y
IoFixedSizeByteSeq = IoSerialize, // obsolete IoFixedSizeByteSeq = IoSerialize, // obsolete
IoEcProj = 1024 // projective or jacobi coordinate IoEcProj = 1024, // projective or jacobi coordinate
IoSerializeHexStr = 2048 // printable hex string
}; };
namespace fp { namespace fp {

@ -55,3 +55,40 @@ CYBOZU_TEST_AUTO(arrayToDec)
CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn); CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn);
} }
} }
CYBOZU_TEST_AUTO(writeHexStr)
{
const char *hex1tbl = "0123456789abcdef";
const char *hex2tbl = "0123456789ABCDEF";
for (size_t i = 0; i < 16; i++) {
uint8_t v = 0xff;
CYBOZU_TEST_ASSERT(mcl::fp::local::hexCharToUint8(&v, hex1tbl[i]));
CYBOZU_TEST_EQUAL(v, i);
CYBOZU_TEST_ASSERT(mcl::fp::local::hexCharToUint8(&v, hex2tbl[i]));
CYBOZU_TEST_EQUAL(v, i);
}
const struct Tbl {
const char *bin;
size_t n;
const char *hex;
} tbl[] = {
{ "", 0, "" },
{ "\x12\x34\xab", 3, "1234ab" },
{ "\xff\xfc\x00\x12", 4, "fffc0012" },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
char buf[32];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
const char *bin = tbl[i].bin;
const char *hex = tbl[i].hex;
size_t n = tbl[i].n;
CYBOZU_TEST_ASSERT(mcl::fp::writeHexStr(os, bin, n));
CYBOZU_TEST_EQUAL(os.getPos(), n * 2);
CYBOZU_TEST_EQUAL_ARRAY(buf, hex, n * 2);
cybozu::MemoryInputStream is(hex, n * 2);
size_t w = mcl::fp::readHexStr(buf, n, is);
CYBOZU_TEST_EQUAL(w, n);
CYBOZU_TEST_EQUAL_ARRAY(buf, bin, n);
}
}

Loading…
Cancel
Save