This page describes tests a provider can write to verify the cryptographic components of their provider implementation.
Google recommends implementing these tests early to ease Fast Pair integration.
Test Cases
These cases cover:
- Hashing
- The Bloom Filter
- AES Encryption and Public Key Exchange
- Message enciphering and deciphering
SHA-256 Hashing
Input value:
0
x11
,
0
x22
,
0
x33
,
0
x44
,
0
x55
,
0
x66
Hashed result:
0
xBB
,
0
x00
,
0
x0D
,
0
xDD
,
0
x92
,
0
xA0
,
0
xA2
,
0
xA3
,
0
x46
,
0
xF0
,
0
xB5
,
0
x31
,
0
xF2
,
0
x78
,
0
xAF
,
0
x06
,
0
xE3
,
0
x70
,
0
xF8
,
0
x69
,
0
x32
,
0
xCC
,
0
xAF
,
0
xCC
,
0
xC8
,
0
x92
,
0
xD6
,
0
x8D
,
0
x35
,
0
x0F
,
0
x80
,
0
xF8
AES Encryption
Input value:
0
xF3
,
0
x0F
,
0
x4E
,
0
x78
,
0
x6C
,
0
x59
,
0
xA7
,
0
xBB
,
0
xF3
,
0
x87
,
0
x3B
,
0
x5A
,
0
x49
,
0
xBA
,
0
x97
,
0
xEA
Secret key:
0
xA0
,
0
xBA
,
0
xF0
,
0
xBB
,
0
x95
,
0
x1F
,
0
xF7
,
0
xB6
,
0
xCF
,
0
x5E
,
0
x3F
,
0
x45
,
0
x61
,
0
xC3
,
0
x32
,
0
x1D
Encrypted output:
0
xAC
,
0
x9A
,
0
x16
,
0
xF0
,
0
x95
,
0
x3A
,
0
x3F
,
0
x22
,
0
x3D
,
0
xD1
,
0
x0C
,
0
xF5
,
0
x36
,
0
xE0
,
0
x9E
,
0
x9C
ECDH Key Exchange
Bob's private key:
0
x02
,
0
xB4
,
0
x37
,
0
xB0
,
0
xED
,
0
xD6
,
0
xBB
,
0
xD4
,
0
x29
,
0
x06
,
0
x4A
,
0
x4E
,
0
x52
,
0
x9F
,
0
xCB
,
0
xF1
,
0
xC4
,
0
x8D
,
0
x0D
,
0
x62
,
0
x49
,
0
x24
,
0
xD5
,
0
x92
,
0
x27
,
0
x4B
,
0
x7E
,
0
xD8
,
0
x11
,
0
x93
,
0
xD7
,
0
x63
Bob's public key:
0
xF7
,
0
xD4
,
0
x96
,
0
xA6
,
0
x2E
,
0
xCA
,
0
x41
,
0
x63
,
0
x51
,
0
x54
,
0
x0A
,
0
xA3
,
0
x43
,
0
xBC
,
0
x69
,
0
x0A
,
0
x61
,
0
x09
,
0
xF5
,
0
x51
,
0
x50
,
0
x06
,
0
x66
,
0
xB8
,
0
x3B
,
0
x12
,
0
x51
,
0
xFB
,
0
x84
,
0
xFA
,
0
x28
,
0
x60
,
0
x79
,
0
x5E
,
0
xBD
,
0
x63
,
0
xD3
,
0
xB8
,
0
x83
,
0
x6F
,
0
x44
,
0
xA9
,
0
xA3
,
0
xE2
,
0
x8B
,
0
xB3
,
0
x40
,
0
x17
,
0
xE0
,
0
x15
,
0
xF5
,
0
x97
,
0
x93
,
0
x05
,
0
xD8
,
0
x49
,
0
xFD
,
0
xF8
,
0
xDE
,
0
x10
,
0
x12
,
0
x3B
,
0
x61
,
0
xD2
Alice's private key:
0
xD7
,
0
x5E
,
0
x54
,
0
xC7
,
0
x7D
,
0
x76
,
0
x24
,
0
x89
,
0
xE5
,
0
x7C
,
0
xFA
,
0
x92
,
0
x37
,
0
x43
,
0
xF1
,
0
x67
,
0
x77
,
0
xA4
,
0
x28
,
0
x3D
,
0
x99
,
0
x80
,
0
x0B
,
0
xAC
,
0
x55
,
0
x58
,
0
x48
,
0
x38
,
0
x93
,
0
xE5
,
0
xB0
,
0
x6D
Alice's public key:
0
x36
,
0
xAC
,
0
x68
,
0
x2C
,
0
x50
,
0
x82
,
0
x15
,
0
x66
,
0
x8F
,
0
xBE
,
0
xFE
,
0
x24
,
0
x7D
,
0
x01
,
0
xD5
,
0
xEB
,
0
x96
,
0
xE6
,
0
x31
,
0
x8E
,
0
x85
,
0
x5B
,
0
x2D
,
0
x64
,
0
xB5
,
0
x19
,
0
x5D
,
0
x38
,
0
xEE
,
0
x7E
,
0
x37
,
0
xBE
,
0
x18
,
0
x38
,
0
xC0
,
0
xB9
,
0
x48
,
0
xC3
,
0
xF7
,
0
x55
,
0
x20
,
0
xE0
,
0
x7E
,
0
x70
,
0
xF0
,
0
x72
,
0
x91
,
0
x41
,
0
x9A
,
0
xCE
,
0
x2D
,
0
x28
,
0
x14
,
0
x3C
,
0
x5A
,
0
xDB
,
0
x2D
,
0
xBD
,
0
x98
,
0
xEE
,
0
x3C
,
0
x8E
,
0
x4F
,
0
xBF
Generated shared key (either Alice's public + Bob's private or Bob's public + Alice's private):
0
x9D
,
0
xAD
,
0
xE4
,
0
xF8
,
0
x6A
,
0
xC3
,
0
x48
,
0
x8B
,
0
xBA
,
0
xC2
,
0
xAC
,
0
x34
,
0
xB5
,
0
xFE
,
0
x68
,
0
xA0
,
0
xEE
,
0
x5A
,
0
x67
,
0
x06
,
0
xF5
,
0
x43
,
0
xD9
,
0
x06
,
0
x1A
,
0
xD5
,
0
x78
,
0
x89
,
0
x49
,
0
x8A
,
0
xE6
,
0
xBA
AES Key from ECDH Shared Secret
This is step 1b (AES key generation) in the GATT procedure .
ECDH shared key:
0
x9D
,
0
xAD
,
0
xE4
,
0
xF8
,
0
x6A
,
0
xC3
,
0
x48
,
0
x8B
,
0
xBA
,
0
xC2
,
0
xAC
,
0
x34
,
0
xB5
,
0
xFE
,
0
x68
,
0
xA0
,
0
xEE
,
0
x5A
,
0
x67
,
0
x06
,
0
xF5
,
0
x43
,
0
xD9
,
0
x06
,
0
x1A
,
0
xD5
,
0
x78
,
0
x89
,
0
x49
,
0
x8A
,
0
xE6
,
0
xBA
Generated AES key:
0
xB0
,
0
x7F
,
0
x1F
,
0
x17
,
0
xC2
,
0
x36
,
0
xCB
,
0
xD3
,
0
x35
,
0
x23
,
0
xC5
,
0
x15
,
0
xF3
,
0
x50
,
0
xAE
,
0
x57
Bloom Filter
Random salt:
0
xC7C8
First account key added to the filter (combine with the above random salt):
0
x11
,
0
x22
,
0
x33
,
0
x44
,
0
x55
,
0
x66
,
0
x77
,
0
x88
,
0
x99
,
0
x00
,
0
xAA
,
0
xBB
,
0
xCC
,
0
xDD
,
0
xEE
,
0
xFF
Resulting bloom filter:
0
x02
,
0
x0C
,
0
x80
,
0
x2A
Battery data (if it is contained in the advertisement):
0
b00110011
,
//
len
gth
=
3
,
show
UI
indication
.
0
b01000000
,
//
left
bud
:
not
charging
,
battery
level
=
64.
0
b01000000
,
//
right
bud
:
not
charging
,
battery
level
=
64.
0
b01000000
//
case
:
not
charging
,
battery
level
=
64.
Resulting bloom filter with battery data:
0
x01
,
0
x01
,
0
x46
,
0
x0A
Second account key added to the filter (combine with the above random salt):
0
x11
,
0
x11
,
0
x22
,
0
x22
,
0
x33
,
0
x33
,
0
x44
,
0
x44
,
0
x55
,
0
x55
,
0
x66
,
0
x66
,
0
x77
,
0
x77
,
0
x88
,
0
x88
Resulting bloom filter from both added account keys:
0
x84
,
0
x4A
,
0
x62
,
0
x20
,
0
x8B
Battery data (if it is contained in the advertisement):
0
b00110011
,
//
len
gth
=
3
,
show
UI
indication
.
0
b01000000
,
//
left
bud
:
not
charging
,
battery
level
=
64.
0
b01000000
,
//
right
bud
:
not
charging
,
battery
level
=
64.
0
b01000000
//
case
:
not
charging
,
battery
level
=
64.
Resulting bloom filter from both added account keys with battery data:
0
x46
,
0
x15
,
0
x24
,
0
xD0
,
0
x08
AES-CTR Encryption
Input data: "Someone's Google Headphone" with utf-8 encoding
0
x53
,
0
x6F
,
0
x6D
,
0
x65
,
0
x6F
,
0
x6E
,
0
x65
,
0
x27
,
0
x73
,
0
x20
,
0
x47
,
0
x6F
,
0
x6F
,
0
x67
,
0
x6C
,
0
x65
,
0
x20
,
0
x48
,
0
x65
,
0
x61
,
0
x64
,
0
x70
,
0
x68
,
0
x6F
,
0
x6E
,
0
x65
Secret key:
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
,
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
Nonce:
0
x00
,
0
x01
,
0
x02
,
0
x03
,
0
x04
,
0
x05
,
0
x06
,
0
x07
Expected encryption result:
0
xEE
,
0
x4A
,
0
x24
,
0
x83
,
0
x73
,
0
x80
,
0
x52
,
0
xE4
,
0
x4E
,
0
x9B
,
0
x2A
,
0
x14
,
0
x5E
,
0
x5D
,
0
xDF
,
0
xAA
,
0
x44
,
0
xB9
,
0
xE5
,
0
x53
,
0
x6A
,
0
xF4
,
0
x38
,
0
xE1
,
0
xE5
,
0
xC6
HMAC-SHA256
Input data:
0
x00
,
0
x01
,
0
x02
,
0
x03
,
0
x04
,
0
x05
,
0
x06
,
0
x07
,
0
xEE
,
0
x4A
,
0
x24
,
0
x83
,
0
x73
,
0
x80
,
0
x52
,
0
xE4
,
0
x4E
,
0
x9B
,
0
x2A
,
0
x14
,
0
x5E
,
0
x5D
,
0
xDF
,
0
xAA
,
0
x44
,
0
xB9
,
0
xE5
,
0
x53
,
0
x6A
,
0
xF4
,
0
x38
,
0
xE1
,
0
xE5
,
0
xC6
Secret key:
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
,
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
Expected HMAC-SHA256 result:
0
x55
,
0
xEC
,
0
x5E
,
0
x60
,
0
x55
,
0
xAF
,
0
x6E
,
0
x92
,
0
x61
,
0
x8B
,
0
x7D
,
0
x87
,
0
x10
,
0
xD4
,
0
x41
,
0
x37
,
0
x09
,
0
xAB
,
0
x5D
,
0
xA2
,
0
x7C
,
0
xA2
,
0
x6A
,
0
x66
,
0
xF5
,
0
x2E
,
0
x5A
,
0
xD4
,
0
xE8
,
0
x20
,
0
x90
,
0
x52
Encode personalized name to additional data packet
Input data: "Someone's Google Headphone" with utf-8 encoding
0
x53
,
0
x6F
,
0
x6D
,
0
x65
,
0
x6F
,
0
x6E
,
0
x65
,
0
x27
,
0
x73
,
0
x20
,
0
x47
,
0
x6F
,
0
x6F
,
0
x67
,
0
x6C
,
0
x65
,
0
x20
,
0
x48
,
0
x65
,
0
x61
,
0
x64
,
0
x70
,
0
x68
,
0
x6F
,
0
x6E
,
0
x65
Secret key:
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
,
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
Nonce:
0
x00
,
0
x01
,
0
x02
,
0
x03
,
0
x04
,
0
x05
,
0
x06
,
0
x07
Expected additional data packet:
0
x55
,
0
xEC
,
0
x5E
,
0
x60
,
0
x55
,
0
xAF
,
0
x6E
,
0
x92
,
0
x00
,
0
x01
,
0
x02
,
0
x03
,
0
x04
,
0
x05
,
0
x06
,
0
x07
,
0
xEE
,
0
x4A
,
0
x24
,
0
x83
,
0
x73
,
0
x80
,
0
x52
,
0
xE4
,
0
x4E
,
0
x9B
,
0
x2A
,
0
x14
,
0
x5E
,
0
x5D
,
0
xDF
,
0
xAA
,
0
x44
,
0
xB9
,
0
xE5
,
0
x53
,
0
x6A
,
0
xF4
,
0
x38
,
0
xE1
,
0
xE5
,
0
xC6
Decode additional data packet to get personalized name
Input data:
0
x55
,
0
xEC
,
0
x5E
,
0
x60
,
0
x55
,
0
xAF
,
0
x6E
,
0
x92
,
0
x00
,
0
x01
,
0
x02
,
0
x03
,
0
x04
,
0
x05
,
0
x06
,
0
x07
,
0
xEE
,
0
x4A
,
0
x24
,
0
x83
,
0
x73
,
0
x80
,
0
x52
,
0
xE4
,
0
x4E
,
0
x9B
,
0
x2A
,
0
x14
,
0
x5E
,
0
x5D
,
0
xDF
,
0
xAA
,
0
x44
,
0
xB9
,
0
xE5
,
0
x53
,
0
x6A
,
0
xF4
,
0
x38
,
0
xE1
,
0
xE5
,
0
xC6
Secret key:
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
,
0
x01
,
0
x23
,
0
x45
,
0
x67
,
0
x89
,
0
xAB
,
0
xCD
,
0
xEF
Expected name: "Someone's Google Headphone" with utf-8 encoding
0
x53
,
0
x6F
,
0
x6D
,
0
x65
,
0
x6F
,
0
x6E
,
0
x65
,
0
x27
,
0
x73
,
0
x20
,
0
x47
,
0
x6F
,
0
x6F
,
0
x67
,
0
x6C
,
0
x65
,
0
x20
,
0
x48
,
0
x65
,
0
x61
,
0
x64
,
0
x70
,
0
x68
,
0
x6F
,
0
x6E
,
0
x65
Encrypted connection status field
Field length and type:
0
b001100101
(
len
gth
=
3
,
type
=
connection
status
field
)
Connection state:
0
b10000101
:
*
on
head
detection
=
1
*
connection
availability
=
0
*
focus
mode
=
0
*
auto
-
reconnected
=
0
*
connection
state
=
0
x5
(
A2DP
with
AVRCP
)
Custom data:
0
x38
Connected devices bitmap:
0
b00001001
Connection status field raw data (combine above 4 bytes):
0
x35853809
In use account key (this is the Key):
0
x04
,
0
x22
,
0
x33
,
0
x44
,
0
x55
,
0
x66
,
0
x77
,
0
x88
,
0
x99
,
0
x00
,
0
xAA
,
0
xBB
,
0
xCC
,
0
xDD
,
0
xEE
,
0
xFF
Non-in use account key:
0
x04
,
0
x11
,
0
x22
,
0
x22
,
0
x33
,
0
x33
,
0
x44
,
0
x44
,
0
x55
,
0
x55
,
0
x66
,
0
x66
,
0
x77
,
0
x77
,
0
x88
,
0
x88
Random salt:
0
xC7C8
Account key filter (this is IV): this is generated by changing the first byte of in use account key from 0b00000100 to 0b00000110.
0
x8C
,
0
xA9
,
0
x0C
,
0
x08
,
0
x1C
Encrypted connection status field:
0
xF4
,
0
xBB
,
0
x40
,
0
x6F