bytes Secp256k1PP::eciesKDF(Secret const& _z, bytes _s1, unsigned kdByteLen) { auto reps = ((kdByteLen + 7) * 8) / (CryptoPP::SHA256::BLOCKSIZE * 8); // SEC/ISO/Shoup specify counter size SHOULD be equivalent // to size of hash output, however, it also notes that // the 4 bytes is okay. NIST specifies 4 bytes. bytes ctr({0, 0, 0, 1}); bytes k; CryptoPP::SHA256 ctx; for (unsigned i = 0; i <= reps; i++) { ctx.Update(ctr.data(), ctr.size()); ctx.Update(_z.data(), Secret::size); ctx.Update(_s1.data(), _s1.size()); // append hash to k bytes digest(32); ctx.Final(digest.data()); ctx.Restart(); k.reserve(k.size() + h256::size); move(digest.begin(), digest.end(), back_inserter(k)); if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0]) continue; } k.resize(kdByteLen); return k; }
TEST(AccountTest, TestAccountAuthorized) { if (settings::instance().cassandraSeeds.size() == 0) return; const char* const USERNAME = "******"; const char* const PASSWORD = "******"; user_account::create(USERNAME, PASSWORD, 1); unsigned char hashResult[CryptoPP::SHA256::DIGESTSIZE]; CryptoPP::SHA256 sha; sha.CalculateDigest(&hashResult[0], (unsigned char*)USERNAME, strlen(USERNAME)); std::string nameHash = util::hex_encode(hashResult, CryptoPP::SHA256::DIGESTSIZE); sha.Restart(); sha.CalculateDigest(&hashResult[0], (unsigned char*)PASSWORD, strlen(PASSWORD)); std::string pwHash = util::hex_encode(hashResult, CryptoPP::SHA256::DIGESTSIZE); std::mutex m; std::condition_variable cv; auto challengeBytes = util::random_bytes(1024); auto pwHashAndChallenge = pwHash + challengeBytes; sha.Restart(); sha.CalculateDigest(&hashResult[0], (unsigned char*)pwHashAndChallenge.c_str(), pwHashAndChallenge.length()); auto challengeResponse = util::hex_encode(hashResult, CryptoPP::SHA256::DIGESTSIZE); bool uauthd = false; bool returned = false; user_account::is_authorized(nameHash, challengeBytes, challengeResponse, [&] (bool authd) { std::lock_guard<std::mutex> lk(m); returned = true; uauthd = authd; cv.notify_one(); }); std::unique_lock<std::mutex> lk(m); cv.wait(lk, [&] {return returned == true;}); ASSERT_EQ(true, uauthd); }