crypto-keygen-suite
Version:
Key generation utilities for cryptographic operations. YES I RENAMED IT. SIX STATE PROTOCOL!!! See its folder for all <3
78 lines (71 loc) • 2.37 kB
JavaScript
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
const m = 26;
function modInverse(a, m) {
a = ((a % m) + m) % m;
for (let x = 1; x < m; x++) {
if ((a * x) % m === 1) return x;
}
throw new Error(`No modular inverse for a = ${a} under mod ${m}.`);
}
function encrypt(text, a, b) {
return text
.toUpperCase()
.replace(/[^A-Z]/g, '')
.split('')
.map(char => {
const x = char.charCodeAt(0) - 65;
const y = (a * x + b) % m;
return String.fromCharCode(y + 65);
})
.join('');
}
function decrypt(text, a, b) {
const aInv = modInverse(a, m);
return text
.toUpperCase()
.replace(/[^A-Z]/g, '')
.split('')
.map(char => {
const y = char.charCodeAt(0) - 65;
const x = ((aInv * (y - b + m)) % m + m) % m;
return String.fromCharCode(x + 65);
})
.join('');
}
yargs(hideBin(process.argv))
.command(
'encrypt',
'Encrypt using Affine cipher',
y => y
.option('a', { describe: 'Key a (must be coprime with 26)', demandOption: true, type: 'number' })
.option('b', { describe: 'Key b', demandOption: true, type: 'number' })
.option('text', { describe: 'Plaintext', demandOption: true, type: 'string' }),
argv => {
try {
console.log('Encrypted:', encrypt(argv.text, argv.a, argv.b));
} catch (err) {
console.error('❌ Error:', err.message);
}
}
)
.command(
'decrypt',
'Decrypt using Affine cipher',
y => y
.option('a', { describe: 'Key a (must be coprime with 26)', demandOption: true, type: 'number' })
.option('b', { describe: 'Key b', demandOption: true, type: 'number' })
.option('text', { describe: 'Ciphertext', demandOption: true, type: 'string' }),
argv => {
try {
console.log('Decrypted:', decrypt(argv.text, argv.a, argv.b));
} catch (err) {
console.error('❌ Error:', err.message);
}
}
)
.demandCommand()
.strict()
.help()
.argv;