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]
}
]