#include "argon2_wrapper.h" extern "C" { #include } #include #include #include #include namespace scar { std::string Argon2Wrapper::generateSalt(size_t length) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(0, 255); std::vector salt_bytes(length); for (size_t i = 0; i < length; ++i) { salt_bytes[i] = static_cast(dis(gen)); } // Convert to hex string std::ostringstream oss; for (uint8_t byte : salt_bytes) { oss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); } return oss.str(); } std::string Argon2Wrapper::hashPassword(const std::string& password, const std::string& salt) { // Convert hex salt string back to bytes std::vector salt_bytes; for (size_t i = 0; i < salt.length(); i += 2) { std::string byte_string = salt.substr(i, 2); uint8_t byte = static_cast(std::stoi(byte_string, nullptr, 16)); salt_bytes.push_back(byte); } // Hash buffer std::vector hash(HASH_LENGTH); // Perform Argon2id hashing int result = argon2id_hash_raw( TIME_COST, MEMORY_COST, PARALLELISM, password.data(), password.size(), salt_bytes.data(), salt_bytes.size(), hash.data(), HASH_LENGTH ); if (result != ARGON2_OK) { throw std::runtime_error("Argon2 hashing failed: " + std::string(argon2_error_message(result))); } // Convert to hex string std::ostringstream oss; for (uint8_t byte : hash) { oss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); } return oss.str(); } bool Argon2Wrapper::verifyPassword(const std::string& password, const std::string& salt, const std::string& hash) { try { std::string computed_hash = hashPassword(password, salt); return computed_hash == hash; } catch (const std::exception&) { return false; } } } // namespace scar