Files
heros/node_modules/crypto-es/lib/mode-ctr-gladman.js
2024-07-17 16:14:14 +08:00

88 lines
1.8 KiB
JavaScript

import {
BlockCipherMode,
} from './cipher-core.js';
const incWord = (word) => {
let _word = word;
if (((word >> 24) & 0xff) === 0xff) { // overflow
let b1 = (word >> 16) & 0xff;
let b2 = (word >> 8) & 0xff;
let b3 = word & 0xff;
if (b1 === 0xff) { // overflow b1
b1 = 0;
if (b2 === 0xff) {
b2 = 0;
if (b3 === 0xff) {
b3 = 0;
} else {
b3 += 1;
}
} else {
b2 += 1;
}
} else {
b1 += 1;
}
_word = 0;
_word += (b1 << 16);
_word += (b2 << 8);
_word += b3;
} else {
_word += (0x01 << 24);
}
return _word;
};
const incCounter = (counter) => {
const _counter = counter;
_counter[0] = incWord(_counter[0]);
if (_counter[0] === 0) {
// encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
_counter[1] = incWord(_counter[1]);
}
return _counter;
};
/** @preserve
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/
export class CTRGladman extends BlockCipherMode {
}
CTRGladman.Encryptor = class extends CTRGladman {
processBlock(words, offset) {
const _words = words;
// Shortcuts
const cipher = this._cipher;
const { blockSize } = cipher;
const iv = this._iv;
let counter = this._counter;
// Generate keystream
if (iv) {
this._counter = iv.slice(0);
counter = this._counter;
// Remove IV for subsequent blocks
this._iv = undefined;
}
incCounter(counter);
const keystream = counter.slice(0);
cipher.encryptBlock(keystream, 0);
// Encrypt
for (let i = 0; i < blockSize; i += 1) {
_words[offset + i] ^= keystream[i];
}
}
};
CTRGladman.Decryptor = CTRGladman.Encryptor;