Commit Graph

10143 Commits

Author SHA1 Message Date
Georgio Nicolas eae2b01f71 enable encryption - kkt 2025-12-22 10:12:40 +01:00
durch bd85a53079 Cleanup and fmt 2025-12-05 13:31:19 +01:00
durch 8fe791c4b4 Implement two-hop WireGuard tunnel for gateway-probe localnet mode
Add UDP forwarder pattern (copied from VPN client) to enable proper two-hop
tunneling where traffic flows: Client → Entry Gateway → Exit Gateway → Internet.

Key changes:
- Add udp_forwarder.go for tunnel-in-tunnel traffic forwarding
- Add wgPingTwoHop() Go function and Rust FFI bindings
- Configure NAT/iptables in localnet for gateway routing
- Remove unnecessary PSK from gateway LP registration (was breaking handshakes)
- Document known container networking instability issue (nym-vbdo)

The probe now correctly uses the entry tunnel to reach the exit gateway's
WireGuard endpoint, rather than trying to connect directly to unreachable
container-internal IPs.
2025-12-05 01:38:04 +01:00
durch bf8e061310 Add mock ecash support and fix PSK injection timing in LP sessions
Key changes:
- Add outer_aead_key_for_sending() to gate outer encryption on PSQ completion
  (fixes bug where initiator encrypted msg 1 before responder could decrypt)
- Add handshake_and_register_with_credential() to NestedLpSession for mock ecash
- Update PSQState::InitiatorWaiting to store PSK instead of ciphertext
- Add probe-localnet.sh script for two-hop localnet testing
- Update gateway handler with connection lifecycle statistics

The PSK timing fix ensures the first Noise message is sent in cleartext
because the responder hasn't derived the PSK yet from the PSQ payload.
2025-12-04 18:13:05 +01:00
durch 2a2f511333 Update gateway-probe README with localnet mode docs
- Add Test Modes section explaining mixnet/single-hop/two-hop/lp-only
- Add Localnet Mode (run-local) usage examples
- Add Split Network Configuration for docker setups
- Add CLI Reference with all new flags
- Add Output section with JSON example

Closes: nym-mj2q
2025-12-01 13:14:55 +01:00
durch f559a29cd8 Minor cleanup: remove unused param and fix docs
- Remove unused _storage parameter from wg_probe_lp (nym-r3w9)
- Fix common/mod.rs docs to match implemented features (nym-1nsv)

Closes: nym-r3w9, nym-1nsv, nym-inol (epic)
2025-12-01 13:10:57 +01:00
durch 11df6e7cd8 Fix P2 issues: validation, division guards, and API cleanup
- Add early validation for --mode two-hop without exit gateway (nym-c0hl)
  Clear error message instead of silent failure deep in probe

- Add safe_ratio() helper for division by zero protection (nym-ktvz)
  Returns 0.0 when sent_hosts/sent_ips is 0 instead of NaN/Inf

- Refactor run_tunnel_tests to take &mut WgProbeResults (nym-4v1p)
  Eliminates 40+ lines of field-by-field copying at call sites

Closes: nym-c0hl, nym-ktvz, nym-4v1p
2025-12-01 13:05:23 +01:00
durch 77858e9e78 Migrate do_probe_test to accept TestMode parameter
- Replace only_lp_registration and test_lp_wg boolean params with TestMode
- Keep only_wireguard separate (controls ping behavior in Mixnet mode)
- Use TestMode helper methods for cleaner control flow:
  - needs_mixnet() && !only_wireguard → run ping tests
  - tests_wireguard() → run WG tests
  - uses_lp() → use LP path instead of authenticator
- Convert legacy flags to TestMode at call sites for backward compatibility

Closes: nym-dd70
2025-12-01 12:28:52 +01:00
durch e6012c9ad4 Add unit tests for TestMode enum
- from_flags() tests for all flag combinations
- Helper method tests (needs_mixnet, uses_lp, tests_wireguard, needs_exit_gateway)
- Display and FromStr tests with alternate formats
- Roundtrip test ensuring Display/FromStr consistency

Closes: nym-39mt
2025-12-01 12:24:05 +01:00
durch c7e92c860b Restructure gateway probe with mode and common modules
- Extract TestMode enum to mode/mod.rs for cleaner organization
- Add common/wireguard.rs with shared WireGuard tunnel testing
- Deduplicate netstack code from wg_probe() and wg_probe_lp()
- Net reduction of 174 lines in lib.rs
2025-12-01 11:02:46 +01:00
durch 1b2f482ff1 Fix --only-wireguard flag ignored in localnet mode
The mode_to_flags() function was discarding the original only_wireguard
flag. Now we preserve args.only_wireguard since it's orthogonal to the
test mode (it means "skip ping tests" in mixnet mode).
2025-12-01 10:30:11 +01:00
durch 59440f9d8b Add localnet mode and TestMode enum to gateway probe
- Add CLI args for localnet testing (no HTTP API needed):
  --entry-gateway-identity, --exit-gateway-identity
  --entry-lp-address, --exit-lp-address, --lp-port

- Add TestMode enum (Mixnet, SingleHop, TwoHop, LpOnly) with
  --mode CLI arg and auto-inference from legacy flags

- Add TestedNodeDetails::from_cli() for localnet mode

- Add Probe::new_localnet() constructor

- Fix LpRegistrationClient API calls for packet-per-connection model
2025-12-01 10:18:43 +01:00
durch b16051ab46 Pedantic fixes 2025-12-01 10:14:02 +01:00
durch ca31c42794 Add gateway subsession support with collision check and fast cleanup
- Store LpStateMachine in session_states (not LpSession) for subsession handling
- Add LpStateMachine::from_subsession() factory for promoted sessions
- Rewrite handle_transport_packet() to use state machine for all messages
- Add handle_subsession_complete() for session promotion flow
- Add collision check for new_receiver_index before insert (nym-90rw)
- Add demoted_session_ttl_secs config (default 60s) for ReadOnlyTransport
  sessions to be cleaned up quickly after subsession promotion (nym-atza)
- Track demoted session cleanup separately with lp_states_cleanup_demoted_removed
2025-11-30 22:51:04 +01:00
durch 0146bbfbb9 Add subsession support with KKpsk0 rekeying and race resolution
- Add subsession message types: SubsessionKK1, KK2, Ready, Request, Abort
- Implement SubsessionHandshake for Noise KKpsk0 tunneled through parent
- Add subsession PSK derivation from parent's PQ shared secret
- Handle simultaneous initiation with X25519 key comparison tie-breaker
- Add stale SubsessionAbort handler for message interleaving scenarios
- Add test for simultaneous subsession initiation race condition

Subsessions provide forward secrecy via periodic rekeying while
inheriting PQ protection from the parent session's ML-KEM shared secret.
2025-11-30 21:23:18 +01:00
durch b05113e522 Implement unified packet format with outer header first
Restructure LP packet format so cleartext fields (receiver_idx, counter)
are always first, enabling trivial header parsing for routing before
session lookup. Protocol version and reserved fields are now encrypted
in the inner payload for encrypted packets.

Wire format change:
- Before: proto(1B) + reserved(3B) + receiver_idx(4B) + counter(8B)
- After:  receiver_idx(4B) + counter(8B) | proto(1B) + reserved(3B) + ...

Key changes:
- Add OuterHeader struct (12 bytes) for routing/replay protection
- Update serialize_lp_packet/parse_lp_packet for unified format
- parse_lp_header_only now returns OuterHeader
- Gateway handler uses OuterHeader for session lookup
- Update DESIGN.md with new wire format diagrams

Security improvement: Only receiver_idx and counter visible after PSK
establishment (was also exposing protocol version and reserved).
2025-11-28 12:09:49 +01:00
durch 09447f5a1c Add response validation, zeroize, and replay protection
- Validate Ack response in NestedLpSession and LP client final handshake
- Replace manual Drop with derive(Zeroize, ZeroizeOnDrop) for OuterAeadKey
- Add replay counter check before AEAD decryption to prevent DoS

[nym-qm2q, nym-z82d, nym-9ik3, nym-62fs]
2025-11-27 13:56:55 +01:00
durch 9473f3418c Refactor LP registration client for packet-per-connection model [nym-8wuj, nym-k0tb]
Refactor LpRegistrationClient from persistent TCP connection model to
packet-per-connection model, matching gateway's stateless connection pattern.
Each LP packet exchange opens a new TCP connection, sends one packet, receives
one response, then closes. State persists in LpStateMachine locally.

Key changes:
- Add connect_send_receive() helper for packet-per-connection exchanges
- Rewrite perform_handshake() with clean loop-based approach
- Remove LpTransport (packet-per-connection doesn't need persistent transport)
- Combine send_registration_request + receive_registration_response into register()
- Remove connect() method - handshake now handles connection internally

NestedLpSession refactoring:
- Add send_and_receive_via_forward() helper (consolidates 9 outer_key extractions)
- Rewrite perform_handshake() from 6-level nesting to clean loop
- Use BOOTSTRAP_RECEIVER_IDX constant instead of hardcoded 0
- Fix stale doc comment referencing removed connect() method

Result: 438 fewer lines, cleaner control flow, DRY outer_key handling.
2025-11-27 13:26:31 +01:00
durch 53c1689011 Add outer AEAD encryption + Ack message type for LP protocol
- Add OuterAeadKey derived from PSK via Blake3 KDF for packet encryption
- Add LpMessage::Ack (0x0008) for ClientHello acknowledgment
- Gateway sends Ack after processing ClientHello (packet-per-connection)
- Update codec with AEAD encrypt/decrypt using ChaCha20-Poly1305
- Header remains cleartext (AAD), payload encrypted after PSK derivation
- Add parse_lp_header_only() for routing before session lookup
- Update session to expose outer_aead_key() getter
- Various LP protocol improvements and test coverage

Closes: nym-f4v1, nym-n9dr
2025-11-27 12:39:48 +01:00
durch d9e9b73c1d Update README 2025-11-26 15:58:04 +01:00
durch 9f3a96116d Add TTL-based state cleanup for stale sessions [nym-a241]
- Create TimestampedState<T> wrapper with created_at and last_activity tracking
- Add TTL config fields to LpConfig:
  * handshake_ttl_secs (default: 90s)
  * session_ttl_secs (default: 24h)
  * state_cleanup_interval_secs (default: 5min)
- Update LpHandlerState maps to use TimestampedState wrappers
- Update all handler.rs access points to wrap/unwrap states
- Implement background cleanup task in LpListener:
  * Spawns on startup, stops on shutdown
  * Removes handshakes older than handshake_ttl
  * Removes sessions with no activity > session_ttl
  * Tracks metrics: lp_states_cleanup_handshake_removed, lp_states_cleanup_session_removed
- Touch last_activity on every packet in handle_transport_packet()
- All 13 tests passing

Prevents memory leaks from abandoned handshakes and expired sessions
in long-running gateways. Configurable TTLs for different use cases.
2025-11-25 11:44:53 +01:00
durch 496f22ff67 Refactor entry gateway for single-packet forwarding [nym-31hl]
- Extend handle_transport_packet() to conditionally deserialize both
  LpRegistrationRequest and ForwardPacketData messages
- Add handle_registration_request() helper for registration flow
- Add handle_forwarding_request() helper for telescoping flow
- Delete dead handle_forwarding_loop() method (persistent connection model)
- Clean up unused imports and dead code warnings
- All 13 tests passing

Entry gateway now fully supports single-packet-per-connection architecture
for both direct client registration and packet forwarding to exit gateways.
Each ForwardPacket arrives on a new connection, gets processed, response sent,
and connection closes - consistent with exit gateway behavior from nym-21th.
2025-11-25 11:28:38 +01:00
durch e8a3d5720c Fix ClientHello handling + add BOOTSTRAP_SESSION_ID constant [nym-v9un]
Gateway responder's StartHandshake doesn't return a packet - it just transitions
to KKTExchange state and waits for client's KKT request. Fixed handle_client_hello()
to not expect a response packet.

## Changes

### Add BOOTSTRAP_SESSION_ID constant
- `common/nym-lp/src/packet.rs`: Add `pub const BOOTSTRAP_SESSION_ID: u32 = 0`
- Document that session_id=0 is only used for ClientHello bootstrap
- Export from lib.rs for public use

### Fix handle_client_hello() logic
- `gateway/src/node/lp_listener/handler.rs:201-225`:  - Remove expectation of SendPacket action from StartHandshake
  - Responder transitions to KKTExchange without sending
  - Store state machine and close connection
  - Client sends KKT request on next connection with computed session_id

### Use constant throughout codebase
- `gateway/src/node/lp_listener/handler.rs:115`: Use BOOTSTRAP_SESSION_ID in routing
- `nym-registration-client/src/lp_client/client.rs:259`: Use constant instead of literal 0

## Protocol Flow (Fixed)
```
Connection 1: Client sends ClientHello (session_id=0)
              → Gateway stores state, closes (no response)
Connection 2: Client sends KKT request (session_id=X)
              → Gateway finds state, processes, responds
Connection 3+: Handshake continues until complete...
```

## Testing
- All 13 unit tests pass
- Real test: docker/localnet + nym-gateway-probe (next step)

Fixes: nym-v9un
Unblocks: nym-21th
2025-11-25 11:08:24 +01:00
durch 953cbb52d1 Refactor exit gateway to single-packet processing [nym-21th]
Major architectural change: decouple handshake state from TCP connection
to enable packet-per-connection forwarding and future UDP support.

## Changes

### Gateway Handler (handler.rs)
- Refactor `handle()` from persistent-connection loop to single-packet processing
- Add `handle_client_hello()`: Process ClientHello (session_id=0), create LpStateMachine, store in handshake_states map
- Add `handle_handshake_packet()`: Process handshake packets incrementally, transition to session_states when complete
- Add `handle_transport_packet()`: Handle registration/forward requests via established sessions

### State Management
- Use handshake_states (DashMap<u32, LpStateMachine>) for in-progress handshakes
- Use session_states (DashMap<u32, LpSession>) for established sessions
- Session ID computed deterministically from X25519 keys immediately after ClientHello
- State persists across connection closes

### Packet Flow
```
packet arrives → parse session_id from header
  if session_id == 0: handle_client_hello (create state)
  elif in handshake_states: handle_handshake_packet (advance state)
  elif in session_states: handle_transport_packet (decrypt, process)
  else: error (unknown session)
send response → close connection
```

## Testing
- All 13 existing unit tests pass
- Tests verify low-level packet I/O, timestamp validation, etc.
- Integration testing via nym-gateway-probe (next step)

## Backwards Compatibility
- Old handshake.rs methods kept but unused (may remove later)
- Metrics unchanged
- Protocol wire format unchanged

## Next Steps
- Test with docker/localnet topology
- Verify telescoping works (nym-gateway-probe)
- Apply same architecture to entry gateway (nym-31hl)

Fixes: nym-21th
Blocks: nym-31hl
2025-11-25 10:56:05 +01:00
durch c1258f761f Add session state storage to LpHandlerState [nym-qtji]
Add in-memory state storage for handshake and session state to enable
stateless transport layer. This is the foundation for packet-per-connection
forwarding and future UDP support.

Changes:
- Add handshake_states: Arc<DashMap<[u8; 32], LpStateMachine>>
  Keyed by client Ed25519 public key for in-progress handshakes
- Add session_states: Arc<DashMap<u32, LpSession>>
  Keyed by session_id for established sessions
- Initialize both maps in production code (node/mod.rs)
- Initialize both maps in test code (handler.rs)

No logic changes yet - pure infrastructure addition.
All existing tests pass.

Fixes: nym-qtji
2025-11-25 10:41:35 +01:00
durch fca9f6ab13 Telescoping, first pass 2025-11-25 10:33:28 +01:00
durch 4317ad3031 Various fixes 2025-11-24 12:13:17 +01:00
Drazen Urch ecdeeb096e KKT + PSQ (#6203)
* Add nymkkt with KKT convenience wrappers for nym-lp integration

Integrates nymkkt module from georgio/noise-psq branch to enable
post-quantum key distribution for nym-lp.

Changes:
- Add common/nymkkt from georgio/noise-psq (KKT protocol implementation)
- Add convenience wrapper layer (kkt.rs) with simplified API:
  - request_kem_key() - Client requests gateway's KEM key
  - validate_kem_response() - Client validates signed response
  - handle_kem_request() - Gateway handles requests
- Add nymkkt to workspace members in root Cargo.toml
- Export kkt module in lib.rs

The KKT (Key Encapsulation Mechanism Transport) protocol enables efficient
distribution of post-quantum KEM public keys. Instead of storing large PQ
keys in the directory (1KB-500KB), we store 32-byte hashes and fetch actual
keys on-demand via this authenticated protocol.

Tests: All 5 unit tests passing (authenticated, anonymous, signature
verification, hash validation)

* feat(lp): add Ed25519 authentication to PSQ protocol

Replace basic PSQ v0 API with authenticated v1 API that includes
cryptographic authentication via Ed25519 signatures.

Changes:
- PSQ initiator now signs encapsulated keys with Ed25519 private key
- PSQ responder verifies Ed25519 signatures before deriving PSK
- Prevents MITM attacks through mutual authentication
- Fixed test helpers to use role-based Ed25519 keypair assignment
  (initiator uses [1u8;32], responder uses [2u8;32])

Security: This adds a critical authentication layer to the post-quantum
PSK derivation protocol, ensuring both parties can verify each other's
identity during the handshake.

Tests: All 77 tests passing (was 11 failures, now 0)

* feat(lp): integrate PSQ post-quantum PSK derivation

Complete integration of Post-Quantum Secure (PSQ) protocol for PSK
derivation in the Lewes Protocol, replacing simple Blake3 derivation
with cryptographically secure DHKEM-based PSK establishment.

This commit encompasses three completed tasks:

- Add KKTRequest/KKTResponse message types to LpMessage enum
- Update codec to handle KKT message serialization/deserialization
- Add kkt_orchestrator.rs with high-level KKT API wrappers
- Enable key exchange orchestration for PSQ protocol

- Add set_psk() method to NoiseProtocol for dynamic PSK injection
- Integrate PSQ derivation into LpSession handshake flow
- PSQ payload embedded in first Noise message (ClientHello)
- Derive PSK using libcrux-psq before Noise handshake completion
- Add helper functions for X25519 to KEM conversions

- Add comprehensive PSQ integration tests in session_integration/
- Test PSQ handshake end-to-end flow
- Validate PSK derivation correctness between initiator/responder
- Test PSQ + Noise combined protocol operation

Dependencies:
- libcrux-psq: Post-quantum PSK protocol implementation
- libcrux-kem: Key Encapsulation Mechanism primitives
- nym-kkt: KKT key exchange protocol wrappers
- rand 0.9: Required for KKT compatibility

Security: This adds Harvest-Now-Decrypt-Later (HNDL) resistance by
combining classical ECDH with post-quantum KEM for PSK derivation.
Even if X25519 is broken by quantum computers, the PSK remains secure.

Tests: All 77 tests passing

* feat(lp): add PSQ error handling documentation and tests (nym-bbi)

Formalize the "always abort" error handling strategy for PSQ failures.
PSQ errors indicate attacks, misconfigurations, or protocol violations
that should not be silently ignored or worked around.

Changes:
- Add comprehensive error handling documentation to psk.rs module
- Add diagnostic logging with error categorization:
  * CredError → warn about potential attack
  * TimestampElapsed → warn about potential replay
  * Other errors → log as errors
- Add 4 error scenario tests:
  * test_psq_deserialization_failure
  * test_handshake_abort_on_psq_failure
  * test_psq_invalid_signature
  * test_psq_state_unchanged_on_error
- Add log dependency to Cargo.toml

Error handling strategy: All PSQ failures abort the handshake cleanly
with no retry or fallback. This prevents silent security degradation
and ensures misconfigurations are detected early.

State guarantees: PSQ errors leave session in clean state - dummy PSK
remains, Noise HandshakeState unchanged, no partial data, no cleanup needed.

Tests: 81 tests passing (77 original + 4 new error tests)

Closes: nym-bbi

* feat(lp): add PSK injection tracking to prevent dummy PSK usage (nym-ep2)

Add safety mechanism to ensure real post-quantum PSK was injected before
allowing transport mode operations (encrypt/decrypt). This prevents
accidentally using the insecure dummy PSK [0u8; 32] if PSQ injection fails.

Changes:
- Add `psk_injected: AtomicBool` field to LpSession
- Initialize to `false` in LpSession::new()
- Set to `true` after successful PSK injection:
  * Initiator: In prepare_handshake_message() after set_psk()
  * Responder: In process_handshake_message() after set_psk()
- Add NoiseError::PskNotInjected error variant
- Add PSK injection checks in encrypt_data() and decrypt_data()
  * Check happens before handshake completion check
  * Returns PskNotInjected if flag is false
- Add comprehensive PSK injection lifecycle documentation to LpSession
- Add test_transport_fails_without_psk_injection test
- Update test_encrypt_decrypt_before_handshake to expect PskNotInjected

PSK Injection Lifecycle:
1. Session created with dummy PSK [0u8; 32] in Noise HandshakeState
2. During handshake, PSQ runs and derives real post-quantum PSK
3. Real PSK injected via set_psk() - psk_injected flag set to true
4. Handshake completes, transport mode available
5. Transport operations check psk_injected flag for safety

This is defensive programming - normal PSQ flow always injects the real PSK.
The safety check prevents transport mode if PSQ somehow fails silently or is
bypassed due to implementation bugs.

Tests: 82 tests passing (81 original + 1 new)

Closes: nym-ep2

* docs(lp): fix PSK state documentation inaccuracy

Correct error handling documentation to clarify that PSK slot 3
remains unmodified only on error, not in all cases.

Previous: "PSK slot 3 = dummy [0u8; 32] (never modified)"
Corrected: "PSK slot 3 = dummy [0u8; 32] (not modified on error)"

This is more accurate since:
- On error: PSK remains as dummy value (never injected)
- On success: PSK is replaced with real post-quantum PSK

Documentation-only change, no functional impact.

* feat(lp): add KKTExchange state to state machine for pre-handshake KEM key transfer (nym-4za)

Add KKTExchange state to LpStateMachine to properly orchestrate KKT (KEM Key Transfer)
protocol before Noise handshake begins. This enables dynamic KEM public key exchange,
allowing post-quantum KEM algorithms to be used without pre-published keys.

Changes:
- Add KKTExchange state and KKTComplete action to state machine
- Implement automatic KKT exchange on StartHandshake:
  * Initiator: sends KKT request → waits for response → validates signature
  * Responder: waits for request → validates → sends signed KEM key
- Update process_kkt_response() to accept Option<&[u8]> for hash validation:
  * Some(hash): full KKT validation with directory hash (future)
  * None: signature-only mode (current deployment)
- Add local_x25519_public() helper for responder KEM key derivation
- Update state flow: ReadyToHandshake → KKTExchange → Handshaking → Transport
- Add PSK handle storage (psk_handle) for future re-registration
- Export generate_fresh_salt() for session creation
- Update psq_responder_process_message() to return encrypted PSK handle (ctxt_B)
- Add comprehensive tests:
  * test_kkt_exchange_initiator_flow
  * test_kkt_exchange_responder_flow
  * test_kkt_exchange_full_roundtrip
  * test_kkt_exchange_close
  * test_kkt_exchange_rejects_invalid_inputs
  * Updated test_state_machine_simplified_flow for KKT phase

All tests passing. Ready for nym-8y5 (PSQ handshake KKT integration).

* docs(lp): add state machine and post-quantum security protocol documentation

Add comprehensive documentation of the Lewes Protocol state machine and
post-quantum security architecture to LP_PROTOCOL.md.

New sections:
- State Machine and Security Protocol overview
- Detailed state transition diagram (ReadyToHandshake → KKTExchange → Handshaking → Transport)
- Complete message sequence diagram showing KKT + PSQ + Noise flow
- KKT (KEM Key Transfer) protocol specification
- PSQ (Post-Quantum Secure PSK) protocol details
- Security guarantees and implementation status
- Algorithm choices (current X25519, future ML-KEM-768)
- Message type specifications for KKT
- Version 1.1 changelog entry documenting KKT/PSQ integration

Documentation includes:
- ASCII art state machine diagram
- Message sequence diagram with all protocol phases
- PSK derivation formulas
- Security properties checklist
- Migration path to post-quantum KEMs
- Integration details (PSQ embedded in Noise, no extra round-trips)

Related to nym-4za (KKTExchange state implementation).

* feat(lp): use KKT-authenticated KEM key in PSQ handshake (nym-8y5)

Replace direct X25519→KEM conversion with KKT-derived authenticated key
in PSQ initiator flow. This ensures PSQ uses the responder's authenticated
KEM public key obtained via KKT protocol instead of blindly converting
their X25519 key, properly completing the post-quantum security chain.

Changes:
- session.rs: Extract KEM key from KKTState::Completed in prepare_handshake_message()
- session.rs: Add set_kkt_completed_for_test() helper for test initialization
- session.rs: Update create_handshake_test_session() to initialize KKT state
- session.rs: Fix test_handshake_abort_on_psq_failure and test_psq_invalid_signature
- session_manager.rs: Add init_kkt_for_test() for integration test setup
- session_integration/mod.rs: Update tests for KKT-first flow (6 rounds total)
- session_integration/mod.rs: Fix state machine test expectations for KKTExchange state

All 87 tests passing. Unblocks nym-w8f (KKT tests) and nym-m15 (production integration).

* feat(lp): simplify API to Ed25519-only, derive X25519 internally

Refactored LP state machine to use Ed25519 keys exclusively in the public
API, with X25519 keys derived internally via RFC 7748. This simplifies the
API from 6 parameters to 4 while maintaining protocol security.

**Core API Changes:**
- LpStateMachine::new(): Removed explicit X25519 keypair parameters
- Old: new(is_initiator, local_keypair, local_ed25519_keypair,
         remote_public_key, remote_ed25519_key, salt)
- New: new(is_initiator, local_ed25519_keypair, remote_ed25519_key, salt)
- X25519 keys now derived internally from Ed25519 using RFC 7748
- lp_id calculation moved inside state machine (uses derived X25519 keys)

**Protocol Changes:**
- ClientHello message extended from 65 to 97 bytes
- Now includes client_ed25519_public_key field (32 bytes)
- Required for PSQ authentication in KKT + PSQ handshake flow
- Breaking change: gateway must extract Ed25519 from ClientHello

**Gateway Updates:**
- receive_client_hello() now extracts Ed25519 public key
- LpGatewayHandshake::new_responder() accepts Ed25519 keys only
- Removed manual X25519 conversion (handled by state machine)

**Registration Client Updates:**
- LpRegistrationClient now uses Ed25519 keypairs
- Generate fresh ephemeral Ed25519 keys for LP registration
- ClientHello includes Ed25519 public key for gateway authentication
- Fixed 7 pre-existing build errors:
  * mixnet_client_startup_timeout field removal
  * IprClientConnect API change (async → sync)
  * Error variant renames (use helper function)
  * LP client key type mismatches (X25519 → Ed25519)

**Test Suite:**
- Updated 16+ test functions to use new 4-parameter constructor
- Fixed 5 integration test failures caused by lp_id mismatch
- Tests now derive X25519 from Ed25519 (matching production behavior)
- Added missing PublicKey imports in test modules
- All 87 tests passing (100% success rate)

**Implementation Details:**
- Added Ed25519RecoveryError variant to LpError enum
- Type conversion: nym_crypto X25519 → nym_lp keypair types
- Maintained backward compatibility for PSQ/KKT protocol flow
- Session manager updated to use new API signature

This change completes the Ed25519-only API migration, hiding X25519 as an
implementation detail while preserving all security properties of the
KKT-authenticated PSQ handshake protocol.

* chore: run cargo fmt

* chore: run cargo clippy --fix to resolve simple linter issues

* Basic handshake working

* Final tweaks

* Wrap PR comments, 2024

---------

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2025-11-21 18:37:38 +01:00
durch 6d0e4f65f2 Simplify, clean up 2025-11-21 18:25:47 +01:00
durch 1f6daa7fd3 Bits and bobs to make everything work 2025-11-21 18:25:47 +01:00
durch fbcc9e4782 lp-reg gw flow working-ish 2025-11-21 18:25:47 +01:00
durch 55e891ae51 Add LP registration testing to nym-gateway-probe
Implement LP (Lewes Protocol) registration flow testing in nym-gateway-probe
to validate gateway LP registration capabilities alongside existing WireGuard
and mixnet tests.

Changes:
- Add LpProbeResults struct to track LP registration test results
  (can_connect, can_handshake, can_register, error)
- Add lp_registration_probe() function that tests full registration flow:
  * TCP connection to LP listener (port 41264)
  * Noise protocol handshake with PSK derivation
  * Registration request with bandwidth credentials
  * Registration response validation
- Integrate LP test into main probe flow - runs automatically if gateway
  has LP address (derived from gateway IP + port 41264)
- Export LpRegistrationClient from nym-registration-client for probe use
- Add LP address field to TestedNodeDetails

The probe tests only successful registration without additional traffic,
keeping the implementation simple and focused.
2025-11-21 18:18:30 +01:00
durch 67de8e263e Title 2025-11-21 18:18:30 +01:00
durch c580343f75 MacOS setup instructions 2025-11-21 18:18:30 +01:00
durch 9e9b1af28a Docker/Container localnet 2025-11-21 18:18:30 +01:00
durch 6533562e1d Cleanup 2025-11-21 18:18:30 +01:00
durch 10405c7dc1 more metrics 2025-11-21 18:18:30 +01:00
durch de06f4a5c0 fmt and metrics 2025-11-21 18:17:32 +01:00
durch ec90a218df Cleanup 2025-11-21 18:16:34 +01:00
durch 5f2122688f KDF and tests 2025-11-21 18:16:34 +01:00
durch dd6b7b6a34 Remove notes 2025-11-21 13:49:22 +01:00
durch cae63877a4 Client bits 2025-11-21 13:49:22 +01:00
durch 542e56044a Gateway side things 2025-11-21 13:40:50 +01:00
Mark Sinclair 96e3ff2af9 Node Status UI (#6210)
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2025-11-17 09:18:01 +00:00
Jędrzej Stuczyński d73b7b7127 chore: remove support for legacy mixnode within the performance contract (#6205) 2025-11-14 15:04:59 +00:00
Jędrzej Stuczyński 440aadf124 chore: updated default endpoint for retrieving attestation.json (#6207) 2025-11-14 15:04:51 +00:00
Jędrzej Stuczyński d126d8e5a0 feat: upgrade mode: VPN adjustments (#6189)
* placeholder handling of wg registration with upgrade mode token

* include upgrade mode credentials as part of credential storage

* introduce helper for decoding JWT payload

* expose methods for removing emergency credentials from the storage

* don't allow duplicate emergency credentials with the same content

* added authenticator ClientMessage for upgrade mode check

* retrieve credentials with longest expiration first

* post rebasing fixes

* fixed gateway config

* feat: allow specifying minimum node performance for client init

* nym-node UM improvements

* fixed upgrade mode bandwidth on initial authentication

* fix: logs and thresholds

* expose attestation information from nym-node http api

* additional logs

* post rebasing fixes

* make @simonwicky happy by removing empty lines in emergency_credential table definition

* chore: remove '_' prefix for internal counters within in-mem ecash storage

* improved import of 'UpgradeModeState' within the nym-node

* use explicit time dependency within credential-storage

* re-order imports within the gateway-client

* moved 'AvailableBandwidth' definition to the monorepo
2025-11-14 13:34:36 +00:00
Jędrzej Stuczyński 6b2bb3029b feat: merge intermediate upgrade mode changes (#6174)
* squashing feat: merge intermediate upgrade mode changes #6174 to more easily resolve merge conflicts during rebasing

added additional v2 query for metadata endpoint for requesting upgrade mode recheck

added additional message to v6 authenticator to request explicit upgrade mode recheck

clippy

test fixes due to updated keys

updated assertion for upgrading v1 top up request to v2

compare attester public key against the expected value within the credential proxy

use pre-generated attestation public keys within nym-nodes

remove version deprecation

bugfix: default bandwidth response for authenticator

expose upgrade mode information in authenticator responses

adding tests for new v2 server

passing upgrade mode information in metadata endpoint

v2 wireguard private metadata

bugfix: make sure to immediately poll for attestation after spawning task

fix gateway probe and remove code duplication for finalizing registration

squashing before rebasing

post rebasing fixes

AuthenticatorVersion helpers

additional nits

allow unwraps in mocks

fixed linux build

clippy

integrating upgrade mode into authenticator

fixed build after adding wrappers to response types

conditionally updating peer handle bandwidth

cleanup

negotiate initial protocol during registration

change auth to use highest protocol

handler for JWT message

dont meter client bandwidth in upgrade mode

handling recheck requests

sending information about upgrade_mode on client messages

gateway watching for upgrade mode attestation

wip: gateways to disable bandwidth metering on upgrade mode

* fixed ServerResponse deserialisation

* fixed incorrect swagger path for upgrade mode check endpoint

* moved upgrade mode endpoint out of bandwidth routes

* chore: remove unused error variant

* removed re-export of UpgradeModeAttestation from credentials-interface

* chore: define single source of truth for minimum bandwidth threshold value

* moved type definitions out of traits.rs

* updated v6 versioning to point to niolo release instead

* fixed incorrect error mapping
2025-11-14 13:13:15 +00:00
benedetta davico 4dcc568ec2 Merge pull request #6204 from nymtech/master
merging master to develop to maintain sync
2025-11-14 11:21:13 +01:00
benedetta davico 468835e3a2 Merge pull request #6199 from nymtech/release/2025.20-leerdammer
Release/2025.20 leerdammer
2025-11-14 10:36:23 +01:00