X9.42 test vectors are wrong
ANSI X9.42-2003 [1] describes a Key Derivation Function Based on Concatenation but the test vectors they provide in section D.5.1 are wrong.
We discovered this problem while implementing a key exchange program based on X9.42. Full credit should go to Wolfgang Ehrhardt for solving it.
The Problem
The text in X9.42 describes the basic key derivation formula using concatenation:
K = H( ZZ || Counter || OtherInfo )
This is correct and is what we use in the KXDH_DeriveKeyingData()
function and DeriveKeyingData
method in
our own software.
However, in their test vectors in Appendix D, the authors of X9.42 appear to be using the incorrect formula
K = H( ZZ || OtherInfo || Counter )
Details
This is an extract from ANSI X9.42:
D.5.1 Examples of the Key Derivation function Based on Concatenation D.5.1.1 Multiple Invocation Example This example demonstrates how multiple invocations of the key derivation process based on concatenation could result in the generation of key material for both HMAC and TDEA. Invocation 1: Generate bits for HMAC: scheme = dhHybrid2 (see calculation example from Section D.3.5.) ZZ = (Z_e || Z_s) = 5E10 B967 A956 0685 3E52 8F04 262A D18A 4767 C761 1639 7139 1E17 CB05 A216 68D4 CE2B 9F15 1617 4080 42CE 0919 5838 23FD 346D 1751 FBE2 341A F2EE 0461 B62F 100F FAD4 F723 F70C 18B3 8238 ED18 3E93 98C8 CA51 7EE0 CBBE FFF9 C594 71FE 2780 9392 4089 480D BC5A 38E9 A1A9 7D23 0381 0684 7D0D 22EC F85F 49A8 6182 1199 BAFC B0D7 4E6A CFFD 7D14 2765 EBF4 C712 414F E4B6 AB95 7F4C B466 B466 0128 9BB8 2060 4282 7284 2EE2 8F11 3CD1 1F39 431C BFFD 8232 54CE 472E 2105 E49B 3D7F 113B 8250 76E6 2645 8580 7BC4 6454 665F 27C5 E4E1 A4BD 0347 0486 3229 81FD C894 CCA1 E293 0987 C92C 15A3 8BC4 2EB3 8810 E867 C443 2F07 259E C00C DBBB 0FB9 9E17 27C7 06DA 58DD Recall the basic key derivation formula using concatenation: K = H( ZZ || Counter || OtherInfo ) OtherInfo = "HMAC Key" Calculate K for Counter = (00000001)_16 K_1 = H(ZZ || Counter || OtherInfo) = 95D6 41F4 2645 88E4 E2B6 E3E9 1345 62BC 1823 69EB
For the details of the algorithm, see the extract below.
Now, to our calculation, (ZZ || Counter || OtherInfo)
for Counter = 00000001 is the 268 bytes*:
5E10B967A95606853E528F04262AD18A 4767C761163971391E17CB05A21668D4 CE2B9F151617408042CE0919583823FD 346D1751FBE2341AF2EE0461B62F100F FAD4F723F70C18B38238ED183E9398C8 CA517EE0CBBEFFF9C59471FE27809392 4089480DBC5A38E9A1A97D2303810684 7D0D22ECF85F49A861821199BAFCB0D7 4E6ACFFD7D142765EBF4C712414FE4B6 AB957F4CB466B46601289BB820604282 72842EE28F113CD11F39431CBFFD8232 54CE472E2105E49B3D7F113B825076E6 264585807BC46454665F27C5E4E1A4BD 03470486322981FDC894CCA1E2930987 C92C15A38BC42EB38810E867C4432F07 259EC00CDBBB0FB99E1727C706DA58DD 00000001484d4143204b6579assuming that "HMAC Key" is the 8-octet string
(0x)484d4143204b6579
,
so the value of K_1 should be
SHA-1(ZZ || Counter || OtherInfo) = bc98eb018cb00ee26d1f97a15ae166912a7ac4c5but X9.42 shows a different result of
95D6 41F4 2645 88E4 E2B6 E3E9 1345 62BC 1823 69EB
Similarly, for the same values of ZZ in D.5.1.1 Invocation 2
where OtherInfo = "TDEA Key"
= (0x)54444541204b6579
,
we input the 268 bytes*
5E10B967A95606853E528F04262AD18A ... 259EC00CDBBB0FB99E1727C706DA58DD 0000000154444541204b6579to the SHA-1 function to get
K_1 = 91df6ba74b2b634cab78715118309dc580fe8c4dcompared to the ANSI X9.42 version
K_1 = EA35 A6C8 84D2 4D73 4793 9E1F DA75 FD79 95CF D4AC
Likewise for D.5.1.2 where OtherInfo = "HMAC and TDEA Keys"
= (0x)484d414320616e642054444541204b657973
,
we input the 278 bytes*
5E10B967A95606853E528F04262AD18A ... 259EC00CDBBB0FB99E1727C706DA58DD 00000001484d414320616e6420544445 41204b657973to SHA-1 to get
K_1 = 87986e5d66b7b949431049cce68c6c174c001c46but X9.42 gives
F13D BE8D 2C11 526C 6F6E 0BAE 7C88 47AB 5FFA 5844
Extract from ANSI X9.42 Section 7.7.2 Key Derivation Function Based on Concatenation
Let hashlen denote the length of the output of the hash function chosen, and let maxhashlen denote the maximum length of the input to the hash function.
Prerequisites: An ASC X9-approved hash function H offering at least 80 bits of security.
Input:- ZZ: A bit string denoting the shared secret value. Depending on which key agreement scheme is executed, ZZ may be oct(Ze), oct(Zs), oct(Ze)||oct(Zs) or oct(ZMQV).
- keylen: An integer representing the length in bits of the keying data to be generated. This integer is less than (hashlen x (232-1)).
- (Optional) OtherInfo: A bit string consisting of some data shared by the two entities intended to share the secret value ZZ.
- Let d = ceil(keylen / hashlen).
- Initiate a 32-bit octet string Counter as (00000001)_16.
- For i = 1 to d,
- Compute hi = H (ZZ || Counter || [OtherInfo]) where hi denotes the hash value computed using the appropriate hash function.
- Convert Counter to an integer.
- Increment Counter.
- Convert Counter to an octet string.
- Increment i.
- Compute KeyingData = the leftmost keylen bits of h1||h2||...||hd.
- Output KeyingData.
Reference
- [1] ANSI X9.42-2003 Agreement of Symmetric Keys Using Discrete Logarithm Cryptography, American National Standards Institute, November 2003.
Contact
For more information, or to comment on this page, please send us a message.
This page last updated 9 September 2025.