Skip to content

Commit 2264e71

Browse files
Merge pull request #217 from w3c/encrypt-dap
Encryption for DAP
2 parents d18a166 + c68932f commit 2264e71

File tree

1 file changed

+156
-21
lines changed

1 file changed

+156
-21
lines changed

api.bs

Lines changed: 156 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ and impressions are not scoped to a single aggregation service.
507507
</div>
508508

509509
<xmp class=idl>
510-
enum PrivateAttributionAggregationProtocol { "dap-12-histogram", "tee-00" };
510+
enum PrivateAttributionAggregationProtocol { "dap-15-histogram", "tee-00" };
511511

512512
dictionary AttributionAggregationService {
513513
required DOMString protocol;
@@ -547,7 +547,7 @@ The <dfn enum>PrivateAttributionAggregationProtocol</dfn> describes the submissi
547547
used by different [=aggregation services=]. This document defines two protocols:
548548

549549
<dl dfn-for=PrivateAttributionAggregationProtocol dfn-type=enum-value>
550-
<dt><dfn>dap-12-histogram</dfn></dt>
550+
<dt><dfn>dap-15-histogram</dfn></dt>
551551
<dd>A DAP-based protocol [[DAP]] that uses [=MPC=]; see [[#s-mpc]].</dd>
552552
<dt><dfn>tee-00</dfn></dt>
553553
<dd>A protocol for submission to a [=TEE=]; see [[#s-tee]].</dd>
@@ -1431,8 +1431,18 @@ The <dfn method for=Attribution>measureConversion(|options|)</dfn> method steps
14311431
1. If the Attribution API is [[#opt-out|enabled]], set |report| to the
14321432
result of [=do attribution and fill a histogram=] with |validatedOptions|,
14331433
|topLevelSite|, |intermediarySite|, and |now|.
1434-
1. Let |encryptedReport| be the result of encrypting |report|.
1435-
<!-- TODO: Define "encrypting" -->
1434+
1. Let |aggregationService| be |validatedOptions|'s [=validated conversion options/aggregation service=].
1435+
1. Switch on the value of |aggregationService|.{{AttributionAggregationService/protocol}}:
1436+
<dl class="switch">
1437+
: <a enum-value for=PrivateAttributionAggregationProtocol>`dap-15-histogram`</a>
1438+
:: Perform the following steps:
1439+
1. Let |encryptedReport| be the result of invoking <a>construct a DAP report</a>,
1440+
given |validatedOptions|, |topLevelSite|, |now|, and |report|.
1441+
1442+
: <a enum-value for=PrivateAttributionAggregationProtocol>`tee-00`</a>
1443+
:: Perform the following steps:
1444+
1. TODO: see [#130](https://github.com/w3c/ppa/issues/130)
1445+
</dl>
14361446
1. Let |result| be a {{AttributionConversionResult}} with the following items:
14371447
: {{AttributionConversionResult/report}}
14381448
:: |encryptedReport|
@@ -1446,7 +1456,7 @@ The <dfn method for=Attribution>measureConversion(|options|)</dfn> method steps
14461456

14471457
<div dfn-for="validated conversion options">
14481458
<pre class=simpledef>
1449-
<dfn>Aggregation Service</dfn>: A [=URL=].
1459+
<dfn>Aggregation Service</dfn>: An instance of {{AttributionAggregationService}}.
14501460
<dfn>Epsilon</dfn>: A finite positive number.
14511461
<dfn>Histogram Size</dfn>: A [=32-bit unsigned integer=].
14521462
<dfn>Lookback</dfn>: A positive [=duration=].
@@ -1465,6 +1475,9 @@ To <dfn>validate {{AttributionConversionOptions}}</dfn> |options|:
14651475
1. If <a attribute for=Attribution>aggregationServices</a> does not [=map/exist|contain=]
14661476
an [=map/entry=] with a [=map/key=] of |options|.{{AttributionConversionOptions/aggregationService}},
14671477
throw a {{ReferenceError}}.
1478+
1. Let |aggregationService| be the result of [=map/get|getting the value=]
1479+
from {{AttributionAggregationServices}},
1480+
given |options|.{{AttributionConversionOptions/aggregationService}}.
14681481
1. If |options|.{{AttributionConversionOptions/epsilon}}
14691482
is less than or equal to 0 or is greater than 4294,
14701483
throw a {{RangeError}}.
@@ -1507,7 +1520,7 @@ To <dfn>validate {{AttributionConversionOptions}}</dfn> |options|:
15071520
1. If any result in |impressionCallers| is failure, throw a {{"SyntaxError"}} {{DOMException}}.
15081521
1. Return a [=validated conversion options=] with the following fields:
15091522
: [=validated conversion options/Aggregation Service=]
1510-
:: |options|.{{AttributionConversionOptions/aggregationService}}
1523+
:: |aggregationService|
15111524
: [=validated conversion options/Epsilon=]
15121525
:: |options|.{{AttributionConversionOptions/epsilon}}
15131526
: [=validated conversion options/Histogram Size=]
@@ -1796,6 +1809,7 @@ To <dfn noexport>parse a `Save-Impression` header</dfn> given a [=header value=]
17961809
* [=Impression site=] for [=conversions=]
17971810
* [=impression/histogram index|Histogram indexes=]
17981811

1812+
17991813
# Aggregation # {#aggregation}
18001814

18011815
An <dfn>aggregation service</dfn> takes multiple pieces of attribution information
@@ -1858,7 +1872,7 @@ by either MPC operator.
18581872

18591873
### Prio and DAP ### {#prio}
18601874

1861-
The <a enum-value for=PrivateAttributionAggregationProtocol>"dap-12-histogram"</a>
1875+
The <a enum-value for=PrivateAttributionAggregationProtocol>`dap-15-histogram`</a>
18621876
aggregation method uses Prio [[PRIO]]
18631877
and the Distributed Aggregation Protocol (DAP) [[DAP]].
18641878
Specifically, this aggregation method uses
@@ -1902,26 +1916,147 @@ as close to 2<sup><var>n</var></sup> − 1 as other constraints allow.
19021916
Several extensions to DAP [[DAP-EXT]] are necessary for this application:
19031917

19041918
* [[DAP-EXT#name-late-task-binding|Late task binding]]
1919+
(`late_binding`)
19051920
improves the ability of a site to collect reports
19061921
and aggregate them as needed.
19071922

1908-
* [[DAP-EXT#name-requester-website-identity|Website identity]]
1923+
* [[DAP-EXT#name-privacy-budget-consumption|Privacy budget]]
1924+
(`privacy_budget`)
1925+
ensures that the aggregation service does not aggregate reports
1926+
that received less privacy budget
1927+
than the aggregation task was configured with.
1928+
1929+
* [[DAP-EXT#name-requester-website-identity|Requester identity]]
1930+
(`requester_identity`)
19091931
is critical to ensure
19101932
that differential privacy protections are effective.
19111933
This prevents a malicious actor
19121934
that is able to correlate user identity across multiple sites
19131935
from exceeding the sensitivity bounds for that user
19141936
by aggregating reports from multiple sites together.
19151937

1916-
* [[DAP-EXT#name-privacy-budget-consumption|Privacy budget consumption]]
1917-
ensures that the aggregation service does not aggregate reports
1918-
that received less privacy budget
1919-
than the aggregation task was configured with.
1920-
1921-
User agents MUST include all of these extensions
1938+
User agents include all of these extensions
19221939
in reports that they generate.
19231940

19241941

1942+
### Report Encryption For DAP ### {#encrypt-dap}
1943+
1944+
<div algorithm>
1945+
To <dfn>construct a DAP report</dfn>,
1946+
producing a [=byte sequence=] |report|,
1947+
given [=validated conversion options=] |options|,
1948+
[=site=] |topLevelSite|,
1949+
[=moment=] |now|,
1950+
and a [=list=] of [=integers=] |histogram|:
1951+
1952+
1. Let |field| be Field128,
1953+
as defined in [Section 6.1.3](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-15#section-6.1.3)
1954+
of [[VDAF]].
1955+
1956+
1. Let |length| be the [=list/size=] of |histogram|.
1957+
1958+
1. Let |bits| be the base-2 logarithm
1959+
of |options|.[=validated conversion options/max value=],
1960+
rounded toward positive Infinity.
1961+
1962+
1. Let |chunkLength| be the square root of (|bits| + 1) * |length|,
1963+
rounded to the nearest integer.
1964+
1965+
1. Let |vdaf| be a new PrioL1BoundSum VDAF [[PRIO-L1]] instance,
1966+
passing |field|, |length|, |bits|, and |chunkLength|.
1967+
1968+
1. Let |taskID| be the [=byte sequence=]
1969+
from the hex string `b13e8440f1cdb4da51eed3967e0a2652d27f5005bc35f751daf188b4b746708b`
1970+
[[DAP-EXT]].
1971+
1972+
1. Let |ctx| be the [=byte sequence=] formed by concatenating
1973+
the [=isomorphic encode|encoded=] string `dap-15`
1974+
and |taskID|,
1975+
as defined in [Section 4.5.2](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.2)
1976+
of [[DAP]].
1977+
1978+
1. Let |reportID| be 16 bytes sampled from a cryptographically-secure random source [[RFC4086]].
1979+
1980+
1. Let |rand| be 128 bytes sampled from a cryptographically-secure random source [[RFC4086]].
1981+
1982+
1. Let |publicShare|, |inputShares| be the result of invoking |vdaf|.[`shard()`](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf#section-4.1),
1983+
as defined in [Section 4.1](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-15#section-4.1)
1984+
of [[VDAF]],
1985+
with |ctx|, |histogram|, |reportID| (as the VDAF "nonce" parameter), and |rand|.
1986+
1987+
1. Let |time| be |now| as a [=duration=] since the [=Unix epoch=],
1988+
divided by a [=duration=] of 5 seconds.
1989+
<!-- TODO: confirm fixed time resolution -->
1990+
1991+
1. Let |extensions| be a [=map=] of [=16-bit unsigned integers=] to [=byte sequences=],
1992+
comprised of:
1993+
1994+
* The extension codepoint for [[DAP-EXT#name-late-task-binding|late task binding]],
1995+
mapped to an [=list/is empty|empty=] [=byte sequence=].
1996+
1997+
* The extension codepoint for [[DAP-EXT#name-privacy-budget-consumption|privacy budget]],
1998+
mapped to the value of |encodedEpsilon|, derived as follows:
1999+
2000+
1. Let |scaledEpsilon| be the [=32-bit unsigned integer=]
2001+
that is |options|.[=validated conversion options/epsilon=],
2002+
multiplied by 1,000,000, then rounded toward positive Infinity.
2003+
2004+
1. Let |encodedEpsilon| be the result of invoking
2005+
[`NumericToRawBytes`](https://tc39.es/ecma262/multipage/structured-data.html#sec-numerictorawbytes)
2006+
with [UINT32](https://tc39.es/ecma262/multipage/indexed-collections.html#table-the-typedarray-constructors), |scaledEpsilon|, and `false` (for `isLittleEndian`).
2007+
2008+
* The extension codepoint for [[DAP-EXT#name-requester-website-identity|requester identity]],
2009+
mapped to the [=isomorphic encode|encoded=] value of |topLevelSite|[1].
2010+
2011+
1. Let |reportMetadata| be encoded DAP [`ReportMetadata`](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.2)
2012+
generated from |reportID|, |time|, and |extensions|.
2013+
2014+
1. Let |encryptedInputShares| be an [=list/is empty|empty=] [=list=].
2015+
2016+
1. [=list/iterate|For each=] |share| of |inputShares|,
2017+
follow the method for encrypting shares
2018+
described in [Section 4.5.2](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.2):
2019+
2020+
1. Let |pkR| be the public key of the corresponding role from
2021+
the [=aggregation service=] [HPKE configuration](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.1)
2022+
obtained for the [=aggregation service=]
2023+
indicated by |options|.[=validated conversion options/Aggregation Service=].
2024+
2025+
<p class=note>The URL for <a enum-value for=PrivateAttributionAggregationProtocol>"dap-15-histogram"</a> is expected to identify the DAP Leader role.
2026+
Implementations need to obtain HPKE configuration for both Aggregators statically.
2027+
The HPKE configuration <span class=allow-2119>must not</span> be fetched on demand, as the time that takes
2028+
will leak information to callers of <a method for=Attribution>measureConversion()</a>.
2029+
2030+
1. Let |serverRole| be 2 for the first item (the Leader)
2031+
and 3 for the second (the Helper role).
2032+
2033+
1. Let |info| be the [=byte sequence=] formed by concatenating:
2034+
the [=isomorphic encode|encoded=] value of the string `dap-15 input share`,
2035+
a byte with the value 0x01, and |serverRole|.
2036+
2037+
1. Let |inputShareAAD| be constructed from
2038+
|taskID|, |reportMetadata|, and |publicShare|,
2039+
following the structure for [`InputShareAad`](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.2).
2040+
2041+
1. Let |hpke| be an HPKE [[RFC9180]] configuration
2042+
that is based on the same [HPKE configuration](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.1).
2043+
2044+
1. Let |encryptedShare| be the result of invoking |hpke|.[`Seal<mode_base>()`](https://hpkewg.github.io/hpke/draft-ietf-hpke-hpke.html#section-6.1),
2045+
passing |pkR|, |info|, |inputShareAAD|, and |share|.
2046+
2047+
1. [=list/Append=] |encryptedShare| to |encryptedInputShares|.
2048+
2049+
1. Let |report| be an encoded DAP [`Report`](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.2)
2050+
generated from |reportMetadata|, |publicShare|, |encryptedInputShares|
2051+
(the two values being the leader and helper encrypted input shares respectively),
2052+
and [=aggregation service=] [HPKE configuration](https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15#section-4.5.1)
2053+
obtained from the DAP aggregators.
2054+
2055+
1. Return |report|.
2056+
2057+
</div>
2058+
2059+
19252060
## Trusted Execution Environments ## {#s-tee}
19262061

19272062
A <dfn lt=TEE>Trusted Execution Environment (TEE)</dfn> uses specialized hardware
@@ -2762,18 +2897,18 @@ spec:structured header; type:dfn; urlPrefix: https://httpwg.org/specs/rfc9651;
27622897
"Eric Rescorla",
27632898
"Christopher A. Wood"
27642899
],
2765-
"date": "2024-10-10",
2766-
"href": "https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-12",
2900+
"date": "2024-04-29",
2901+
"href": "https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-15",
27672902
"title": "Distributed Aggregation Protocol for Privacy Preserving Measurement",
27682903
"publisher": "IETF"
27692904
},
27702905
"dap-ext": {
27712906
"authors": [
27722907
"Martin Thomson"
27732908
],
2774-
"title": "Distributed Aggregation Protocol (DAP) Extensions for Improved Application of Differential Privacy",
2775-
"date": "2024-10-18",
2776-
"href": "https://datatracker.ietf.org/doc/draft-thomson-ppm-dap-dp-ext/"
2909+
"title": "Distributed Aggregation Protocol (DAP) Report Binding Extensions",
2910+
"date": "2025-07-04",
2911+
"href": "https://datatracker.ietf.org/doc/html/draft-thomson-ppm-dap-dp-ext-02"
27772912
},
27782913
"dp": {
27792914
"authors": [
@@ -2868,8 +3003,8 @@ spec:structured header; type:dfn; urlPrefix: https://httpwg.org/specs/rfc9651;
28683003
"Phillipp Schoppmann"
28693004
],
28703005
"title": "Verifiable Distributed Aggregation Functions",
2871-
"date": "2024-10-04",
2872-
"href": "https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/"
3006+
"date": "2025-06-17",
3007+
"href": "https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-15"
28733008
}
28743009
}
28753010
</pre>

0 commit comments

Comments
 (0)