From 292f4afbb8449c8586acda815c6cb392fec8dfaa Mon Sep 17 00:00:00 2001 From: J8k3 Date: Tue, 19 May 2026 09:34:51 -0400 Subject: [PATCH] Rename IBM 3624 ops to PIN-domain-first; use crypto.getRandomValues in PAN generator Co-Authored-By: Claude Sonnet 4.6 --- PAYMENT_RECIPES.md | 14 +++++++------- src/core/config/Categories.json | 4 ++-- src/core/lib/Pan.mjs | 4 +++- src/core/operations/GenerateIBM3624PINOffset.mjs | 2 +- src/core/operations/VerifyIBM3624PIN.mjs | 4 ++-- tests/operations/tests/Payment.mjs | 14 +++++++------- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/PAYMENT_RECIPES.md b/PAYMENT_RECIPES.md index ad0cbade..01225b44 100644 --- a/PAYMENT_RECIPES.md +++ b/PAYMENT_RECIPES.md @@ -12,7 +12,7 @@ These recipe starters are for software-only payment-crypto emulation, inspection All payment operation display names follow **Title Case** throughout. Acronyms (DUKPT, AES, EMV, MAC, PAN, PVV, KCV, ARQC, ARPC, TR-31, TR-34) are always upper-case. Brand names retain their canonical capitalisation (`payShield`). Pattern: `[Domain Prefix] [Verb] [Qualifier]` -- Domain prefixes: EMV, DUKPT, PIN Block, PIN Data, PAN, Card Validation Data, VISA PVV, IBM 3624, AS2805, HSM, Payment, MAC, Key, TR-31, TR-34 +- Domain prefixes: EMV, DUKPT, PIN Block, PIN Data, PIN IBM 3624, PAN, Card Validation Data, VISA PVV, AS2805, HSM, Payment, MAC, Key, TR-31, TR-34 - Verbs: Generate, Verify, Parse, Build, Translate, Derive, Calculate, Encrypt, Decrypt, Re-Encrypt - The prefix comes first so operations sort and scan by topic in the UI list - Only operations authored in this fork belong in the Payments category — do not add upstream CyberChef ops @@ -181,8 +181,8 @@ Important assumptions: ## 8) Issuer PIN Verification Helpers Operations: -- `IBM 3624 Generate PIN Offset` -- `IBM 3624 Verify PIN` +- `PIN IBM 3624 Offset Generate` +- `PIN IBM 3624 Verify` - `VISA PVV Generate` - `VISA PVV Verify` @@ -315,8 +315,8 @@ Flow: ## G) IBM 3624 / PVV Verification Operations: -- `IBM 3624 Generate PIN Offset` -- `IBM 3624 Verify PIN` +- `PIN IBM 3624 Offset Generate` +- `PIN IBM 3624 Verify` - `VISA PVV Generate` - `VISA PVV Verify` @@ -404,8 +404,8 @@ Release guidance: `Publish` = safe with normal guardrails; `Publish with guardra | `EMV Generate ARPC` | Vendor-aligned | AWS `VerifyAuthRequestCryptogram` issuer flow | Publish with guardrails | | `Card Validation Data Generate` | Vendor-aligned | AWS `GenerateCardValidationData` | Publish with guardrails | | `Card Validation Data Verify` | Vendor-aligned | AWS `VerifyCardValidationData` | Publish with guardrails | -| `IBM 3624 Generate PIN Offset` | Vendor-aligned | AWS IBM 3624 PIN verification object | Publish with guardrails | -| `IBM 3624 Verify PIN` | Vendor-aligned | AWS IBM 3624 PIN verification object | Publish with guardrails | +| `PIN IBM 3624 Offset Generate` | Vendor-aligned | AWS IBM 3624 PIN verification object | Publish with guardrails | +| `PIN IBM 3624 Verify` | Vendor-aligned | AWS IBM 3624 PIN verification object | Publish with guardrails | | `VISA PVV Generate` | Vendor-aligned | AWS VISA PIN verification object | Publish with guardrails | | `VISA PVV Verify` | Vendor-aligned | AWS VISA PIN verification object | Publish with guardrails | | `AS2805 Generate KEK Validation` | Test helper | AWS `GenerateAs2805KekValidation` | Publish with guardrails | diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 8a30c292..6052e9fb 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -599,8 +599,8 @@ "EMV Verify MAC", "HSM Parse Futurex Command", "HSM Parse Thales Command", - "IBM 3624 Generate PIN Offset", - "IBM 3624 Verify PIN", + "PIN IBM 3624 Offset Generate", + "PIN IBM 3624 Verify", "Key Generate", "MAC Generate", "MAC Verify", diff --git a/src/core/lib/Pan.mjs b/src/core/lib/Pan.mjs index f25ee528..18d32d08 100644 --- a/src/core/lib/Pan.mjs +++ b/src/core/lib/Pan.mjs @@ -257,7 +257,9 @@ function finalizePan(body) { * @returns {string} */ function fillerDigits(length) { - return Array.from({ length }, () => Math.floor(Math.random() * 10)).join(""); + const buf = new Uint8Array(length); + crypto.getRandomValues(buf); + return Array.from(buf, b => b % 10).join(""); } /** diff --git a/src/core/operations/GenerateIBM3624PINOffset.mjs b/src/core/operations/GenerateIBM3624PINOffset.mjs index a1d9bdf2..d75d0e81 100644 --- a/src/core/operations/GenerateIBM3624PINOffset.mjs +++ b/src/core/operations/GenerateIBM3624PINOffset.mjs @@ -16,7 +16,7 @@ class GenerateIBM3624PINOffset extends Operation { constructor() { super(); - this.name = "IBM 3624 Generate PIN Offset"; + this.name = "PIN IBM 3624 Offset Generate"; this.module = "Payment"; this.description = "Paste the clear PIN into the input field and generate the IBM 3624 offset used by issuer-side PIN verification.

Input: clear PIN digits.
Arguments: provide the clear PVK in hex, decimalization table, validation data, and pad character.

Validation: Partially verified. This is a clear-key software implementation of the IBM 3624 PIN offset scheme rather than HSM-certified behavior.

Security: Clear PIN and PVK material are test-use only."; this.inlineHelp = "Input: clear PIN digits.
Args: provide PVK, decimalization table, validation data, and pad character.
Validation: clear-key IBM 3624 helper."; diff --git a/src/core/operations/VerifyIBM3624PIN.mjs b/src/core/operations/VerifyIBM3624PIN.mjs index 06947ace..a135b13c 100644 --- a/src/core/operations/VerifyIBM3624PIN.mjs +++ b/src/core/operations/VerifyIBM3624PIN.mjs @@ -16,9 +16,9 @@ class VerifyIBM3624PIN extends Operation { constructor() { super(); - this.name = "IBM 3624 Verify PIN"; + this.name = "PIN IBM 3624 Verify"; this.module = "Payment"; - this.description = "Paste the stored PIN offset into the input field and verify it against a clear PIN.

Input: stored IBM 3624 PIN offset (4 to 12 decimal digits).
Arguments: provide the clear PVK in hex, decimalization table, validation data, pad character, and the clear PIN to verify.

This operation re-derives the offset from the supplied PIN and keying material and compares it to the input offset. Use this directly after IBM 3624 Generate PIN Offset in a recipe — the offset output flows naturally into this input.

Validation: Partially verified. This is the verification pair for the same clear-key IBM 3624 helper logic used by generation.

Security: Clear PIN and PVK material are test-use only."; + this.description = "Paste the stored PIN offset into the input field and verify it against a clear PIN.

Input: stored IBM 3624 PIN offset (4 to 12 decimal digits).
Arguments: provide the clear PVK in hex, decimalization table, validation data, pad character, and the clear PIN to verify.

This operation re-derives the offset from the supplied PIN and keying material and compares it to the input offset. Use this directly after PIN IBM 3624 Offset Generate in a recipe — the offset output flows naturally into this input.

Validation: Partially verified. This is the verification pair for the same clear-key IBM 3624 helper logic used by generation.

Security: Clear PIN and PVK material are test-use only."; this.inlineHelp = "Input: stored IBM 3624 PIN offset.
Args: provide PVK, decimalization table, validation data, pad character, and the clear PIN to verify.
Validation: clear-key IBM 3624 verification helper."; this.testDataSamples = [ { diff --git a/tests/operations/tests/Payment.mjs b/tests/operations/tests/Payment.mjs index 0307944f..c6bf0c49 100644 --- a/tests/operations/tests/Payment.mjs +++ b/tests/operations/tests/Payment.mjs @@ -849,7 +849,7 @@ TestRegister.addTests([ ] }, { - name: "IBM 3624 Generate PIN Offset: known sample", + name: "PIN IBM 3624 Offset Generate: known sample", input: "1234", expectedOutput: JSON.stringify({ pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210", @@ -865,13 +865,13 @@ TestRegister.addTests([ }, null, 4), recipeConfig: [ { - op: "IBM 3624 Generate PIN Offset", + op: "PIN IBM 3624 Offset Generate", args: ["0123456789ABCDEFFEDCBA9876543210", "0123456789012345", "5432101234567890", "F", true] } ] }, { - name: "IBM 3624 Verify PIN: known sample", + name: "PIN IBM 3624 Verify: known sample", input: "3207", expectedOutput: JSON.stringify({ pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210", @@ -889,7 +889,7 @@ TestRegister.addTests([ }, null, 4), recipeConfig: [ { - op: "IBM 3624 Verify PIN", + op: "PIN IBM 3624 Verify", args: ["0123456789ABCDEFFEDCBA9876543210", "0123456789012345", "5432101234567890", "F", "1234", true] } ] @@ -1021,7 +1021,7 @@ TestRegister.addTests([ ] }, { - name: "Chain: IBM 3624 Generate PIN Offset → Verify PIN", + name: "Chain: PIN IBM 3624 Offset Generate → PIN Verify", input: "1234", expectedOutput: JSON.stringify({ pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210", @@ -1039,11 +1039,11 @@ TestRegister.addTests([ }, null, 4), recipeConfig: [ { - op: "IBM 3624 Generate PIN Offset", + op: "PIN IBM 3624 Offset Generate", args: ["0123456789ABCDEFFEDCBA9876543210", "0123456789012345", "5432101234567890", "F", false] }, { - op: "IBM 3624 Verify PIN", + op: "PIN IBM 3624 Verify", args: ["0123456789ABCDEFFEDCBA9876543210", "0123456789012345", "5432101234567890", "F", "1234", true] } ]