Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flesh out documentation #42

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ An Android client library for the [Distributed Aggregation Protocol][DAP].
The following versions of the DAP protocol are supported by different branches
and releases.

| Package version | Git branch | Protocol version | Conformant? | Status |
|-----------------|------------|------------------|-------------|--------|
| 0.1.0 (forthcoming) | `main` | [`draft-ietf-ppm-dap-07`][draft-07] | Yes | Supported |
| Package version | Git branch | Protocol version | Conformant? | Status |
|---------------------|------------|-------------------------------------|-------------|-----------|
| 0.1.0 (forthcoming) | `main` | [`draft-ietf-ppm-dap-07`][draft-07] | Yes | Supported |

[draft-07]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/07/

Expand Down
82 changes: 82 additions & 0 deletions divviup/src/main/java/org/divviup/android/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
import java.net.URL;
import java.util.Arrays;

/**
* A client that can submit reports to a particular DAP task. Objects of this class are immutable,
* and thus thread-safe.
*
* @param <M> the type of measurements (determined by the VDAF)
*/
public class Client<M> {
private static final String HPKE_CONFIG_LIST_CONTENT_TYPE = "application/dap-hpke-config-list";
private static final String REPORT_CONTENT_TYPE = "application/dap-report";
Expand Down Expand Up @@ -50,6 +56,19 @@ private Client(
this.reportPreparer = reportPreparer;
}

/**
* Constructs a client for a DAP task using the Prio3Count VDAF. Measurements are
* <code>Boolean</code>s. The aggregate result is the number of <code>true</code> measurements.
*
* @param leaderEndpoint the URI of the leader aggregator's HTTPS endpoint
* @param helperEndpoint the URI of the helper aggregator's HTTPS endpoint
* @param taskId the {@link TaskId} of the DAP task
* @param timePrecisionSeconds the time precision of the DAP task, in seconds
* @return a client for the configured DAP task
* @throws IllegalArgumentException if the scheme of leaderEndpoint or helperEndpoint is not
* http or https, or if timePrecisionSeconds is not a positive
* number
*/
public static Client<Boolean> createPrio3Count(
URI leaderEndpoint,
URI helperEndpoint,
Expand All @@ -65,6 +84,22 @@ public static Client<Boolean> createPrio3Count(
);
}

/**
* Constructs a client for a DAP task using the Prio3Sum VDAF. Measurements are <code>Long</code>
* integers. Valid measurements must be greater than or equal to zero, and less than
* <code>2 ^ bits</code>. The aggregate result is the sum of all measurements.
*
* @param leaderEndpoint the URI of the leader aggregator's HTTPS endpoint
* @param helperEndpoint the URI of the helper aggregator's HTTPS endpoint
* @param taskId the {@link TaskId} of the DAP task
* @param timePrecisionSeconds the time precision of the DAP task, in seconds
* @param bits the bit width of measurements. This is a parameter of the
* Prio3Sum VDAF.
* @return a client for the configured DAP task
* @throws IllegalArgumentException if the scheme of leaderEndpoint or helperEndpoint is not
* http or https, or if timePrecisionSeconds is not a positive
* number
*/
public static Client<Long> createPrio3Sum(
URI leaderEndpoint,
URI helperEndpoint,
Expand All @@ -81,6 +116,26 @@ public static Client<Long> createPrio3Sum(
);
}

/**
* Constructs a client for a DAP task using the Prio3SumVec VDAF. Measurements are vectors of
* integers, as a <code>long[]</code> array of the given length. Valid measurements must have
* every integer be greater than or equal to zero, and less than <code>2 ^ bits</code>. The
* aggregate result is the element-wise sum of all measurements.
*
* @param leaderEndpoint the URI of the leader aggregator's HTTPS endpoint
* @param helperEndpoint the URI of the helper aggregator's HTTPS endpoint
* @param taskId the {@link TaskId} of the DAP task
* @param timePrecisionSeconds the time precision of the DAP task, in seconds
* @param length the length of measurement vectors. This is a parameter of
* the Prio3SumVec VDAF.
* @param bits the bit width of each element of the measurement vector.
* This is a parameter of the Prio3SumVec VDAF.
* @param chunkLength the chunk length internally used by the Prio3SumVec VDAF
* @return a client for the configured DAP task
* @throws IllegalArgumentException if the scheme of leaderEndpoint or helperEndpoint is not
* http or https, or if timePrecisionSeconds is not a positive
* number
*/
public static Client<long[]> createPrio3SumVec(
URI leaderEndpoint,
URI helperEndpoint,
Expand All @@ -99,6 +154,24 @@ public static Client<long[]> createPrio3SumVec(
);
}

/**
* Constructs a client for a DAP task using the Prio3Histogram VDAF. Measurements are bucket
* indexes, as <code>Long</code> integers. Valid measurements must be greater than or equal to
* zero, and less than the <code>length</code> parameter. The aggregate result counts how many
* times each bucket index appeared in a measurement.
*
* @param leaderEndpoint the URI of the leader aggregator's HTTPS endpoint
* @param helperEndpoint the URI of the helper aggregator's HTTPS endpoint
* @param taskId the {@link TaskId} of the DAP task
* @param timePrecisionSeconds the time precision of the DAP task, in seconds
* @param length the total number of histogram buckets. This is a parameter
* of the Prio3Histogram VDAF.
* @param chunkLength the chunk length internally used by the Prio3Histogram VDAF
* @return a client for the configured DAP task
* @throws IllegalArgumentException if the scheme of leaderEndpoint or helperEndpoint is not
* http or https, or if timePrecisionSeconds is not a positive
* number
*/
public static Client<Long> createPrio3Histogram(
URI leaderEndpoint,
URI helperEndpoint,
Expand All @@ -116,6 +189,15 @@ public static Client<Long> createPrio3Histogram(
);
}

/**
* Encodes a measurement into a DAP report, and submits it. This must not be called from the UI
* thread.
*
* @param measurement the measurement to be aggregated
* @throws IOException if requests to either aggregator fail
* @throws IllegalArgumentException if the measurement is of the wrong type
* @throws RuntimeException if there is an internal error while preparing the report
*/
public void sendMeasurement(M measurement) throws IOException {
HpkeConfigList leaderConfigList = this.fetchHPKEConfigList(this.leaderEndpoint, this.taskId);
HpkeConfigList helperConfigList = this.fetchHPKEConfigList(this.helperEndpoint, this.taskId);
Expand Down
13 changes: 10 additions & 3 deletions divviup/src/main/java/org/divviup/android/TaskId.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

import android.util.Base64;

/**
* A DAP task identifier. This is the unique identifier that clients, aggregators, and collectors
* use to distinguish between different kinds of measurements, and associate reports with a task.
* Objects of this class are immutable.
*/
public class TaskId {
private final byte[] bytes;

Expand All @@ -13,7 +18,7 @@ private TaskId(byte[] bytes) {
}

/**
* Encodes a task ID into its textual representation.
* Encodes this task ID into its textual representation.
*
* @return the task ID in un-padded base64url form
*/
Expand All @@ -27,8 +32,10 @@ public String encodeToString() {
/**
* Parses a task ID from its textual representation, as seen in DAP URLs.
*
* @param input the task ID in un-padded base64url form
* @return the task ID
* @param input the task ID in un-padded base64url form
* @return the task ID
* @throws IllegalArgumentException if the input is not a valid un-padded base64url value, or if
* it does not decode to 32 bytes
*/
public static TaskId parse(String input) {
byte[] bytes = Base64.decode(
Expand Down
9 changes: 9 additions & 0 deletions divviup/src/main/java/org/divviup/android/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* An Android client library for the <a
* href="https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/">Distributed
* Aggregation Protocol</a>.
* <p>
* This library is developed and maintained by <a href="https://divviup.org/">Divvi Up</a>, a
* project of the <a href="https://www.abetterinternet.org/">Internet Security Research Group</a>.
*/
package org.divviup.android;
Loading