codec: update vendored VaptVupt codec 2.65.0 -> 2.65.3
From vaptvupt-codec tag v2.65.3. Output is byte-identical to 2.65.0 (same ratio, wire format v1.6 unchanged) but extreme-mode encode is ~1.6-2x faster (Sprint 132 optimal-parser speedup) and the extreme prepass window allocation is capped at wlog=20 = 8 MiB virtual instead of up to 128 MiB (Sprint 133 memory hygiene). Our AVX2 offset-read decoder guard is now UPSTREAM (dropped from the local patch set); the ANS safe-zone 2*SAFEZONE_MAX_RUN reserve is re-applied on top (still not upstream). make check 16/16, KAT 16/16, cross- version roundtrip with 5.1.0 archives verified.
This commit is contained in:
parent
df534503ec
commit
59f9ebc59e
24 changed files with 94 additions and 17 deletions
230
vendor/vuptsdk/include/zuptsdk.hpp
vendored
Normal file
230
vendor/vuptsdk/include/zuptsdk.hpp
vendored
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
// libzuptsdk C++17 header — RAII wrappers, exception-based error handling
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#ifndef ZUPTSDK_HPP
|
||||
#define ZUPTSDK_HPP
|
||||
|
||||
#include "zuptsdk.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace zuptsdk {
|
||||
|
||||
class Error : public std::runtime_error {
|
||||
int code_;
|
||||
public:
|
||||
Error(int code, const std::string& msg) : std::runtime_error(msg), code_(code) {}
|
||||
int code() const noexcept { return code_; }
|
||||
};
|
||||
|
||||
inline void check(int rc) {
|
||||
if (rc != ZUPTSDK_OK) {
|
||||
const char* detail = zuptsdk_last_error_detail();
|
||||
throw Error(rc, detail && *detail ? detail : zuptsdk_strerror(rc));
|
||||
}
|
||||
}
|
||||
|
||||
// RAII wrapper for SDK-allocated buffers (must be freed via zuptsdk_free)
|
||||
class Buffer {
|
||||
uint8_t* data_;
|
||||
std::size_t size_;
|
||||
public:
|
||||
Buffer() : data_(nullptr), size_(0) {}
|
||||
Buffer(uint8_t* data, std::size_t size) : data_(data), size_(size) {}
|
||||
~Buffer() { if (data_) zuptsdk_free(data_); }
|
||||
Buffer(const Buffer&) = delete;
|
||||
Buffer& operator=(const Buffer&) = delete;
|
||||
Buffer(Buffer&& o) noexcept : data_(o.data_), size_(o.size_) { o.data_ = nullptr; o.size_ = 0; }
|
||||
Buffer& operator=(Buffer&& o) noexcept {
|
||||
if (data_) zuptsdk_free(data_);
|
||||
data_ = o.data_; size_ = o.size_; o.data_ = nullptr; o.size_ = 0;
|
||||
return *this;
|
||||
}
|
||||
const uint8_t* data() const noexcept { return data_; }
|
||||
uint8_t* data() noexcept { return data_; }
|
||||
std::size_t size() const noexcept { return size_; }
|
||||
std::vector<uint8_t> to_vector() const { return {data_, data_ + size_}; }
|
||||
uint8_t** out_ptr() noexcept { return &data_; }
|
||||
std::size_t* out_size() noexcept { return &size_; }
|
||||
};
|
||||
|
||||
class Context {
|
||||
zuptsdk_ctx_t* ctx_;
|
||||
public:
|
||||
Context() : ctx_(nullptr) { check(zuptsdk_ctx_create(&ctx_)); }
|
||||
~Context() { if (ctx_) zuptsdk_ctx_destroy(ctx_); }
|
||||
Context(const Context&) = delete;
|
||||
Context& operator=(const Context&) = delete;
|
||||
zuptsdk_ctx_t* raw() const noexcept { return ctx_; }
|
||||
};
|
||||
|
||||
class Pubkey {
|
||||
zuptsdk_pubkey_t* pk_;
|
||||
public:
|
||||
Pubkey() : pk_(nullptr) {}
|
||||
explicit Pubkey(zuptsdk_pubkey_t* pk) : pk_(pk) {}
|
||||
~Pubkey() { if (pk_) zuptsdk_pubkey_destroy(pk_); }
|
||||
Pubkey(const Pubkey&) = delete;
|
||||
Pubkey& operator=(const Pubkey&) = delete;
|
||||
Pubkey(Pubkey&& o) noexcept : pk_(o.pk_) { o.pk_ = nullptr; }
|
||||
static Pubkey load(const std::string& path) {
|
||||
zuptsdk_pubkey_t* pk = nullptr;
|
||||
check(zuptsdk_pubkey_load(path.c_str(), &pk));
|
||||
return Pubkey(pk);
|
||||
}
|
||||
zuptsdk_pubkey_t* raw() const noexcept { return pk_; }
|
||||
std::array<uint8_t, 32> fingerprint() const {
|
||||
std::array<uint8_t, 32> fp{};
|
||||
check(zuptsdk_pubkey_fingerprint(pk_, fp.data()));
|
||||
return fp;
|
||||
}
|
||||
};
|
||||
|
||||
class Privkey {
|
||||
zuptsdk_privkey_t* sk_;
|
||||
public:
|
||||
Privkey() : sk_(nullptr) {}
|
||||
explicit Privkey(zuptsdk_privkey_t* sk) : sk_(sk) {}
|
||||
~Privkey() { if (sk_) zuptsdk_privkey_destroy(sk_); }
|
||||
Privkey(const Privkey&) = delete;
|
||||
Privkey& operator=(const Privkey&) = delete;
|
||||
Privkey(Privkey&& o) noexcept : sk_(o.sk_) { o.sk_ = nullptr; }
|
||||
static Privkey load(const std::string& path) {
|
||||
zuptsdk_privkey_t* sk = nullptr;
|
||||
check(zuptsdk_privkey_load(path.c_str(), &sk));
|
||||
return Privkey(sk);
|
||||
}
|
||||
zuptsdk_privkey_t* raw() const noexcept { return sk_; }
|
||||
};
|
||||
|
||||
class Keypair {
|
||||
zuptsdk_keypair_t* kp_;
|
||||
public:
|
||||
explicit Keypair(Context& ctx) : kp_(nullptr) {
|
||||
check(zuptsdk_keypair_generate(ctx.raw(), &kp_));
|
||||
}
|
||||
~Keypair() { if (kp_) zuptsdk_keypair_destroy(kp_); }
|
||||
Keypair(const Keypair&) = delete;
|
||||
Keypair& operator=(const Keypair&) = delete;
|
||||
void save_public(const std::string& path) const {
|
||||
check(zuptsdk_keypair_save_public(kp_, path.c_str()));
|
||||
}
|
||||
void save_private(const std::string& path) const {
|
||||
check(zuptsdk_keypair_save_private(kp_, path.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
// Result type for encryption operations
|
||||
struct EncryptResult {
|
||||
Buffer header;
|
||||
Buffer ciphertext;
|
||||
};
|
||||
|
||||
inline EncryptResult encrypt_pq(Context& ctx, const Pubkey& pk,
|
||||
const uint8_t* pt, std::size_t pt_sz,
|
||||
const uint8_t* aad = nullptr, std::size_t aad_sz = 0) {
|
||||
EncryptResult r;
|
||||
check(zuptsdk_encrypt_pq(ctx.raw(), pk.raw(), pt, pt_sz, aad, aad_sz,
|
||||
r.header.out_ptr(), r.header.out_size(),
|
||||
r.ciphertext.out_ptr(), r.ciphertext.out_size()));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline EncryptResult encrypt_pq_v2(Context& ctx, const Pubkey& pk,
|
||||
int aead_id, bool forward_secret,
|
||||
const uint8_t* pt, std::size_t pt_sz,
|
||||
const uint8_t* aad = nullptr, std::size_t aad_sz = 0) {
|
||||
EncryptResult r;
|
||||
check(zuptsdk_encrypt_pq_v2(ctx.raw(), pk.raw(), aead_id, forward_secret ? 1 : 0,
|
||||
pt, pt_sz, aad, aad_sz,
|
||||
r.header.out_ptr(), r.header.out_size(),
|
||||
r.ciphertext.out_ptr(), r.ciphertext.out_size()));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline Buffer decrypt_pq(Context& ctx, const Privkey& sk,
|
||||
const uint8_t* hdr, std::size_t hdr_sz,
|
||||
const uint8_t* ct, std::size_t ct_sz,
|
||||
const uint8_t* aad = nullptr, std::size_t aad_sz = 0) {
|
||||
Buffer r;
|
||||
check(zuptsdk_decrypt_pq(ctx.raw(), sk.raw(), hdr, hdr_sz, ct, ct_sz, aad, aad_sz,
|
||||
r.out_ptr(), r.out_size()));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline Buffer decrypt_pq_v2(Context& ctx, const Privkey& sk,
|
||||
const uint8_t* hdr, std::size_t hdr_sz,
|
||||
const uint8_t* ct, std::size_t ct_sz,
|
||||
const uint8_t* aad = nullptr, std::size_t aad_sz = 0) {
|
||||
Buffer r;
|
||||
check(zuptsdk_decrypt_pq_v2(ctx.raw(), sk.raw(), hdr, hdr_sz, ct, ct_sz, aad, aad_sz,
|
||||
r.out_ptr(), r.out_size()));
|
||||
return r;
|
||||
}
|
||||
|
||||
// Streaming
|
||||
class StreamEncrypter {
|
||||
zuptsdk_stream_state_t* st_;
|
||||
Buffer header_;
|
||||
public:
|
||||
StreamEncrypter(Context& ctx, const Pubkey& pk,
|
||||
const uint8_t* aad = nullptr, std::size_t aad_sz = 0) : st_(nullptr) {
|
||||
check(zuptsdk_stream_pq_init_encrypt(ctx.raw(), pk.raw(), aad, aad_sz,
|
||||
header_.out_ptr(), header_.out_size(), &st_));
|
||||
}
|
||||
~StreamEncrypter() { if (st_) zuptsdk_stream_state_destroy(st_); }
|
||||
StreamEncrypter(const StreamEncrypter&) = delete;
|
||||
StreamEncrypter& operator=(const StreamEncrypter&) = delete;
|
||||
const Buffer& header() const noexcept { return header_; }
|
||||
|
||||
std::vector<uint8_t> encrypt_chunk(const uint8_t* pt, std::size_t pt_sz, bool final_chunk) {
|
||||
std::vector<uint8_t> out(pt_sz + 21);
|
||||
std::size_t out_sz = 0;
|
||||
check(zuptsdk_stream_chunk_encrypt(st_,
|
||||
final_chunk ? ZUPTSDK_CHUNK_FINAL : ZUPTSDK_CHUNK_MESSAGE,
|
||||
pt, pt_sz, nullptr, 0, out.data(), out.size(), &out_sz));
|
||||
out.resize(out_sz);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
class StreamDecrypter {
|
||||
zuptsdk_stream_state_t* st_;
|
||||
bool finished_ = false;
|
||||
public:
|
||||
StreamDecrypter(Context& ctx, const Privkey& sk,
|
||||
const uint8_t* hdr, std::size_t hdr_sz,
|
||||
const uint8_t* aad = nullptr, std::size_t aad_sz = 0) : st_(nullptr) {
|
||||
check(zuptsdk_stream_pq_init_decrypt(ctx.raw(), sk.raw(), hdr, hdr_sz,
|
||||
aad, aad_sz, &st_));
|
||||
}
|
||||
~StreamDecrypter() { if (st_) zuptsdk_stream_state_destroy(st_); }
|
||||
StreamDecrypter(const StreamDecrypter&) = delete;
|
||||
StreamDecrypter& operator=(const StreamDecrypter&) = delete;
|
||||
|
||||
struct ChunkResult {
|
||||
std::vector<uint8_t> data;
|
||||
bool final_chunk;
|
||||
};
|
||||
ChunkResult decrypt_chunk(const uint8_t* in, std::size_t in_sz) {
|
||||
std::vector<uint8_t> out(in_sz); // upper bound
|
||||
std::size_t out_sz = 0;
|
||||
zuptsdk_chunk_tag_t tag;
|
||||
check(zuptsdk_stream_chunk_decrypt(st_, in, in_sz, nullptr, 0,
|
||||
out.data(), out.size(), &out_sz, &tag));
|
||||
out.resize(out_sz);
|
||||
bool fin = (tag == ZUPTSDK_CHUNK_FINAL);
|
||||
if (fin) finished_ = true;
|
||||
return { std::move(out), fin };
|
||||
}
|
||||
bool finished() const noexcept { return finished_; }
|
||||
};
|
||||
|
||||
inline std::string version() { return zuptsdk_version_string(); }
|
||||
|
||||
} // namespace zuptsdk
|
||||
|
||||
#endif // ZUPTSDK_HPP
|
||||
Loading…
Reference in a new issue