### Manage server lifecycle Source: https://katzenpost.network/docs/run_katzenpost_mixnode_docker Start or stop the mix server container. ```bash cd katzenpost-mix ./service.sh [start|stop] ``` -------------------------------- ### Start ThinClient Source: https://katzenpost.network/docs/_print Starts the client by establishing a connection to the daemon and initiating the background event loop. ```python async def start(loop: asyncio.AbstractEventLoop) -> None ``` -------------------------------- ### Build and run katzenqt Source: https://katzenpost.network/docs/build_from_source Install dependencies, clone the repository, checkout the pinned version, and launch the application. ```bash sudo apt install -y git make libxcb-cursor0 libegl1 git clone https://github.com/katzenpost/katzenqt cd katzenqt git checkout 0.0.2 make deps make run ``` -------------------------------- ### Install server binaries Source: https://katzenpost.network/docs/admin_guide/install.html Copy the compiled server and directory authority binaries to the system binary directory. ```bash # cp server/cmd/server/server /usr/local/bin/katzenpost-mixserver # cp authority/cmd/dirauth/dirauth /usr/local/bin/katzenpost-authority ``` -------------------------------- ### Dial / new / start Source: https://katzenpost.network/docs/thin_client_api_reference Establishes a connection to the client daemon and initializes the client. This method performs the handshake, receives initial status and PKI documents, and starts background workers. ```APIDOC ## Dial / new / start ### Description Establishes a connection to the client daemon and initializes the client. This method performs the complete connection handshake, including network connection, status retrieval, PKI document reception, and starting background workers. ### Signatures - **Go**: `func (t *ThinClient) Dial() error` - **Rust**: `pub async fn new(config: Config) -> Result, Box>` - **Python**: `async def start(self, loop: asyncio.AbstractEventLoop) -> None` ``` -------------------------------- ### ThinClient.start Source: https://katzenpost.network/docs/python_thin_client_api Establishes a connection to the daemon, reads initial events, and starts the background event loop. ```APIDOC ## async start(loop: asyncio.AbstractEventLoop) -> None ### Description Starts the thin client by establishing a connection to the daemon, reading initial events, and beginning the background event loop. ### Parameters - **loop** (asyncio.AbstractEventLoop) - Required - The running asyncio event loop. ### Exceptions - **BrokenPipeError** - Raised if the connection fails. ``` -------------------------------- ### Install dependencies on Debian/Ubuntu Source: https://katzenpost.network/docs/admin_guide/docker.html Use these commands to install the required software packages on a Debian or Ubuntu system. ```bash # **apt update**# **apt install git golang make podman podman-compose** ``` -------------------------------- ### Configure Server Section Source: https://katzenpost.network/docs/admin_guide/components.html Example configuration block for a Katzenpost service node. ```toml [Server] Identifier = "servicenode1" WireKEM = "xwing" PKISignatureScheme = "Ed25519" Addresses = ["127.0.0.1:30006"] OnlyAdvertiseAltAddresses = false MetricsAddress = "127.0.0.1:30007" DataDir = "/dirauth_mixnet/servicenode1" IsGatewayNode = false IsServiceNode = true [Server.AltAddresses] ``` -------------------------------- ### ThinClient.start(loop) Source: https://katzenpost.network/docs/_print Starts the thin client, establishing a connection to the daemon and beginning the background event loop. ```APIDOC ## ThinClient.start ### Description Establishes a connection to the daemon, reads initial events, and starts the background event loop. ### Parameters - **loop** (asyncio.AbstractEventLoop) - Required - The running asyncio event loop. ``` -------------------------------- ### Enable Spool Service Source: https://katzenpost.network/docs/admin_guide/components.html Example setting to enable the spool service. ```toml Disable = false ``` -------------------------------- ### Start the Mixnet Source: https://katzenpost.network/docs/admin_guide/docker.html Initializes the network. Use the docker argument to override automatic Podman detection. ```bash ~/katzenpost/docker$ **make start** ``` ```bash ~/katzenpost/docker$ **make start docker=docker** ``` -------------------------------- ### Initialize Config and ThinClient Source: https://katzenpost.network/docs/_print Basic setup for a ThinClient instance using a TOML configuration file and a reply handler callback. ```python payload = event['payload'] config = Config("client.toml", on_message_reply=handle_reply) client = ThinClient(config) ``` -------------------------------- ### Initialize Config with Callbacks Source: https://katzenpost.network/docs/python_thin_client_api Example of defining a reply handler and initializing the Config object with a TOML file path. ```python def handle_reply(event): # Process the received reply payload = event['payload'] config = Config("client.toml", on_message_reply=handle_reply) client = ThinClient(config) ``` -------------------------------- ### Define server configuration Source: https://katzenpost.network/docs/run_katzenpost_mixnode_docker Example TOML configuration for the mix server. ```toml [Server] Identifier = "" PKISignatureScheme = "Ed25519 Sphincs+" WireKEM = "KYBER768-X25519" Addresses = [ "tcp://:" ] BindAddresses = [ "tcp://0.0.0.0:8181" ] DataDir = "/var/lib/katzenpost" IsGatewayNode = false IsServiceNode = false [Logging] Disable = false File = "" Level = "NOTICE" ``` -------------------------------- ### Initialize and Connect Client Source: https://katzenpost.network/docs/thin_client_api_reference Establishes a connection to the client daemon. Rust handles connection during instantiation, while Go and Python require explicit start methods. ```go func (t *ThinClient) Dial() error ``` ```rust pub async fn new(config: Config) -> Result, Box> ``` ```python async def start(self, loop: asyncio.AbstractEventLoop) -> None: ``` -------------------------------- ### Get Services by Capability Source: https://katzenpost.network/docs/python_thin_client_api Looks up all services in the PKI that advertise a specific capability. ```python def get_services(capability: str) -> "List[ServiceDescriptor]" ``` -------------------------------- ### Connect and handle events in Python Source: https://katzenpost.network/docs/thin_client_howto Configures event callback functions and starts the client using an asyncio event loop. ```python async def on_connection_status(event): print(f"Connected: {event.get('is_connected')}") async def on_new_document(event): print("New PKI document received") async def on_message_reply(event): print(f"Reply received") config = Config("thinclient.toml") config.on_connection_status = on_connection_status config.on_new_pki_document = on_new_document config.on_message_reply = on_message_reply client = ThinClient(config) loop = asyncio.get_running_loop() await client.start(loop) # ... do work ... client.stop() ``` -------------------------------- ### End-to-End Stream Communication Source: https://katzenpost.network/docs/_print A complete example demonstrating stream creation, message writing by Alice, and reading by Bob. ```go package main import ( "log" "github.com/katzenpost/hpqc/rand" "github.com/katzenpost/katzenpost/client/thin" "github.com/katzenpost/katzenpost/core/config" ) func main() { cfg, err := thin.LoadFile("thinclient.toml") if err != nil { log.Fatal(err) } client := thin.NewThinClient(cfg, &config.Logging{Level: "INFO"}) if err := client.Dial(); err != nil { log.Fatal(err) } defer client.Close() // Alice creates a stream. seed := make([]byte, 32) if _, err := rand.Reader.Read(seed); err != nil { log.Fatal(err) } writeCap, readCap, idx, err := client.NewKeypair(seed) if err != nil { log.Fatal(err) } // Alice writes one message. ct, ed, eh, _, err := client.EncryptWrite( []byte("hello from Alice"), writeCap, idx) if err != nil { log.Fatal(err) } if _, err := client.StartResendingEncryptedMessage( nil, writeCap, nil, nil, ed, ct, eh); err != nil { log.Fatal(err) } // Bob reads it back (readCap would normally be shared out-of-band). rct, red, reh, _, err := client.EncryptRead(readCap, idx) if err != nil { log.Fatal(err) } idxBytes, err := idx.MarshalBinary() if err != nil { log.Fatal(err) } result, err := client.StartResendingEncryptedMessage( readCap, nil, idxBytes, nil, red, rct, reh) if err != nil { log.Fatal(err) } log.Printf("Bob read: %s", result.Plaintext) } ``` ```rust use katzenpost_thin_client::{Config, ThinClient}; #[tokio::main] async fn main() -> Result<(), Box> { let config = Config::new("thinclient.toml")?; let client = ThinClient::new(config).await?; // Alice creates a stream. let seed: [u8; 32] = rand::random(); let kp = client.new_keypair(&seed).await?; // Alice writes one message. let w = client.encrypt_write( b"hello from Alice", &kp.write_cap, &kp.first_message_index).await?; client.start_resending_encrypted_message( None, Some(&kp.write_cap), None, None, &w.envelope_descriptor, &w.message_ciphertext, &w.envelope_hash).await?; // Bob reads it back (read_cap would normally be shared out-of-band). let r = client.encrypt_read(&kp.read_cap, &kp.first_message_index).await?; let result = client.start_resending_encrypted_message( Some(&kp.read_cap), None, Some(&kp.first_message_index), None, &r.envelope_descriptor, &r.message_ciphertext, &r.envelope_hash).await?; println!("Bob read: {:?}", result.plaintext); client.stop().await; Ok(()) } ``` ```python import asyncio, os from katzenpost_thinclient import ThinClient, Config async def main(): config = Config("thinclient.toml") client = ThinClient(config) await client.start(asyncio.get_running_loop()) # Alice creates a stream. seed = os.urandom(32) kp = await client.new_keypair(seed) # Alice writes one message. w = await client.encrypt_write( b"hello from Alice", kp.write_cap, kp.first_message_index) await client.start_resending_encrypted_message( read_cap=None, write_cap=kp.write_cap, message_box_index=None, reply_index=None, envelope_descriptor=w.envelope_descriptor, message_ciphertext=w.message_ciphertext, envelope_hash=w.envelope_hash) ``` -------------------------------- ### Create service management script Source: https://katzenpost.network/docs/run_katzenpost_mixnode_docker Create a shell script to handle starting, stopping, and key generation for the container. ```bash #!/bin/bash CMD=${1:-start} case ${CMD} in genkeys) MODE="-ti --rm" EXEC="/usr/bin/server -g" ;; start) MODE="-d --restart=unless-stopped" EXEC="" ;; stop) docker stop katzenpost-mix docker rm katzenpost-mix exit ;; *) echo "unknown command" exit 1 ;; esac docker run ${MODE} \ --name katzenpost-mix -h katzenpost-mix \ -p 0.0.0.0::8181 \ -v $(pwd)/conf:/conf \ -v $(pwd)/data:/var/lib/katzenpost \ katzenpost/mix ${EXEC} ``` -------------------------------- ### Usage Example for Tombstone Envelopes Source: https://katzenpost.network/docs/python_thin_client_api Demonstrates how to invoke the tombstone range creation and iterate over the resulting envelopes. ```python result = await client.create_courier_envelopes_from_tombstone_range( write_cap, start_index, 10, is_start=True, is_last=True) for envelope in result.envelopes: # write envelope to temp copy stream channel pass ``` -------------------------------- ### End-to-end stream messaging example Source: https://katzenpost.network/docs/thin_client_howto A complete program demonstrating stream creation, message writing, and reading. The read capability must be shared out-of-band in a real-world scenario. ```go package main import ( "log" "github.com/katzenpost/hpqc/rand" "github.com/katzenpost/katzenpost/client/thin" "github.com/katzenpost/katzenpost/core/config" ) func main() { cfg, err := thin.LoadFile("thinclient.toml") if err != nil { log.Fatal(err) } client := thin.NewThinClient(cfg, &config.Logging{Level: "INFO"}) if err := client.Dial(); err != nil { log.Fatal(err) } defer client.Close() // Alice creates a stream. seed := make([]byte, 32) if _, err := rand.Reader.Read(seed); err != nil { log.Fatal(err) } writeCap, readCap, idx, err := client.NewKeypair(seed) if err != nil { log.Fatal(err) } // Alice writes one message. ct, ed, eh, _, err := client.EncryptWrite( []byte("hello from Alice"), writeCap, idx) if err != nil { log.Fatal(err) } if _, err := client.StartResendingEncryptedMessage( nil, writeCap, nil, nil, ed, ct, eh); err != nil { log.Fatal(err) } // Bob reads it back (readCap would normally be shared out-of-band). rct, red, reh, _, err := client.EncryptRead(readCap, idx) if err != nil { log.Fatal(err) } idxBytes, err := idx.MarshalBinary() if err != nil { log.Fatal(err) } result, err := client.StartResendingEncryptedMessage( readCap, nil, idxBytes, nil, red, rct, reh) if err != nil { log.Fatal(err) } log.Printf("Bob read: %s", result.Plaintext) } ``` ```rust use katzenpost_thin_client::{Config, ThinClient}; #[tokio::main] async fn main() -> Result<(), Box> { let config = Config::new("thinclient.toml")?; let client = ThinClient::new(config).await?; // Alice creates a stream. let seed: [u8; 32] = rand::random(); let kp = client.new_keypair(&seed).await?; // Alice writes one message. let w = client.encrypt_write( b"hello from Alice", &kp.write_cap, &kp.first_message_index).await?; client.start_resending_encrypted_message( None, Some(&kp.write_cap), None, None, &w.envelope_descriptor, &w.message_ciphertext, &w.envelope_hash).await?; // Bob reads it back (read_cap would normally be shared out-of-band). let r = client.encrypt_read(&kp.read_cap, &kp.first_message_index).await?; let result = client.start_resending_encrypted_message( Some(&kp.read_cap), None, Some(&kp.first_message_index), None, &r.envelope_descriptor, &r.message_ciphertext, &r.envelope_hash).await?; println!("Bob read: {:?}", result.plaintext); client.stop().await; Ok(()) } ``` ```python import asyncio, os from katzenpost_thinclient import ThinClient, Config async def main(): config = Config("thinclient.toml") client = ThinClient(config) await client.start(asyncio.get_running_loop()) # Alice creates a stream. seed = os.urandom(32) kp = await client.new_keypair(seed) # Alice writes one message. w = await client.encrypt_write( b"hello from Alice", kp.write_cap, kp.first_message_index) await client.start_resending_encrypted_message( read_cap=None, write_cap=kp.write_cap, message_box_index=None, reply_index=None, envelope_descriptor=w.envelope_descriptor, message_ciphertext=w.message_ciphertext, envelope_hash=w.envelope_hash) # Bob reads it back (read_cap would normally be shared out-of-band). r = await client.encrypt_read(kp.read_cap, kp.first_message_index) plaintext = await client.start_resending_encrypted_message( read_cap=kp.read_cap, write_cap=None, message_box_index=kp.first_message_index, reply_index=None, envelope_descriptor=r.envelope_descriptor, message_ciphertext=r.message_ciphertext, envelope_hash=r.envelope_hash) print("Bob read:", plaintext) client.stop() asyncio.run(main()) ``` -------------------------------- ### Build kpclientd from source Source: https://katzenpost.network/docs/build_from_source Clone the repository, checkout the pinned version, and build the client daemon binary. ```bash git clone https://github.com/katzenpost/katzenpost cd katzenpost git checkout v0.0.90 make kpclientd ``` -------------------------------- ### Execute next_message_box_index Source: https://katzenpost.network/docs/_print Example usage of the index increment method. ```python current_index = first_message_index next_index = await client.next_message_box_index(current_index) ``` -------------------------------- ### Prepare host filesystem Source: https://katzenpost.network/docs/run_katzenpost_mixnode_docker Create the necessary directory structure for configuration and data storage. ```bash mkdir katzenpost-mix cd katzenpost-mix mkdir {conf,data} chmod 700 data ``` -------------------------------- ### Execute cancel_resending_encrypted_message Source: https://katzenpost.network/docs/_print Example usage of the cancellation method using an envelope hash. ```python await client.cancel_resending_encrypted_message(env_hash) ``` -------------------------------- ### Initialize Thin Client Source: https://katzenpost.network/docs/thin_client_api_reference Constructs a new thin client instance using a TOML configuration file. ```go cfg, err := thin.LoadFile("thinclient.toml") if err != nil { log.Fatal(err) } logging := &config.Logging{Level: "INFO"} client := thin.NewThinClient(cfg, logging) ``` ```rust let config = Config::new("thinclient.toml")?; let client = ThinClient::new(config).await?; ``` ```python config = Config("thinclient.toml") client = ThinClient(config) ``` -------------------------------- ### ThinClient.__init__ Source: https://katzenpost.network/docs/python_thin_client_api Initializes the ThinClient instance with the provided configuration. ```APIDOC ## ThinClient.__init__(config) ### Description Initializes the thin client to establish a connection with the local Katzenpost client daemon based on the provided configuration. ### Parameters - **config** (Config) - Required - The configuration object containing socket details and callbacks. ### Raises - **RuntimeError** - Raised if the network type is unrecognized or the configuration is incomplete. ``` -------------------------------- ### Configure Directory Authorities Source: https://katzenpost.network/docs/admin_guide/_print Example configuration for multiple directory authorities in a Katzenpost network. ```TOML [[PKI.dirauth.Authorities]] Identifier = "auth1" IdentityPublicKey = """-----BEGIN ED25519 PUBLIC KEY----- tqN6tpOVotHWXKCszVn2kS7vAZjQpvJjQF3Qz/Qwhyg= -----END ED25519 PUBLIC KEY----- """ PKISignatureScheme = "Ed25519" LinkPublicKey = """-----BEGIN XWING PUBLIC KEY----- JnJ8ztQEIjAkKJcpuZvJAdkWjBim/5G5d8yoosEQHeGJeeBqNPdm2AitUbpiQPcd tNCo9DxuC9Ieqmsfw0YpV6AtOOsaInA6QnHDYcuBfZcQL5MU4+t2TzpBZQYlrSED hPCKrAG+8GEUl6akseG371WQzEtPpEWWCJCJOiS/VDFZT7eKrldlumN6gfiB84sR ... arFh/WKwYJUj+aGBsFYSqGdzC6MdY4x/YyFe2ze0MJEjThQE91y1d/LCQ3Sb7Ri+ u6PBi3JU2qzlPEejDKwK0t5tMNEAkq8iNrpRTdD/hS0gR+ZIN8Z9QKh7Xf94FWG2 H+r8OaqImQhgHabrWRDyLg== -----END XWING PUBLIC KEY----- """ WireKEMScheme = "xwing" Addresses = ["127.0.0.1:30001"] [[PKI.dirauth.Authorities]] Identifier = "auth2" IdentityPublicKey = """-----BEGIN ED25519 PUBLIC KEY----- O51Ty2WLu4C1ETMa29s03bMXV72gnjJfTfwLV++LVBI= -----END ED25519 PUBLIC KEY----- """ PKISignatureScheme = "Ed25519" LinkPublicKey = """-----BEGIN XWING PUBLIC KEY----- TtQkg2XKUnY602FFBaPJ+zpN0Twy20cwyyFxh7FNUjaXA9MAJXs0vUwFbJc6BjYv f+olKnlIKFSmDvcF74U6w1F0ObugwTNKNxeYKPKhX4FiencUbRwkHoYHdtZdSctz TKy08qKQyCAccqCRpdo6ZtYXPAU+2rthjYTOL7Zn+7SHUKCuJClcPnvEYjVcJxtZ ... ubJIe5U4nMJbBkOqr7Kq6niaEkiLODa0tkpB8tKMYTMBdcYyHSXCzpo7U9sb6LAR HktiTBDtRXviu2vbw7VRXhkMW2kjYZDtReQ5sAse04DvmD49zgTp1YxYW+wWFaL3 37X7/SNuLdHX4PHZXIWHBQ== -----END XWING PUBLIC KEY----- """ WireKEMScheme = "xwing" Addresses = ["127.0.0.1:30002"] [[PKI.dirauth.Authorities]] Identifier = "auth3" IdentityPublicKey = """-----BEGIN ED25519 PUBLIC KEY----- zQvydRYJq3npeLcg1NqIf+SswEKE5wFmiwNsI9Z1whQ= -----END ED25519 PUBLIC KEY----- """ PKISignatureScheme = "Ed25519" LinkPublicKey = """ -----BEGIN XWING PUBLIC KEY----- OYK9FiC53xwZ1VST3jDOO4tR+cUMSVRSekmigZMChSjDCPZbKut8TblxtlUfc/yi Ugorz4NIvYPMWUt3QPwS2UWq8/HMWXNGPUiAevg12+oV+jOJXaJeCfY24UekJnSw TNcdGaFZFSR0FocFcPBBnrK1M2B8w8eEUKQIsXRDM3x/8aRIuDif+ve8rSwpgKeh ... OdVD3yw7OOS8uPZLORGQFyJbHtVmFPVvwja4G/o2gntAoHUZ2LiJJakpVhhlSyrI yuzvwwFtZVfWtNb5gAKZCyg0aduR3qgd7MPerRF+YopZk3OCRpC02YxfUZrHv398 FZWJFK0R8iU52CEUxVpXTA== -----END XWING PUBLIC KEY----- """ WireKEMScheme = "xwing" Addresses = ["127.0.0.1:30003"] ``` -------------------------------- ### View Mix Server CLI Options Source: https://katzenpost.network/docs/admin_guide/quickstart.html Display help information for the katzenpost-mixserver binary. ```bash $ katzenpost-mixserver -h Usage of katzenpost-mixserver: -f string Path to the authority config file. (default "katzenpost.toml") -g Generate the keys and exit immediately. -v Get version info. ``` -------------------------------- ### Get PKI Document Source: https://katzenpost.network/docs/_print Retrieves the most recent PKI consensus document forwarded by the daemon. ```python def pki_document() -> "Dict[str,Any] | None" ``` -------------------------------- ### Get Directory Authorities Source: https://katzenpost.network/docs/python_thin_client_api Retrieves the directory authority descriptors configured in the client daemon. ```python async def get_directory_authorities() -> "List[Dict[str,Any]]" ``` -------------------------------- ### Connect and handle events in Go Source: https://katzenpost.network/docs/thin_client_howto Initializes the thin client from a configuration file and processes events using a channel-based loop. ```go cfg, err := thin.LoadFile("thinclient.toml") if err != nil { log.Fatal(err) } logging := &config.Logging{Level: "INFO"} client := thin.NewThinClient(cfg, logging) err = client.Dial() if err != nil { log.Fatal(err) } defer client.Close() // Listen for events eventCh := client.EventSink() defer client.StopEventSink(eventCh) for ev := range eventCh { switch v := ev.(type) { case *thin.ConnectionStatusEvent: fmt.Printf("Connected: %v\n", v.IsConnected) case *thin.NewDocumentEvent: fmt.Println("New PKI document received") case *thin.MessageReplyEvent: fmt.Printf("Reply received for SURB %x\n", v.SURBID) } } ``` -------------------------------- ### Handle reply event example Source: https://katzenpost.network/docs/_print A callback function template for handling received message replies. ```python def handle_reply(event): ``` -------------------------------- ### Get Logger Instance Source: https://katzenpost.network/docs/thin_client_api_reference Returns a logger instance with a specified prefix for consistent log formatting. ```Go func (t *ThinClient) GetLogger(prefix string) *logging.Logger ``` -------------------------------- ### Config.__init__(filepath, on_connection_status=None, on_new_pki_document=None, on_message_sent=None, on_message_reply=None, on_daemon_disconnected=None) Source: https://katzenpost.network/docs/_print Initializes the configuration object, defining the path to the TOML configuration file and optional callback functions for handling various network events. ```APIDOC ## Config.__init__ ### Description Initializes the Config object with a path to a TOML configuration file and optional callback functions for handling mixnet events. ### Parameters - **filepath** (str) - Required - Path to the TOML config file. - **on_connection_status** (callable) - Optional - Callback for daemon connection status changes. - **on_new_pki_document** (callable) - Optional - Callback for receiving new PKI documents. - **on_message_sent** (callable) - Optional - Callback for message transmission status. - **on_message_reply** (callable) - Optional - Callback for received message replies. - **on_daemon_disconnected** (callable) - Optional - Callback for daemon disconnection events. ``` -------------------------------- ### Build and run kpclientd Source: https://katzenpost.network/docs/_print Commands to clone, checkout the pinned version, and build the client daemon. A TOML configuration file is required to run the resulting binary. ```bash git clone https://github.com/katzenpost/katzenpost cd katzenpost git checkout v0.0.90 make kpclientd ``` ```bash ./kpclientd -c /path/to/client.toml ``` -------------------------------- ### Execute start_resending_encrypted_message Source: https://katzenpost.network/docs/_print Example usage of the resending method to perform a read operation and print the resulting plaintext. ```python result = await client.start_resending_encrypted_message( read_cap, None, message_box_index, reply_idx, env_desc, ciphertext, env_hash) print(f"Received: {result.plaintext}") ``` -------------------------------- ### Monitor Mixnet Status Source: https://katzenpost.network/docs/_print Example output showing loop decoy traffic and success rate metrics. ```text !19:29:54.108 INFO gateway1_client: sending loop decoy 19:29:54.632 INFO gateway1_client: sending loop decoy 19:29:55.160 INFO gateway1_client: sending loop decoy !19:29:56.071 INFO gateway1_client: sending loop decoy !19:29:59.173 INFO gateway1_client: sending loop decoy !Success rate is 100.000000 percent 10/10) ``` -------------------------------- ### ConfigFile.load Source: https://katzenpost.network/docs/python_thin_client_api Parses a kpclientd-style thin-client TOML configuration file. ```APIDOC ## ConfigFile.load ### Description Parses a kpclientd-style thin-client TOML config. Raises ConfigError on structural problems, missing sections, or unknown keys. ### Method classmethod ### Parameters - **toml_path** (str) - Required - The file path to the TOML configuration file. ### Response - **ConfigFile** (object) - Returns an instance of ConfigFile representing the loaded configuration. ``` -------------------------------- ### Build server-side components Source: https://katzenpost.network/docs/build_from_source Build the mix server, directory authority, courier, and replica components from the katzenpost repository. ```bash git clone https://github.com/katzenpost/katzenpost cd katzenpost git checkout v0.0.90 make server make dirauth make courier make replica ``` -------------------------------- ### Define PQ Noise protocol string Source: https://katzenpost.network/docs/specs/wireprotocol Example of a protocol string configuration for the Katzenpost mix network. ```text Noise_pqXX_Xwing_ChaChaPoly_BLAKE2b ``` -------------------------------- ### Get Client Configuration Source: https://katzenpost.network/docs/thin_client_api_reference Retrieves the client configuration. Python callers should access the config attribute directly. ```Go func (t *ThinClient) GetConfig() *Config ``` -------------------------------- ### Run kpclientd Source: https://katzenpost.network/docs/build_from_source Execute the client daemon binary using a required TOML configuration file. ```bash ./kpclientd -c /path/to/client.toml ``` -------------------------------- ### Read encrypted messages Source: https://katzenpost.network/docs/_print Demonstrates reading an encrypted message using a read capability and starting the resending process. ```python # Bob reads it back (read_cap would normally be shared out-of-band). r = await client.encrypt_read(kp.read_cap, kp.first_message_index) plaintext = await client.start_resending_encrypted_message( read_cap=kp.read_cap, write_cap=None, message_box_index=kp.first_message_index, reply_index=None, envelope_descriptor=r.envelope_descriptor, message_ciphertext=r.message_ciphertext, envelope_hash=r.envelope_hash) print("Bob read:", plaintext) client.stop() asyncio.run(main()) ``` -------------------------------- ### Start Resending Copy Command Source: https://katzenpost.network/docs/thin_client_api_reference Sends a copy command to a courier and blocks until completion. Requires a write capability. ```Go func (t *ThinClient) StartResendingCopyCommand(writeCap *bacap.WriteCap) error ``` ```Rust pub async fn start_resending_copy_command( &self, write_cap: &[u8], courier_identity_hash: Option<&[u8]>, courier_queue_id: Option<&[u8]>, ) -> Result<(), ThinClientError> ``` ```Python async def start_resending_copy_command(self, write_cap: bytes, courier_identity_hash: 'bytes|None' = None, courier_queue_id: 'bytes|None' = None) -> None: ``` -------------------------------- ### ConfigFile.load Method Source: https://katzenpost.network/docs/python_thin_client_api Parses a kpclientd-style TOML configuration file. ```python @classmethod def load(cls, toml_path: str) -> "ConfigFile" ``` -------------------------------- ### Config.__init__ Source: https://katzenpost.network/docs/python_thin_client_api Initializes the configuration object for the ThinClient, including network settings and event callback functions. ```APIDOC ## Config.__init__(filepath, on_connection_status=None, on_new_pki_document=None, on_message_sent=None, on_message_reply=None, on_daemon_disconnected=None) ### Description Initializes the Config object by loading network, address, and geometry parameters from a TOML file and registering optional event callbacks. ### Parameters - **filepath** (str) - Required - Path to the TOML configuration file. - **on_connection_status** (callable) - Optional - Callback for daemon connection status changes. - **on_new_pki_document** (callable) - Optional - Callback for received PKI documents. - **on_message_sent** (callable) - Optional - Callback for message transmission confirmations. - **on_message_reply** (callable) - Optional - Callback for received message replies. - **on_daemon_disconnected** (callable) - Optional - Callback for daemon disconnection events. ``` -------------------------------- ### View Katzenpost server CLI options Source: https://katzenpost.network/docs/_print Display help and configuration options for the mixserver and authority binaries. ```bash $ katzenpost-mixserver -h Usage of katzenpost-mixserver: -f string Path to the authority config file. (default "katzenpost.toml") -g Generate the keys and exit immediately. -v Get version info. ``` ```bash $ katzenpost-authority -h Usage of katzenpost-authority: -f string Path to the authority config file. (default "authority.toml") -g Generate the keys and exit immediately. -v Get version info. ``` -------------------------------- ### Get Raw PKI Document Source: https://katzenpost.network/docs/_print Retrieves the signed, cert.Certificate-wrapped PKI document for verification of directory authority signatures. ```python async def get_pki_document_raw(epoch: int = 0) -> "Tuple[bytes,int]" ``` -------------------------------- ### Get Single Service Source: https://katzenpost.network/docs/python_thin_client_api Selects one random service matching a given capability from the current PKI document. ```python def get_service(service_name: str) -> ServiceDescriptor ``` -------------------------------- ### Retrieve All Services by Capability Source: https://katzenpost.network/docs/thin_client_api_reference Searches the current PKI document for all services providing the specified capability. ```Go func (t *ThinClient) GetServices(capability string) ([]*common.ServiceDescriptor, error) ``` ```Python def get_services(self, capability: str) -> 'List[ServiceDescriptor]': ``` -------------------------------- ### Retrieve All Services Source: https://katzenpost.network/docs/_print Returns all services matching a specific capability name. ```Go func (t *ThinClient) GetServices(capability string) ([]*common.ServiceDescriptor, error) ``` -------------------------------- ### Start resending a copy command Source: https://katzenpost.network/docs/_print Initiates ARQ resending for a copy command, either to a random courier or a specific one. ```python # Send copy command to a random courier await client.start_resending_copy_command(temp_write_cap) # Send copy command to a specific courier await client.start_resending_copy_command( temp_write_cap, courier_identity_hash, courier_queue_id) ```