The Implementation of the Method Used in the NHSX App

The NHSX Contact Tracing App uses ECIES to send Bob’s identifier to the Health Authority (HA). Basically the HA creates a unique…

The Implementation of the Method Used in the NHSX App

The NHSX Contact Tracing App uses ECIES to send Bob’s identifier to the Health Authority (HA). Initially the HA creates a unique InstallationID for Bob, and sends their public key (PubHA). Bob then creates a new key pair every day (PubBobD, PrivBobD). Bob then creates a secret Z using the HA’s public key and Bob’s daily private key. This is then used to create an AES encryption key in order to pass Bob’s InstallationID. When received by the HA, the HA will take Bob’s daily public key, and its private key, and creates the same secret (Z). This is then used to create the encryption key used by Bob. I have implemented the method here:

And here is a demo:

The method used is defined next.

Broadcast Value

The values broadcasted by Bob (BroadcastValues) uses the public key sent within the registration process. Each day the device creates a new ephemeral private key on an elliptic curve (P256):

PrivKeyD (daily) = r

PubKeyD (daily) = rG

and where G is the base point on the P-256 elliptic curve. The secret is then:

Z = ECDH (PubServer, PrivKeyD)

This is the elliptic curve Diffie Hellman and creates a key exchange. Next, a key is generated using X9.63 KDF and SHA-256 to give two 128-bit values (and where we split the result into two parts (Key and IV):

Key, IV = KDF(Z,rG)

The payload for the message is then:

m = (Start Date) || (End Date) || (InstallationID) || (Country Code)

and where InstallationID is a 128-bit unique identifier for the person. It is then encrypted with AES (GCM) to give:

Cipher, IntCheck = AES(m,IV)

where IV is the initialisation vector (salt) used, and IntCheck is the integrity check. The broadcast value to the device is then:

BV=(Country Code||PubKeyD||C|| ICV)

and where || is a concatenation. This gives a 856-bit broadcast value. This broadcast value will change every day, and where the daily secret is stored on the server:

Only the server has the private key for the public key (PublickeyS), and only it (and Bob) will be able to determine Z.

When the BV is received by Alice and is based onto the central server. The central server will take the public key (PublicKeyD) and then derive Z, and then generate the same encryption key that Bob used. We thus generate a BV every day and a new PublicKeyD. When there is a connection, Bob sends:

P = (BV || TxPower || TxTime || Auth)

and where TxPower is the power of the sender in dBm, TxTime is the transmission time stamp, and Auth is the HMAC relates to he other contents in the payload and keyed using the sending device’s symmetric authentication key. When received, the server can then extract the daily public key (PubKeyD) and then use this with the ECDH method to derive the shared secret (Z). Once we have this, we can then determine the key used to encrypt the message: