J8k3 0da4c99a0c Fix PAN generation: random prefix within range, Mastercard series option
Two bugs in generateBrandPan:
1. For networks with multiple prefix rules, always picked the same rule
   (Mastercard always 2-series, AmEx always 37, Discover always 6011)
2. Always used the start of the range as the prefix, so Mastercard
   generated 51xxxxx or 2221xxxxxx every time instead of any value
   in 51-55 or 2221-2720

Fix both: pick a random prefix rule and a random prefix within start..end.

Add a "Mastercard series" arg to PAN Generate so callers can explicitly
request 5-series (51-55), 2-series (2221-2720), or leave it random.
The curated sample path is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:18:22 -04:00

847 lines
28 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Payment operation tests.
*
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
const ecdhPrivateKey = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVPecKErSPjan5fSz
f+jsKPKthv3Ao5N0IxkbatQNw16hRANCAARhg779GdYIpH0QnY66FmGX1nMFyybu
sjExdXFN15BBa1+zh1Cf7Cr484KJ8Mh2ga/Qs8qKk/8VbWSj0SbLb6Os
-----END PRIVATE KEY-----`;
const ecdhPrivateKeySec1 = `-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFT3nChK0j42p+X0s3/o7CjyrYb9wKOTdCMZG2rUDcNeoAoGCCqGSM49
AwEHoUQDQgAEYYO+/RnWCKR9EJ2OuhZhl9ZzBcsm7rIxMXVxTdeQQWtfs4dQn+wq
+POCifDIdoGv0LPKipP/FW1ko9Emy2+jrA==
-----END EC PRIVATE KEY-----`;
const ecdhPeerPublicKey = `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZWOfvFUyA5ITdtEUar7aAz308Llr
pPVK74bCKbeq3gIA5ZN0we6T18GSkTHtCCOG266YyCGTcE2JrnswYk1f8A==
-----END PUBLIC KEY-----`;
TestRegister.addTests([
{
name: "Parse Thales payShield command: header, LMK identifier, trailer",
input: "HEADHE0123456789ABCDEF0011223344556677%00TAIL",
expectedOutput: JSON.stringify({
rawInput: "HEADHE0123456789ABCDEF0011223344556677%00TAIL",
framing: {
stxPresent: true,
etxPresent: true,
endMessageDelimiterPresent: true
},
normalizedMessage: "HEADHE0123456789ABCDEF0011223344556677%00",
messageHeaderLength: 4,
messageHeader: "HEAD",
commandCode: "HE",
commandCodeType: "request",
commandNames: ["Encrypt Data Block"],
requestCodes: ["HE"],
expectedResponseCodes: ["HF"],
manualPages: [107],
payload: "0123456789ABCDEF0011223344556677",
payloadLength: 32,
lmkIdentifier: "00",
lmkIdentifierDelimiterPresent: true,
tildeDelimiterPresentBeforeLmkIdentifier: false,
messageTrailer: "TAIL",
notes: []
}, null, 4),
recipeConfig: [
{
op: "HSM Parse Thales Command",
args: [4]
}
]
},
{
name: "Parse Thales payShield command: trailing tilde before LMK identifier",
input: "MA0123456789ABCDEFHELLO~%12",
expectedOutput: JSON.stringify({
rawInput: "MA0123456789ABCDEFHELLO~%12",
framing: {
stxPresent: false,
etxPresent: false,
endMessageDelimiterPresent: false
},
normalizedMessage: "MA0123456789ABCDEFHELLO~%12",
messageHeaderLength: 0,
messageHeader: "",
commandCode: "MA",
commandCodeType: "request",
commandNames: ["Generate a MAC"],
requestCodes: ["MA"],
expectedResponseCodes: ["MB"],
manualPages: [90],
payload: "0123456789ABCDEFHELLO",
payloadLength: 21,
lmkIdentifier: "12",
lmkIdentifierDelimiterPresent: true,
tildeDelimiterPresentBeforeLmkIdentifier: true,
messageTrailer: "",
notes: []
}, null, 4),
recipeConfig: [
{
op: "HSM Parse Thales Command",
args: [0]
}
]
},
{
name: "Parse Futurex Excrypt command: bracketed fields",
input: "[AOGMAC;FS6;RV0011223344556677;]",
expectedOutput: JSON.stringify({
rawInput: "[AOGMAC;FS6;RV0011223344556677;]",
openingDelimiterPresent: true,
closingDelimiterPresent: true,
body: "AOGMAC;FS6;RV0011223344556677;",
rawFields: [
"AOGMAC",
"FS6",
"RV0011223344556677"
],
fields: [
{
raw: "AOGMAC",
tag: "AO",
value: "GMAC"
},
{
raw: "FS6",
tag: "FS",
value: "6"
},
{
raw: "RV0011223344556677",
tag: "RV",
value: "0011223344556677"
}
],
commandFieldTag: "AO",
commandCode: "GMAC",
commandName: "Generate Message Authentication Code",
fieldCount: 3,
notes: []
}, null, 4),
recipeConfig: [
{
op: "HSM Parse Futurex Command",
args: []
}
]
},
{
name: "Parse Futurex Excrypt command: missing closing delimiter",
input: "[AOVMAC;FS6;RV89ABCDEF",
expectedOutput: JSON.stringify({
rawInput: "[AOVMAC;FS6;RV89ABCDEF",
openingDelimiterPresent: true,
closingDelimiterPresent: false,
body: "AOVMAC;FS6;RV89ABCDEF",
rawFields: [
"AOVMAC",
"FS6",
"RV89ABCDEF"
],
fields: [
{
raw: "AOVMAC",
tag: "AO",
value: "VMAC"
},
{
raw: "FS6",
tag: "FS",
value: "6"
},
{
raw: "RV89ABCDEF",
tag: "RV",
value: "89ABCDEF"
}
],
commandFieldTag: "AO",
commandCode: "VMAC",
commandName: "Verify Message Authentication Code",
fieldCount: 3,
notes: [
"Message is missing one or both expected Excrypt outer delimiters."
]
}, null, 4),
recipeConfig: [
{
op: "HSM Parse Futurex Command",
args: []
}
]
},
{
name: "Parse TR-31 key block: fixed header only",
input: "D0016D0AB00E0000",
expectedOutput: JSON.stringify({
raw: "D0016D0AB00E0000",
fixedHeader: {
raw: "D0016D0AB00E0000",
versionId: "D",
versionDescription: "ANSI X9.24-2 (2017) — AES, Key Derivation Binding Method (current PCI standard)",
declaredBlockLength: 16,
keyUsage: "D0",
keyUsageDescription: "Symmetric Data Encryption Key (DEK)",
algorithm: "A",
algorithmDescription: "AES",
modeOfUse: "B",
modeOfUseDescription: "Both Encrypt and Decrypt / Both Generate and Verify",
keyVersionNumber: "00",
exportability: "E",
exportabilityDescription: "Exportable — can be wrapped under a KEK in a trusted key block",
optionalBlocksDeclared: 0,
reserved: "00"
},
compliance: [
"OK: Version D (AES Key Derivation) — current PCI-required format",
"NOTE: Exportable key — verify the wrapping KEK is a PCI-approved key block protection key"
],
optionalBlocks: [],
bodyOffset: 16,
remainingBody: "",
notes: []
}, null, 4),
recipeConfig: [
{
op: "TR-31 Parse Key Block",
args: [true]
}
]
},
{
name: "Parse TR-34 key transport: split sections",
input: "001730303030423930303100112233300030303034AABBCCDD",
expectedOutput: JSON.stringify({
declaredLength: 23,
actualLengthExcludingLengthField: 23,
header: "0000",
messageType: "B9",
messageDescription: "BindResponse — final key delivery; contains CMS EnvelopedData + signature",
errorCode: "00",
errorDescription: "Success",
authData: {
hex: "3100",
byteCount: 2,
asnOuter: null
},
kcvHex: "112233",
envelopeData: {
hex: "3000",
byteCount: 2,
description: "CMS EnvelopedData — wrapped symmetric key (decrypt with KRD private RSA key)",
asnOuter: {
tag: "0x30 (SEQUENCE)",
headerBytes: 2,
valueLength: 0,
totalExpected: 2,
complete: true
}
},
signatureLengthAscii: "0004",
signatureLength: 4,
signatureHex: "AABBCCDD",
trailingHex: "",
notes: []
}, null, 4),
recipeConfig: [
{
op: "TR-34 Parse Key Transport",
args: []
}
]
},
{
name: "Payment Calculate KCV: HMAC SHA-256",
input: "00112233445566778899AABBCCDDEEFF",
expectedOutput: "E8A065",
recipeConfig: [
{
op: "Payment Calculate KCV",
args: ["Hex", "HMAC SHA-256", 6]
}
]
},
{
name: "Payment Calculate KCV: AES-CMAC empty",
input: "00112233445566778899AABBCCDDEEFF",
expectedOutput: "917737",
recipeConfig: [
{
op: "Payment Calculate KCV",
args: ["Hex", "AES-CMAC (Empty)", 6]
}
]
},
{
name: "Payment Calculate KCV: AES-CMAC zeros",
input: "00112233445566778899AABBCCDDEEFF",
expectedOutput: "53E107",
recipeConfig: [
{
op: "Payment Calculate KCV",
args: ["Hex", "AES-CMAC (Zeros)", 6]
}
]
},
{
name: "Payment Calculate KCV: AES-CMAC ones",
input: "00112233445566778899AABBCCDDEEFF",
expectedOutput: "7B3046",
recipeConfig: [
{
op: "Payment Calculate KCV",
args: ["Hex", "AES-CMAC (Ones)", 6]
}
]
},
{
name: "Payment Calculate KCV: AES-ECB zeros",
input: "00112233445566778899AABBCCDDEEFF",
expectedOutput: "FDE4FB",
recipeConfig: [
{
op: "Payment Calculate KCV",
args: ["Hex", "AES-ECB (Zeros)", 6]
}
]
},
{
name: "DUKPT Derive TDES Key: known IPEK vector",
input: "0123456789ABCDEFFEDCBA9876543210",
expectedOutput: "6AC292FAA1315B4D858AB3A3D7D5933A",
recipeConfig: [
{
op: "DUKPT Derive TDES Key",
args: ["Derive IPEK", "FFFF9876543210E00008", "None", false]
}
]
},
{
name: "PIN Block Build: ISO Format 0",
input: "1234",
expectedOutput: "041215FEDCBA9876",
recipeConfig: [
{
op: "PIN Block Build",
args: ["ISO Format 0", "5432101234567890", false]
}
]
},
{
name: "PIN Block Parse: ISO Format 0",
input: "041215FEDCBA9876",
expectedOutput: JSON.stringify({
format: "ISO Format 0",
pin: "1234",
pinLength: 4,
pinFieldHex: "041234FFFFFFFFFF",
panFieldHex: "0000210123456789",
blockHex: "041215FEDCBA9876",
fillDigitsHex: "FFFFFFFFFF"
}, null, 4),
recipeConfig: [
{
op: "PIN Block Parse",
args: ["ISO Format 0", "5432101234567890"]
}
]
},
{
name: "PIN Block Translate: ISO Format 0 to ISO Format 1",
input: "041215FEDCBA9876",
expectedOutput: JSON.stringify({
source: {
format: "ISO Format 0",
pin: "1234",
pinLength: 4,
pinFieldHex: "041234FFFFFFFFFF",
panFieldHex: "0000210123456789",
blockHex: "041215FEDCBA9876",
fillDigitsHex: "FFFFFFFFFF"
},
target: {
format: "ISO Format 1",
blockHex: "141234FFFFFFFFFF"
}
}, null, 4),
recipeConfig: [
{
op: "PIN Block Translate",
args: ["ISO Format 0", "5432101234567890", "ISO Format 1", "", false]
}
]
},
{
name: "Card Validation Data Generate: known CVV2 sample",
input: "0123456789ABCDEFFEDCBA9876543210",
expectedOutput: "221",
recipeConfig: [
{
op: "Card Validation Data Generate",
args: ["CVV2 / CVC2 (force 000)", "4123456789012345", "02", "25", "MMYY", "101", 3, false]
}
]
},
{
name: "PAN Generate: Visa curated sample",
input: "",
expectedOutput: JSON.stringify({
brand: "Visa",
mode: "Curated sample",
pan: "4024140000000131",
source: "Public Visa test PAN published in Mastercard AVS scenario documentation.",
network: "Visa",
majorIndustryIdentifier: "4",
majorIndustryIdentifierDescription: "Banking and financial (Visa)",
issuerIdentificationNumber: "40241400",
length: 16,
luhnValid: true,
matchedRule: {
rangeStart: "4",
rangeEnd: "4",
lengths: [13, 16, 19],
description: "Visa cards begin with 4."
}
}, null, 4),
recipeConfig: [
{
op: "PAN Generate",
args: ["Visa", "Curated sample", 16, "Any", true]
}
]
},
{
name: "PAN Generate: American Express curated sample",
input: "",
expectedOutput: "371449635398431",
recipeConfig: [
{
op: "PAN Generate",
args: ["American Express", "Curated sample", 15, "Any", false]
}
]
},
{
name: "PAN Parse: Discover sample",
input: "6011000991543426",
expectedOutput: JSON.stringify({
pan: "6011000991543426",
network: "Discover",
cardType: "Credit",
cardTypeConfidence: "medium",
cardTypeNote: "The common Discover BIN ranges (6011, 644-649, 65, 622126-622925) are predominantly credit cards. Discover does offer some debit products on separate BIN ranges.",
majorIndustryIdentifier: "6",
majorIndustryIdentifierDescription: "Merchandising and banking (Discover, Maestro)",
issuerIdentificationNumber: "60110009",
length: 16,
luhnValid: true,
matchedRule: {
rangeStart: "6011",
rangeEnd: "6011",
lengths: [16, 17, 18, 19],
description: "Discover range 6011."
}
}, null, 4),
recipeConfig: [
{
op: "PAN Parse",
args: []
}
]
},
{
name: "Card Validation Data Verify: known CVV2 sample",
input: "0123456789ABCDEFFEDCBA9876543210",
expectedOutput: JSON.stringify({
profile: "CVV2 / CVC2 (force 000)",
pan: "4123456789012345",
expiry: "0225",
expiryLayout: "MMYY",
serviceCode: "000",
digitCount: 3,
inputDigits: "41234567890123450225000000000000",
resultHex: "D2D21E5FA3030D91",
decimalized: "22153",
validationData: "221",
expectedValue: "221",
valid: true
}, null, 4),
recipeConfig: [
{
op: "Card Validation Data Verify",
args: ["CVV2 / CVC2 (force 000)", "4123456789012345", "02", "25", "MMYY", "101", "221"]
}
]
},
{
name: "EMV Generate ARQC: AES-CMAC profile",
input: "000102030405060708090A0B0C0D0E0F",
expectedOutput: "C1F732B52FB20CAA",
recipeConfig: [
{
op: "EMV Generate ARQC",
args: ["00112233445566778899AABBCCDDEEFF", 8, false]
}
]
},
{
name: "EMV Generate ARPC: AES-CMAC profile",
input: "11223344556677889900AABBCCDDEEFF",
expectedOutput: "312442B1A4D64F94",
recipeConfig: [
{
op: "EMV Generate ARPC",
args: ["00112233445566778899AABBCCDDEEFF", 8, false]
}
]
},
{
name: "EMV Verify ARQC: AES-CMAC profile",
input: "000102030405060708090A0B0C0D0E0F",
expectedOutput: JSON.stringify({
inputHex: "000102030405060708090A0B0C0D0E0F",
outputBytes: 8,
fullMacHex: "C1F732B52FB20CAAB58D5B6C78CBD514",
cryptogramHex: "C1F732B52FB20CAA",
expectedArqcHex: "C1F732B52FB20CAA",
valid: true
}, null, 4),
recipeConfig: [
{
op: "EMV Verify ARQC",
args: ["00112233445566778899AABBCCDDEEFF", 8, "C1F732B52FB20CAA"]
}
]
},
{
name: "Payment Encrypt Data: AES CBC",
input: "00112233445566778899AABBCCDDEEFF",
expectedOutput: "67423557CA0509243B9EE04A5DA3448AA397F6D29B5C8BCE065D9CDC936B7F9B",
recipeConfig: [
{
op: "Payment Encrypt Data",
args: ["AES CBC", "00112233445566778899AABBCCDDEEFF", "000102030405060708090A0B0C0D0E0F", "", "Data", false]
}
]
},
{
name: "Payment Decrypt Data: AES CBC",
input: "67423557CA0509243B9EE04A5DA3448AA397F6D29B5C8BCE065D9CDC936B7F9B",
expectedOutput: "00112233445566778899AABBCCDDEEFF",
recipeConfig: [
{
op: "Payment Decrypt Data",
args: ["AES CBC", "00112233445566778899AABBCCDDEEFF", "000102030405060708090A0B0C0D0E0F", "", "Data", false]
}
]
},
{
name: "Payment Re-Encrypt Data: AES CBC to TDES CBC",
input: "67423557CA0509243B9EE04A5DA3448AA397F6D29B5C8BCE065D9CDC936B7F9B",
expectedOutput: "C47BC6E91A9D566F649D750BCE1CE9889FB5AE1489A16692",
recipeConfig: [
{
op: "Payment Re-Encrypt Data",
args: ["AES CBC", "00112233445566778899AABBCCDDEEFF", "000102030405060708090A0B0C0D0E0F", "", "Data", "TDES CBC", "0123456789ABCDEFFEDCBA9876543210", "1234567890ABCDEF", "", "Data", false]
}
]
},
{
name: "MAC Generate: AES-CMAC",
input: "1122334455667788",
expectedOutput: "339AF1AD1650E908",
recipeConfig: [
{
op: "MAC Generate",
args: ["Hex", "AES-CMAC", "00112233445566778899AABBCCDDEEFF", "Hex", "", "Method 1", 8, false]
}
]
},
{
name: "MAC Generate: HMAC SHA-256",
input: "1122334455667788",
expectedOutput: "9300E1D36DD30415",
recipeConfig: [
{
op: "MAC Generate",
args: ["Hex", "HMAC SHA-256", "00112233445566778899AABBCCDDEEFF", "Hex", "", "Method 1", 8, false]
}
]
},
{
name: "MAC Generate: DUKPT MAC Request CMAC",
input: "1122334455667788",
expectedOutput: "3616961727FE155D",
recipeConfig: [
{
op: "MAC Generate",
args: ["Hex", "DUKPT MAC Request CMAC", "0123456789ABCDEFFEDCBA9876543210", "Hex", "FFFF9876543210E00008", "Method 1", 8, false]
}
]
},
{
name: "MAC Generate: ISO 9797-1 Algorithm 1",
input: "1122334455667788",
expectedOutput: "0C949BCDEF6FDF1D",
recipeConfig: [
{
op: "MAC Generate",
args: ["Hex", "ISO 9797-1 Algorithm 1", "0123456789ABCDEFFEDCBA9876543210", "Hex", "", "Method 1", 8, false]
}
]
},
{
name: "MAC Generate: ISO 9797-1 Algorithm 3",
input: "1122334455667788",
expectedOutput: "7E2AEA5CF35FDC0E",
recipeConfig: [
{
op: "MAC Generate",
args: ["Hex", "ISO 9797-1 Algorithm 3", "0123456789ABCDEFFEDCBA9876543210", "Hex", "", "Method 2", 8, false]
}
]
},
{
name: "MAC Generate: AS2805-4.1",
input: "1122334455667788",
expectedOutput: "3EB3B72576BBBE83",
recipeConfig: [
{
op: "MAC Generate",
args: ["Hex", "AS2805-4.1", "0123456789ABCDEFFEDCBA9876543210", "Hex", "", "Method 1", 8, false]
}
]
},
{
name: "MAC Verify: AES-CMAC",
input: "1122334455667788",
expectedOutput: JSON.stringify({
method: "AES-CMAC",
inputFormat: "Hex",
inputHex: "1122334455667788",
paddingMethod: null,
outputBytes: 8,
fullMacHex: "339AF1AD1650E908A794284D91DC6D29",
macHex: "339AF1AD1650E908",
keySource: "Direct key input",
expectedMacHex: "339AF1AD1650E908",
valid: true
}, null, 4),
recipeConfig: [
{
op: "MAC Verify",
args: ["Hex", "AES-CMAC", "00112233445566778899AABBCCDDEEFF", "Hex", "", "Method 1", "339AF1AD1650E908", true]
}
]
},
{
name: "EMV Generate MAC: issuer script sample",
input: "8424000008999E57FD0F47CACE0007",
expectedOutput: "22CB48394DFD1977",
recipeConfig: [
{
op: "EMV Generate MAC",
args: ["0123456789ABCDEFFEDCBA9876543210", 8, false]
}
]
},
{
name: "EMV Verify MAC: issuer script sample",
input: "8424000008999E57FD0F47CACE0007",
expectedOutput: JSON.stringify({
algorithm: "EMV MAC",
paddingMethod: "Method 2",
inputHex: "8424000008999E57FD0F47CACE0007",
fullMacHex: "22CB48394DFD1977",
macHex: "22CB48394DFD1977",
expectedMacHex: "22CB48394DFD1977",
valid: true
}, null, 4),
recipeConfig: [
{
op: "EMV Verify MAC",
args: ["0123456789ABCDEFFEDCBA9876543210", "22CB48394DFD1977", true]
}
]
},
{
name: "EMV Generate MAC (PIN Change): issuer script sample",
input: "00A4040008A000000004101080D80500000001010A04000000000000",
expectedOutput: "C0F24786EF1C4522",
recipeConfig: [
{
op: "EMV Generate MAC (PIN Change)",
args: ["67FB27C75580EFE7", "0123456789ABCDEFFEDCBA9876543210", 8, false]
}
]
},
{
name: "PIN Data Generate: ISO Format 0",
input: "1234",
expectedOutput: "041215FEDCBA9876",
recipeConfig: [
{
op: "PIN Data Generate",
args: ["ISO Format 0", "5432101234567890", false, false]
}
]
},
{
name: "IBM 3624 Generate PIN Offset: known sample",
input: "1234",
expectedOutput: JSON.stringify({
pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210",
pinValidationData: "5432101234567890",
pinValidationDataPadCharacter: "F",
pinLength: 4,
validationBlockHex: "5432101234567890",
encryptedValidationBlockHex: "8A3712EE04F010A0",
decimalized: "8037124404501000",
naturalPin: "8037",
pin: "1234",
pinOffset: "3207"
}, null, 4),
recipeConfig: [
{
op: "IBM 3624 Generate PIN Offset",
args: ["0123456789ABCDEFFEDCBA9876543210", "0123456789012345", "5432101234567890", "F", true]
}
]
},
{
name: "IBM 3624 Verify PIN: known sample",
input: "1234",
expectedOutput: JSON.stringify({
pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210",
pinValidationData: "5432101234567890",
pinValidationDataPadCharacter: "F",
pinLength: 4,
validationBlockHex: "5432101234567890",
encryptedValidationBlockHex: "8A3712EE04F010A0",
decimalized: "8037124404501000",
naturalPin: "8037",
pin: "1234",
pinOffset: "3207",
expectedPinOffset: "3207",
valid: true
}, null, 4),
recipeConfig: [
{
op: "IBM 3624 Verify PIN",
args: ["0123456789ABCDEFFEDCBA9876543210", "0123456789012345", "5432101234567890", "F", "3207", true]
}
]
},
{
name: "VISA PVV Generate: known sample",
input: "1234",
expectedOutput: JSON.stringify({
pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210",
pan: "5432101234567890",
pinVerificationKeyIndex: 1,
pin: "1234",
pvvInput: "1012345678911234",
encryptedPvvInputHex: "6A77E65CFE349D60",
pvv: "6077"
}, null, 4),
recipeConfig: [
{
op: "VISA PVV Generate",
args: ["0123456789ABCDEFFEDCBA9876543210", "5432101234567890", 1, true]
}
]
},
{
name: "VISA PVV Verify: known sample",
input: "1234",
expectedOutput: JSON.stringify({
pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210",
pan: "5432101234567890",
pinVerificationKeyIndex: 1,
pin: "1234",
pvvInput: "1012345678911234",
encryptedPvvInputHex: "6A77E65CFE349D60",
pvv: "6077",
expectedPvv: "6077",
valid: true
}, null, 4),
recipeConfig: [
{
op: "VISA PVV Verify",
args: ["0123456789ABCDEFFEDCBA9876543210", "5432101234567890", 1, "6077", true]
}
]
},
{
name: "AS2805 Generate KEK Validation: response sample",
input: "0123456789ABCDEFFEDCBA9876543210",
expectedOutput: JSON.stringify({
validationType: "KekValidationResponse",
deriveKeyAlgorithm: "TDES_2KEY",
randomKeySendVariantMask: "VARIANT_MASK_82",
keyCheckValue: "08D7B4",
randomKeySend: "9217DC67B8763BABCFDF3DADFCD0F84A",
randomKeyReceive: "6DE823984789C4543020C252032F07B5"
}, null, 4),
recipeConfig: [
{
op: "AS2805 Generate KEK Validation",
args: ["KekValidationResponse", "TDES_2KEY", "VARIANT_MASK_82", "9217DC67B8763BABCFDF3DADFCD0F84A", true]
}
]
},
{
name: "PIN Data Verify: ISO Format 0",
input: "041215FEDCBA9876",
expectedOutput: JSON.stringify({
format: "ISO Format 0",
pin: "1234",
pinLength: 4,
pinFieldHex: "041234FFFFFFFFFF",
panFieldHex: "0000210123456789",
blockHex: "041215FEDCBA9876",
fillDigitsHex: "FFFFFFFFFF",
expectedPin: "1234",
valid: true
}, null, 4),
recipeConfig: [
{
op: "PIN Data Verify",
args: ["ISO Format 0", "5432101234567890", "1234"]
}
]
},
{
name: "Derive ECDH Key Material: raw shared secret",
input: ecdhPrivateKey,
expectedOutput: "4BE993A2D1BD25C7B5A625EDEBE48D022557ACA445C60EE403ECE9BA38A41CFE",
recipeConfig: [
{
op: "Derive ECDH Key Material",
args: ["PEM", "P-256", "PEM", ecdhPeerPublicKey, "None", 32, "", "Hex"]
}
]
},
{
name: "Derive ECDH Key Material: SEC1 EC private key PEM",
input: ecdhPrivateKeySec1,
expectedOutput: "4BE993A2D1BD25C7B5A625EDEBE48D022557ACA445C60EE403ECE9BA38A41CFE",
recipeConfig: [
{
op: "Derive ECDH Key Material",
args: ["PEM", "P-256", "PEM", ecdhPeerPublicKey, "None", 32, "", "Hex"]
}
]
}
]);