#include "types.hpp" #include #include #include #include #include #include #include #include namespace llarp { bool PubKey::FromString(const std::string& str) { if (str.size() != 2 * size()) return false; oxenmq::from_hex(str.begin(), str.end(), begin()); return true; } std::string PubKey::ToString() const { return oxenmq::to_hex(begin(), end()); } bool SecretKey::LoadFromFile(const fs::path& fname) { std::ifstream f(fname.string(), std::ios::in | std::ios::binary); if (!f.is_open()) { return false; } f.seekg(0, std::ios::end); const size_t sz = f.tellg(); f.seekg(0, std::ios::beg); if (sz == size()) { // is raw buffer std::copy_n(std::istreambuf_iterator(f), sz, begin()); return true; } std::array tmp; llarp_buffer_t buf(tmp); if (sz > sizeof(tmp)) { return false; } f.read(reinterpret_cast(tmp.data()), sz); return BDecode(&buf); } bool SecretKey::Recalculate() { PrivateKey key; PubKey pubkey; if (!toPrivate(key) || !key.toPublic(pubkey)) return false; std::memcpy(data() + 32, pubkey.data(), 32); return true; } bool SecretKey::toPrivate(PrivateKey& key) const { // Ed25519 calculates a 512-bit hash from the seed; the first half (clamped) // is the private key; the second half is the hash that gets used in // signing. unsigned char h[crypto_hash_sha512_BYTES]; if (crypto_hash_sha512(h, data(), 32) < 0) return false; h[0] &= 248; h[31] &= 63; h[31] |= 64; std::memcpy(key.data(), h, 64); return true; } bool PrivateKey::toPublic(PubKey& pubkey) const { return crypto_scalarmult_ed25519_base_noclamp(pubkey.data(), data()) != -1; } bool SecretKey::SaveToFile(const fs::path& fname) const { std::array tmp; llarp_buffer_t buf(tmp); if (!BEncode(&buf)) { return false; } auto optional_f = llarp::util::OpenFileStream(fname, std::ios::binary); if (!optional_f) return false; auto& f = *optional_f; if (!f.is_open()) return false; f.write((char*)buf.base, buf.cur - buf.base); return f.good(); } bool IdentitySecret::LoadFromFile(const fs::path& fname) { auto optional = util::OpenFileStream(fname, std::ios::binary | std::ios::in); if (!optional) return false; auto& f = *optional; f.seekg(0, std::ios::end); const size_t sz = f.tellg(); f.seekg(0, std::ios::beg); if (sz != 32) { llarp::LogError("service node seed size invalid: ", sz, " != 32"); return false; } std::copy_n(std::istreambuf_iterator(f), sz, begin()); return true; } byte_t* Signature::Lo() { return data(); } const byte_t* Signature::Lo() const { return data(); } byte_t* Signature::Hi() { return data() + 32; } const byte_t* Signature::Hi() const { return data() + 32; } } // namespace llarp