From 2999c277ab315e5307a819c8f91f0f908da75d3f Mon Sep 17 00:00:00 2001 From: pmendes Date: Tue, 1 Oct 2024 16:45:02 +0100 Subject: [PATCH] Improve dapf documentation --- crates/dapf/README.md | 61 +++++++++++++++++++++++++++++++++++++++++ crates/dapf/src/main.rs | 33 +++++++++++++++++++--- 2 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 crates/dapf/README.md diff --git a/crates/dapf/README.md b/crates/dapf/README.md new file mode 100644 index 00000000..576032bd --- /dev/null +++ b/crates/dapf/README.md @@ -0,0 +1,61 @@ +# dapf (DAP functions) + +This binary provides various functions that can be called to interact with DAP +deployments. + +Its subcommands and their functionality can be consulted with the built in +help pages the CLI provides. + + +## Examples + +Here are some examples of common functionality of dapf. To avoid installing the +tool replace all instances of `dapf` with `cargo run --bin dapf`. + +### Generate an hpke config + +With the default algorithm: +``` +dapf hpke generate +``` + +With a specific algorithm: +``` +dapf hpke generate x25519_hkdf_sha256 +``` + +This will output the config twice: +``` +{ + "config": { + "id": 155, + "kem_id": "x25519_hkdf_sha256", + "kdf_id": "hkdf_sha256", + "aead_id": "aes128_gcm", + "public_key": "a63dd7e6bbfc68d54e8b25e39ceb826cdf5101592a026590cb935d754e4f210d" + }, + "private_key": "a5adeefcb0e09053e6ebded53277b65c81412c8eafadfe5706aef3453d45b05c" +} +DAP and base64 encoded hpke config: mwAgAAEAAQAgpj3X5rv8aNVOiyXjnOuCbN9RAVkqAmWQy5NddU5PIQ0 +``` + +First as JSON and second as a [DAP encoded][hpke-config-encoding] + base64 encoded string which can be +used when issuing requests to `internal/test/add_task`. + + +### Decoding responses from aggregators + + +#### Decoding aggregate shares + +Once you've collected from the leader you may want to see what the result of the +aggregation was, for that you can use the `decode` subcommand: + +```sh +dapf decode ./aggregate_share collection \ + --vdaf-config '{"prio3": { "sum": { "bits": 8 } } }' \ + --task-id "8TuT5Z5fAuutsX9DZWSqkUw6pzDl96d3tdsDJgWH2VY" \ + --hpke-config-path ./hpke-config.json +``` + +[hpke-config-encoding]: https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-09#section-4.4.1-6 diff --git a/crates/dapf/src/main.rs b/crates/dapf/src/main.rs index 52ac61e2..b0ebcb88 100644 --- a/crates/dapf/src/main.rs +++ b/crates/dapf/src/main.rs @@ -3,6 +3,7 @@ use anyhow::{anyhow, bail, Context, Result}; use clap::{builder::PossibleValue, Args, Parser, Subcommand, ValueEnum}; +use core::fmt; use dapf::{ acceptance::{load_testing, LoadControlParams, LoadControlStride, TestOptions}, deduce_dap_version_from_url, response_to_anyhow, HttpClient, @@ -251,7 +252,13 @@ enum HpkeAction { dap_version: DapVersion, }, /// Generate an hpke receiver config. - GenerateReceiverConfig { kem_alg: KemAlg }, + /// + /// This command outputs to stdout the hpke config in json and to stderr the config encoded + /// first by prio and then in base64. This version can later be used when TODO + Generate { + #[arg(default_value_t)] + kem_alg: KemAlg, + }, /// Rotate the HPKE config advertised by the Aggregator. RotateReceiverConfig { #[arg(short = 'c', long)] @@ -260,6 +267,7 @@ enum HpkeAction { wrangler_env: Option, #[arg(default_value_t, long)] dap_version: DapVersion, + #[arg(default_value_t)] kem_alg: KemAlg, }, } @@ -269,7 +277,7 @@ enum TestAction { /// Add an hpke config to a test-utils enabled `daphne-server`. AddHpkeConfig { aggregator_url: Url, - #[arg(short, long, default_value = "x25519_hkdf_sha256")] + #[arg(short, long, default_value_t)] kem_alg: KemAlg, }, /// Clear all storage of an aggregator. @@ -286,6 +294,11 @@ enum TestAction { enum CliDapMediaType { AggregationJobResp, AggregateShare, + /// Decode a [DapMediaType::Collection]. + /// + /// If the `--vdaf-config`, `--task-id` and `--hpke-config-path` are supplied, then the + /// aggregate share will also be decrypted and unsharded, presenting the final result of the + /// vdaf. Collection { #[clap(long, env)] vdaf_config: Option, @@ -383,6 +396,18 @@ impl LoadControlParamsCli { #[derive(Clone, Debug)] struct KemAlg(HpkeKemId); +impl Default for KemAlg { + fn default() -> Self { + Self(HpkeKemId::X25519HkdfSha256) + } +} + +impl fmt::Display for KemAlg { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.to_possible_value().unwrap().get_name()) + } +} + impl ValueEnum for KemAlg { fn value_variants<'a>() -> &'a [Self] { &[ @@ -781,12 +806,12 @@ async fn handle_hpke_actions(hpke: HpkeAction, http_client: HttpClient) -> anyho println!("{}", serde_json::to_string_pretty(&config)?); Ok(()) } - HpkeAction::GenerateReceiverConfig { kem_alg } => { + HpkeAction::Generate { kem_alg } => { let receiver_config = HpkeReceiverConfig::gen(rng.gen(), kem_alg.0) .with_context(|| "failed to generate HPKE receiver config")?; println!( "{}", - serde_json::to_string(&receiver_config) + serde_json::to_string_pretty(&receiver_config) .with_context(|| "failed to JSON-encode the HPKE receiver config")? ); eprintln!(