User notifications can have different “severity levels”. Some of which are informational and others are meant to communicate a “call to action” to the receiving Guest. Depending on the severity level, notifications/warnings are generated automatically by the Luca Server or require a manual action by a Health Department. The table provides an overview of the notification/warning levels available in luca.
#1 - Data Access Notification
#2 - Potential Risk of Infection
Informs all Guests of a venue in a determined time span about their potential risk of infection. Asks Guests to behave responsibly, reduce their face-to-face meetings and get tested. The notification contains contact details of the issuing Health Department.
#3 - Increased Risk of Infection 1
Warns specific Traced Guests that a Health Department determined an increased risk of infection for them. Asks Guests to behave responsibly, reduce their face-to-face meetings and get tested. The notification contains contact details of the issuing Health Department.
#4 - Infection Cluster Warning 1
To implement the above-described notifications and warnings in a privacy-preserving manner, the Luca Server publishes a list of hashed trace IDs affected by contact tracing activities of Health Departments. Guest Apps download this list on a regular basis and check their recently used trace IDs (which the app keeps track of locally) against them.
If the Guest App finds a match locally, it informs the Guest that one of their Check-Ins was involved in an infection event, whether they are advised to act on the notification and (if applicable) which Health Department (with direct contact details) is responsible for the notification.
As the notification lists are publicly available, the utilized hashing mechanism must ensure that no uninvolved party learns the association between Guest, Health Department, Check-In, severity level and venue.
Notification List Construction¶
The outlined notification list contains keyed hashes that are constructed as follows:
hash = HMAC-SHA256(key=traceID, data=healthDepartmentId + severityLevel).truncate(16)
traceID is the ID of the Check-In to be warned,
healthDepartmentId references the Health Department responsible for the warning and the
severityLevel substantiates the notification type. All hashes are truncated to 16 bytes.
The result is a flat list of 16 byte hashes published by the Luca Server that is updated whenever new notification hashes are generated. Each individual hash is removed from the list after a life time of 28 days. To save bandwidth, the notification list might be paginated based either on time slices and/or a maximum page size.
Notification List Lookup¶
Each Guest App occasionally fetches the updates of the notification list to detect notification hashes addressed to it.
To do that, the Guest App must generate hashes for all combinations of locally stored Check-Ins, all existing
healthDepartmentIds and all supported severity levels (currently: 1-4).
The results are individually compared to the latest notification list. If any combination matches the list, the Guest App learns which Check-In, Health Department and severity level is responsible for the warning and warns the Guest accordingly.
Secrecy of Trace ID and Privacy Guarantees¶
The notification list is public and can be fetched by anyone. An attacker with access to a specific trace ID can therefore perform the necessary hash calculations and lookups to detect and interpret warnings for this specific trace ID.
The trace ID is a 128bit pseudo-random string that can neither be efficiently guessed nor is it publicly shared by the Luca Server or other components in any way. Despite the trace IDs referencing a specific Check-In on the Luca Server, it does not bear any personal information of the Guest that created the Check-In.
By design, the Venue Owner Frontend and the Scanner Frontend might learn about some or all of the trace IDs associated to the venue. In the very most cases, venue owners will have become aware of infection cases in their venues anyway; hence, they do not gain new information from warnings issued for their own venue.
Finally, the trace IDs generated via static badges are enumerable by anyone with knowledge of the Badge’s QR code. Hence, in particular, the Scanner Frontends that performed Check-Ins for the static Badge. As static Badges obviously won’t benefit from dynamic notifications anyway, Check-Ins with static Badges do not emit any notification list entries.
Given the above discussion, we assume the trace ID generated by the Guest App as a reasonably private information to use as a secret for the above-described keyed hash. Without the knowledge of the 128 bit trace ID no meaningful information regarding Guests, Health Departments or Venues can be retrieved from the public notification list.
Access Notification List reveals the Number of Traced IDs¶
The number of hashed trace IDs in the above-described notification list allows an estimate on how many trace IDs were warned by Health Departments across Germany in the last weeks. Given that many Health Departments participate in the luca system no association to individual Health Departments is possible, though.