diff --git a/include/mcl/fp.hpp b/include/mcl/fp.hpp index 96110a8..4f3c35b 100644 --- a/include/mcl/fp.hpp +++ b/include/mcl/fp.hpp @@ -77,8 +77,8 @@ void hkdf_extract_addZeroByte(uint8_t hmac[32], const uint8_t *salt, size_t salt void hkdf_extract(uint8_t hmac[32], const uint8_t *salt, size_t saltSize, const uint8_t *msg, size_t msgSize); void hkdf_expand(uint8_t out[64], const uint8_t prk[32], char info[6]); -// draft-07 -void expand_message_xmd(uint8_t out[256], const void *msg, size_t msgSize, const void *dst, size_t dstSize); +// draft-07 outSize = 128 or 256 +void expand_message_xmd(uint8_t out[], size_t outSize, const void *msg, size_t msgSize, const void *dst, size_t dstSize); void expand_message_xmd06(uint8_t out[256], const void *msg, size_t msgSize, const void *dst, size_t dstSize); diff --git a/include/mcl/mapto_wb19.hpp b/include/mcl/mapto_wb19.hpp index dd11e09..bb7df52 100644 --- a/include/mcl/mapto_wb19.hpp +++ b/include/mcl/mapto_wb19.hpp @@ -445,7 +445,7 @@ struct MapToG2_WB19 { if (draftVersion_ == 6) { mcl::fp::expand_message_xmd06(md, msg, msgSize, dst, dstSize); } else { - mcl::fp::expand_message_xmd(md, msg, msgSize, dst, dstSize); + mcl::fp::expand_message_xmd(md, sizeof(md), msg, msgSize, dst, dstSize); } Fp *x = out[0].getFp0(); for (size_t i = 0; i < 4; i++) { diff --git a/src/fp.cpp b/src/fp.cpp index f9307ac..343d242 100644 --- a/src/fp.cpp +++ b/src/fp.cpp @@ -194,20 +194,21 @@ void expand_message_xmd06(uint8_t out[256], const void *msg, size_t msgSize, con } } -void expand_message_xmd(uint8_t out[256], const void *msg, size_t msgSize, const void *dst, size_t dstSize) +void expand_message_xmd(uint8_t out[], size_t outSize, const void *msg, size_t msgSize, const void *dst, size_t dstSize) { - const size_t len_in_bytes = 256; + assert(outSize == 128 || outSize == 256); const size_t mdSize = 32; const size_t r_in_bytes = 64; - const size_t ell = len_in_bytes / mdSize; + const size_t n = outSize / mdSize; static const uint8_t Z_pad[r_in_bytes] = {}; assert(dstSize < 256); /* - Z_apd | msg | BE(len_in_bytes, 2) | BE(0, 1) | DST | BE(dstSize, 1) + Z_apd | msg | BE(outSize, 2) | BE(0, 1) | DST | BE(dstSize, 1) */ - static const uint8_t lenBuf[2] = { 1, 0 }; // 256 = len_in_bytes + uint8_t lenBuf[2] = { 1, 0 }; // 256 = outSize uint8_t iBuf = 0; uint8_t dstSizeBuf = uint8_t(dstSize); + cybozu::Set16bitAsBE(lenBuf, uint16_t(outSize)); cybozu::Sha256 h; h.update(Z_pad, r_in_bytes); h.update(msg, msgSize); @@ -223,7 +224,7 @@ void expand_message_xmd(uint8_t out[256], const void *msg, size_t msgSize, const h.update(dst, dstSize); h.digest(out, mdSize, &dstSizeBuf, 1); uint8_t mdXor[mdSize]; - for (size_t i = 1; i < ell; i++) { + for (size_t i = 1; i < n; i++) { h.clear(); for (size_t j = 0; j < mdSize; j++) { mdXor[j] = md[j] ^ out[mdSize * (i - 1) + j]; diff --git a/test/mapto_wb19_test.cpp b/test/mapto_wb19_test.cpp index 3041419..3dbf8f9 100644 --- a/test/mapto_wb19_test.cpp +++ b/test/mapto_wb19_test.cpp @@ -890,7 +890,17 @@ void testHashToFp2v7(const T& mapto) size_t msgSize = strlen(msg); size_t dstSize = strlen(dst); uint8_t md[256]; - mcl::fp::expand_message_xmd(md, msg, msgSize, dst, dstSize); + mcl::fp::expand_message_xmd(md, sizeof(md), msg, msgSize, dst, dstSize); + CYBOZU_TEST_EQUAL(toHexStr(md, sizeof(md)), expect); + } + { + char msg[] = "asdf"; + char dst[] = "QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_"; + char expect[] = "ecc25edef8f6b277e27a88cf5ca0cdd4c4a49e8ba273d6069a4f0c9db05d37b78e700a875f4bb5972bfce49a867172ec1cb8c5524b1853994bb8af52a8ad2338d2cf688cf788b732372c10013445cd2c16a08a462028ae8ffff3082c8e47e8437dee5a58801e03ee8320980ae7c071ab022473231789d543d56defe9ff53bdba"; + size_t msgSize = strlen(msg); + size_t dstSize = strlen(dst); + uint8_t md[128]; + mcl::fp::expand_message_xmd(md, sizeof(md), msg, msgSize, dst, dstSize); CYBOZU_TEST_EQUAL(toHexStr(md, sizeof(md)), expect); } { @@ -1054,6 +1064,12 @@ void testEth2phase0() } } +template +void testHashToG1(const T& mapto) +{ + (void)mapto; +} + CYBOZU_TEST_AUTO(test) { initPairing(mcl::BLS12_381); @@ -1076,4 +1092,5 @@ CYBOZU_TEST_AUTO(test) testHashToFp2v6(mapto); testHashToFp2v7(mapto); testEth2phase0(); + testHashToG1(mapto); }