Initial scaffold for kestrove-core

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-15 18:30:14 +09:00
co-authored by Claude Opus 5.5
commit 462fbbc523
34 changed files with 2063 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "kv-sync"
description = "Sync engine: OPAQUE login, RFC 9421 request signing, pull/push, merge, manifest."
version.workspace = true
edition.workspace = true
license.workspace = true
publish.workspace = true
[dependencies]
kv-proto.workspace = true
uuid.workspace = true
thiserror.workspace = true
+38
View File
@@ -0,0 +1,38 @@
//! Sync engine (milestone M1, kestrove-spec/docs/03).
//!
//! Responsibilities:
//! * `Transport`: HTTPS with rustls, TLS 1.3 only, SPKI pinning (primary + backup pin).
//! * OPAQUE login via `opaque-ke` (ristretto255 / SHA-512, identity KSF because the input is already Argon2id-stretched).
//! * RFC 9421 request signing with the device key. The key lives in the platform keystore, so signing is
//! a callback into platform code ([`DeviceSigner`]).
//! * Pull, then push with `If-Match`, then three-way field merge on 412, then manifest verify and publish.
use uuid::Uuid;
#[derive(Debug, thiserror::Error)]
pub enum SyncError {
#[error("network: {0}")]
Network(String),
#[error("server rejected request: {0}")]
Server(String),
#[error("integrity alarm on vault {0}: manifest rollback or tampering")]
Integrity(Uuid),
#[error("not logged in")]
NotAuthenticated,
}
/// Implemented by each platform: Secure Enclave, StrongBox, TPM or software fallback.
pub trait DeviceSigner: Send + Sync {
fn device_id(&self) -> Uuid;
/// SEC1 uncompressed P-256 public key.
fn public_key(&self) -> Vec<u8>;
/// ECDSA P-256 / SHA-256 signature (IEEE P1363 r||s) over `message`.
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, SyncError>;
}
/// Server endpoint plus pinned SPKI SHA-256 hashes (base64).
#[derive(Debug, Clone)]
pub struct ServerConfig {
pub base_url: String,
pub spki_pins: Vec<String>,
}