mirror of
https://github.com/Quad4-Software/Reticulum-Go
synced 2026-08-29 23:48:44 -04:00
164 lines
4.1 KiB
C++
164 lines
4.1 KiB
C++
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright (c) 2024-2026 Quad4.io
|
|
|
|
#ifndef RNS_IDENTITY_HPP
|
|
#define RNS_IDENTITY_HPP
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "rns/detail/c_api.hpp"
|
|
#include "rns/error.hpp"
|
|
#include "rns/span.hpp"
|
|
#include "rns/types.hpp"
|
|
#include "rns/util.hpp"
|
|
|
|
namespace rns {
|
|
|
|
class Identity {
|
|
public:
|
|
Identity() noexcept : handle_(0) {}
|
|
|
|
Identity(Identity &&other) noexcept : handle_(other.handle_) { other.handle_ = 0; }
|
|
|
|
Identity &operator=(Identity &&other) noexcept {
|
|
if (this != &other) {
|
|
reset();
|
|
handle_ = other.handle_;
|
|
other.handle_ = 0;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
Identity(const Identity &) = delete;
|
|
Identity &operator=(const Identity &) = delete;
|
|
|
|
~Identity() { reset(); }
|
|
|
|
static Result<Identity> generate() {
|
|
std::uint64_t h = rns_identity_generate();
|
|
if (h == 0) {
|
|
return Result<Identity>(Error::Internal);
|
|
}
|
|
return Result<Identity>(Identity(h));
|
|
}
|
|
|
|
static Result<Identity> load(std::string_view path) {
|
|
char path_buf[4096];
|
|
const char *path_z = nullptr;
|
|
Error cerr = util::require_cstring(path, path_buf, sizeof(path_buf), &path_z);
|
|
if (cerr != Error::Ok) {
|
|
return Result<Identity>(cerr);
|
|
}
|
|
std::uint64_t h = rns_identity_load(path_z);
|
|
if (h == 0) {
|
|
return Result<Identity>(Error::Io);
|
|
}
|
|
return Result<Identity>(Identity(h));
|
|
}
|
|
|
|
Error save(std::string_view path) const {
|
|
char path_buf[4096];
|
|
const char *path_z = nullptr;
|
|
Error cerr = util::require_cstring(path, path_buf, sizeof(path_buf), &path_z);
|
|
if (cerr != Error::Ok) {
|
|
return cerr;
|
|
}
|
|
return map_code(rns_identity_save(handle_, path_z));
|
|
}
|
|
|
|
Result<std::string> hash() const {
|
|
char buf[64];
|
|
std::size_t written = 0;
|
|
Error err = map_code(rns_identity_hash(handle_, buf, sizeof(buf), &written));
|
|
if (err != Error::Ok) {
|
|
return Result<std::string>(err);
|
|
}
|
|
if (written > sizeof(buf)) {
|
|
written = sizeof(buf);
|
|
}
|
|
return Result<std::string>(std::string(buf, written));
|
|
}
|
|
|
|
Result<Hash> hash_bytes() const {
|
|
Hash out{};
|
|
std::size_t written = 0;
|
|
Error err = map_code(rns_identity_hash_bytes(handle_, out.data(), out.size(), &written));
|
|
if (err != Error::Ok) {
|
|
return Result<Hash>(err);
|
|
}
|
|
if (written != hash_len) {
|
|
return Result<Hash>(Error::Truncated);
|
|
}
|
|
return Result<Hash>(out);
|
|
}
|
|
|
|
Result<std::vector<std::uint8_t>> public_key() const {
|
|
std::uint8_t buf[64];
|
|
std::size_t written = 0;
|
|
Error err = map_code(rns_identity_public_key(handle_, buf, sizeof(buf), &written));
|
|
if (err != Error::Ok) {
|
|
return Result<std::vector<std::uint8_t>>(err);
|
|
}
|
|
if (written > sizeof(buf)) {
|
|
written = sizeof(buf);
|
|
}
|
|
return Result<std::vector<std::uint8_t>>(
|
|
std::vector<std::uint8_t>(buf, buf + written));
|
|
}
|
|
|
|
static Result<Identity> from_public_key(span<const std::uint8_t> pub) {
|
|
if (pub.empty()) {
|
|
return Result<Identity>(Error::InvalidArg);
|
|
}
|
|
std::uint64_t h = rns_identity_from_public_key(pub.data(), pub.size());
|
|
if (h == 0) {
|
|
return Result<Identity>(Error::InvalidArg);
|
|
}
|
|
return Result<Identity>(Identity(h));
|
|
}
|
|
|
|
Result<std::vector<std::uint8_t>> sign(span<const std::uint8_t> data) const {
|
|
std::uint8_t buf[64];
|
|
std::size_t written = 0;
|
|
Error err = map_code(rns_identity_sign(handle_, data.data(), data.size(), buf,
|
|
sizeof(buf), &written));
|
|
if (err != Error::Ok) {
|
|
return Result<std::vector<std::uint8_t>>(err);
|
|
}
|
|
if (written > sizeof(buf)) {
|
|
written = sizeof(buf);
|
|
}
|
|
return Result<std::vector<std::uint8_t>>(
|
|
std::vector<std::uint8_t>(buf, buf + written));
|
|
}
|
|
|
|
Error verify(span<const std::uint8_t> data, span<const std::uint8_t> signature) const {
|
|
return map_code(rns_identity_verify(handle_, data.data(), data.size(),
|
|
signature.data(), signature.size()));
|
|
}
|
|
|
|
std::uint64_t handle() const noexcept { return handle_; }
|
|
explicit operator bool() const noexcept { return handle_ != 0; }
|
|
|
|
void release() noexcept { handle_ = 0; }
|
|
|
|
void reset() noexcept {
|
|
if (handle_ != 0) {
|
|
rns_identity_destroy(handle_);
|
|
handle_ = 0;
|
|
}
|
|
}
|
|
|
|
private:
|
|
explicit Identity(std::uint64_t handle) noexcept : handle_(handle) {}
|
|
|
|
std::uint64_t handle_;
|
|
};
|
|
|
|
} // namespace rns
|
|
|
|
#endif
|