roughtime 0.1.0

A no_std-capable Roughtime secure time-sync client with pluggable crypto backends
Documentation
# Roughtime

A `no_std`-capable Rust client for the [Roughtime](https://blog.cloudflare.com/roughtime/) secure
time synchronization protocol, with pluggable crypto backends and an anti-rollback time floor.
Client-only: this crate queries and verifies Roughtime servers, but does not implement one.

## Quickstart (hosted, default features)

With default features, server hostnames are resolved end-to-end-encrypted over
[DNSCrypt](https://docs.rs/dnscrypt) — no manual IP resolution required:

```rust
use roughtime::client::{RoughtimeClientConfig, TokioClient};

#[tokio::main]
async fn main() {
    let client = TokioClient::new(RoughtimeClientConfig::default());
    let result = client.query_well_known().await.expect("query failed");
    println!("Verified time: {}s", result.time.as_unix_seconds());
}
```

See `examples/query_dnscrypt.rs` (`cargo run --example query_dnscrypt`). If you'd rather resolve
hostnames yourself (e.g. via the plain OS resolver, or your own pinned IPs), build the
`(RoughtimeServer, IpAddr)` list by hand and call `client.query(&resolved)` instead — see
`examples/query_tokio.rs`.

## Feature flags

Exactly one crypto backend must be selected:

| Feature | Backend |
|---|---|
| `rustcrypto` | Pure Rust ([`ed25519-dalek`] + [`sha2`]), `no_std`-capable |
| `aws-lc-rs` (default) | [`aws-lc-rs`] |
| `aws-lc-rs-fips` | `aws-lc-rs` built in FIPS mode |

Layered on top:

- `std` (default) — enables the networking clients and the Linux `os-clock` backend.
- `tokio-client` (default) — an async, concurrent multi-server query client.
- `blocking-client` — a synchronous `std::net::UdpSocket`-based client.
- `os-clock` — an opt-in Linux `SystemClock` implementation that can set the OS wall clock
  forward to the verified time floor.
- `dnscrypt` (default) — resolves well-known Roughtime server hostnames over
  [DNSCrypt]https://docs.rs/dnscrypt (authenticated, encrypted DNS) instead of the OS's plain,
  unauthenticated resolver, via `resolve_servers`/`resolve_servers_async` and
  `TokioClient`/`BlockingClient::query_well_known`. This closes the one remaining
  unauthenticated hop before Roughtime's own Ed25519-verified response takes over.
- `build-time-floor` — opt-in, **not** in `default`. See "The anti-rollback floor" below.

## `no_std` / kernel usage

For a kernel or bootloader that supplies its own networking and randomness:

```sh
cargo add roughtime --no-default-features --features rustcrypto
```

This gives you wire-format parsing, request building, and response verification, with no
`std`, networking, or OS-clock dependency — only a global allocator is required (see below).

```rust
use roughtime::{Nonce, build_request, verify_response};

let nonce = Nonce::new(my_hardware_rng_bytes());
let request = build_request(&nonce);
// ... send `request` over your own UDP stack, receive `response_bytes` ...
let verified = verify_response(&response_bytes, &nonce, server_pubkey_base64)?;
```

See `examples/no_std.rs` for a complete, runnable version of this
(`cargo run --example no_std --no-default-features --features rustcrypto`).

### Requirement: a global allocator

This crate always links `alloc` (for `Vec`-backed message parsing), even in `no_std` builds.
`no_std` consumers must provide a global allocator.

## The anti-rollback floor

No time reported by a Roughtime server (or the OS clock) is trusted below a floor: a machine
cannot legitimately observe a time earlier than when this crate was built.

Two supported workflows:

- **Default (reproducible builds)**: the floor is a static constant (`src/floor.rs`,
  `HARDCODED_FLOOR_SECS`) with no dependency on the build machine's clock. Bump it in source as
  a normal, reviewable commit as time passes. This is required for bit-for-bit reproducible
  builds (e.g. SEV-SNP attestation measurement matching) — enabling `build-time-floor` would
  make the build depend on wall-clock time and break reproducibility.
- **Opt-in `build-time-floor`**: the floor auto-ratchets forward to the build day, using the
  build machine's wall clock, at the cost of build reproducibility. If the build machine's
  clock is before the hardcoded floor, the build refuses to compile (this should only happen on
  a misconfigured build host). Suitable for non-attested hosted deployments that rebuild
  frequently.

## Security notes

This is a **client-only** crate — it never holds Ed25519 *private* key material, only verifies
server-supplied public keys and signatures. The one client-generated secret-like value is the
64-byte nonce, which is zeroized on drop. Raw response bytes and extracted public keys are
intentionally **not** zeroized: they are bulk public-protocol data (broadcast in the clear by
protocol design), and scrubbing them would cost real performance for no confidentiality benefit.

## MSRV

Rust 1.89.

## License

This project licensed under either the [MIT License](LICENSE-MIT) or the [Apache License, Version 2.0](LICENSE-APACHE) at your option.