Skip to content

Instantly share code, notes, and snippets.

@Rychu-Pawel
Last active November 23, 2024 20:14
Show Gist options
  • Save Rychu-Pawel/b8e944db7534342931e78c1c039633c3 to your computer and use it in GitHub Desktop.
Save Rychu-Pawel/b8e944db7534342931e78c1c039633c3 to your computer and use it in GitHub Desktop.
NodeJS AES-256-CTR IV counter increment functions test
/*
This is a comparison-test of multiple IV counter increment functions I found on the internet and created myself.
The goal here was to pick the most reliable one.
`incrementIVOriginal` comes from https://stackoverflow.com/questions/49954020/is-it-possible-to-decipher-at-random-position-with-nodejs-crypto
Run with:
> npx ava
Output:
$ npx ava --timeout=10m
- [skip] incrementIVOpenSSL - Increment by maximum possible value
✔ ORIGINAL - Increment by 1 (6m 58.1s)
✔ ORIGINAL - Incrementation causing transfer between segments (6m 58.1s)
✘ [fail]: ORIGINAL - Increment by MAX_UINT32 Error thrown in test
✔ ORIGINAL - Increment over 64 bits (6m 58s)
✘ [fail]: ORIGINAL - Increment by a big value Error thrown in test
✔ ORIGINAL - Increment causing overflow of entire IV (6m 58s)
✘ [fail]: ORIGINAL - Increment by maximum possible value
✔ incrementIVFixed - Increment by 1 (6m 58s)
✔ incrementIVFixed - Incrementation causing transfer between segments (6m 58s)
✔ incrementIVFixed - Increment by MAX_UINT32 (6m 58s)
✔ incrementIVFixed - Increment over 64 bits (6m 58s)
✔ incrementIVFixed - Increment by a big value (6m 58s)
✔ incrementIVFixed - Increment causing overflow of entire IV (6m 58s)
✘ [fail]: incrementIVFixed - Increment by maximum possible value
✔ incrementIVBigInt - Increment by 1 (6m 58s)
✔ incrementIVBigInt - Incrementation causing transfer between segments (6m 58s)
✔ incrementIVBigInt - Increment by MAX_UINT32 (6m 58s)
✔ incrementIVBigInt - Increment over 64 bits (6m 58s)
✔ incrementIVBigInt - Increment by a big value (6m 58s)
✔ incrementIVBigInt - Increment causing overflow of entire IV (6m 58s)
✔ incrementIVBigInt - Increment by maximum possible value (6m 58s)
✔ incrementIVOpenSSL - Increment by 1 (6m 58s)
✔ incrementIVOpenSSL - Incrementation causing transfer between segments (6m 58s)
✔ incrementIVOpenSSL - Increment by MAX_UINT32 (6m 58s)
✔ incrementIVOpenSSL - Increment over 64 bits (5m 13.4s)
✔ incrementIVOpenSSL - Increment by a big value (3m 29.5s)
✔ incrementIVOpenSSL - Increment causing overflow of entire IV
✔ incrementIVCryptoAesCtr - Increment by 1
✔ incrementIVCryptoAesCtr - Incrementation causing transfer between segments
✔ incrementIVCryptoAesCtr - Increment by MAX_UINT32
✔ incrementIVCryptoAesCtr - Increment over 64 bits
✔ incrementIVCryptoAesCtr - Increment by a big value
✘ [fail]: incrementIVCryptoAesCtr - Increment causing overflow of entire IV
✘ [fail]: incrementIVCryptoAesCtr - Increment by maximum possible value
ORIGINAL - Increment by MAX_UINT32
Error thrown in test:
RangeError {
code: 'ERR_OUT_OF_RANGE',
message: 'The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received -1',
}
RangeError [ERR_OUT_OF_RANGE]: The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received -1
at checkInt (node:internal/buffer:74:11)
at writeU_Int32BE (node:internal/buffer:804:3)
at Buffer.writeUInt32BE (node:internal/buffer:817:10)
at incrementIVOriginal (file:///C:/Users/Rychu/Desktop/Temp/aes/test.spec.mjs:502:12)
at file:///C:/Users/Rychu/Desktop/Temp/aes/test.spec.mjs:39:5
at Test.callFn (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/test.js:525:26)
at Test.run (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/test.js:534:33)
at Runner.runSingle (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/runner.js:281:33)
at Runner.runTest (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/runner.js:363:30)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
ORIGINAL - Increment by a big value
Error thrown in test:
RangeError {
code: 'ERR_OUT_OF_RANGE',
message: 'The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received -1',
}
RangeError [ERR_OUT_OF_RANGE]: The value of "value" is out of range. It must be >= 0 and <= 4294967295. Received -1
at checkInt (node:internal/buffer:74:11)
at writeU_Int32BE (node:internal/buffer:804:3)
at Buffer.writeUInt32BE (node:internal/buffer:817:10)
at incrementIVOriginal (file:///C:/Users/Rychu/Desktop/Temp/aes/test.spec.mjs:502:12)
at file:///C:/Users/Rychu/Desktop/Temp/aes/test.spec.mjs:67:5
at Test.callFn (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/test.js:525:26)
at Test.run (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/test.js:534:33)
at Runner.runSingle (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/runner.js:281:33)
at Runner.runTest (file:///C:/Users/Rychu/Desktop/Temp/aes/node_modules/ava/lib/runner.js:363:30)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
ORIGINAL - Increment by maximum possible value
test.spec.mjs:92
91:
92: t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
93: });
Difference (- actual, + expected):
- '00000000000000000000000000000001'
+ 'ffffffffffffffffffffffffffffffff'
› file:///test.spec.mjs:92:7
incrementIVFixed - Increment by maximum possible value
test.spec.mjs:188
187:
188: t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
189: });
Difference (- actual, + expected):
- '00000000000000010000000000000000'
+ 'ffffffffffffffffffffffffffffffff'
› file:///test.spec.mjs:188:7
incrementIVCryptoAesCtr - Increment causing overflow of entire IV
test.spec.mjs:466
465:
466: t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
467: });
Difference (- actual, + expected):
- '00000000000000000000000000000003'
+ '00000000000000000000000000000002'
› file:///test.spec.mjs:466:7
incrementIVCryptoAesCtr - Increment by maximum possible value
test.spec.mjs:477
476:
477: t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
478: });
Difference (- actual, + expected):
- '00000000000000000000000000000001'
+ 'ffffffffffffffffffffffffffffffff'
› file:///test.spec.mjs:477:7
6 tests failed
1 test skipped
*/
import test from "ava";
test(`ORIGINAL - Increment by 1`, t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 1;
const expectedIV = Buffer.from('00000000000000000000000000000001', 'hex');
// Act
incrementIVOriginal(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('ORIGINAL - Incrementation causing transfer between segments ', t => {
// Arrange
const originalIV = Buffer.from('00000000FFFFFFFFFFFFFFFFFFFFFFFF', 'hex');
const increment = 1;
const expectedIV = Buffer.from('00000001000000000000000000000000', 'hex');
// Act
incrementIVOriginal(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('ORIGINAL - Increment by MAX_UINT32', t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 0xFFFFFFFF;
const expectedIV = Buffer.from('000000000000000000000000FFFFFFFF', 'hex');
// Act
incrementIVOriginal(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('ORIGINAL - Increment over 64 bits', t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 0x1_00000000; // 2^32
const expectedIV = Buffer.from('00000000000000000000000100000000', 'hex');
// Act
incrementIVOriginal(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('ORIGINAL - Increment by a big value', t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 0x1FFFFFFFF; // 2^33 - 1
const expectedIV = Buffer.from('000000000000000000000001FFFFFFFF', 'hex');
// Act
incrementIVOriginal(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('ORIGINAL - Increment causing overflow of entire IV', t => {
const originalIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
const increment = 3;
const expectedIV = Buffer.from('00000000000000000000000000000002', 'hex');
incrementIVOriginal(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('ORIGINAL - Increment by maximum possible value', t => {
const originalIV = Buffer.alloc(16, 0);
const increment = 0xffffffffffffffffffffffffffffffff; // 2^128 - 1
const expectedIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
incrementIVOriginal(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
///////////////////
// Fixed below
///////////////////
test(`incrementIVFixed - Increment by 1`, t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 1;
const expectedIV = Buffer.from('00000000000000000000000000000001', 'hex');
// Act
incrementIVFixed(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVFixed - Incrementation causing transfer between segments ', t => {
// Arrange
const originalIV = Buffer.from('00000000FFFFFFFFFFFFFFFFFFFFFFFF', 'hex');
const increment = 1;
const expectedIV = Buffer.from('00000001000000000000000000000000', 'hex');
// Act
incrementIVFixed(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVFixed - Increment by MAX_UINT32', t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 0xFFFFFFFF;
const expectedIV = Buffer.from('000000000000000000000000FFFFFFFF', 'hex');
// Act
incrementIVFixed(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVFixed - Increment over 64 bits', t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 0x1_00000000; // 2^32
const expectedIV = Buffer.from('00000000000000000000000100000000', 'hex');
// Act
incrementIVFixed(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVFixed - Increment by a big value', t => {
// Arrange
const originalIV = Buffer.alloc(16, 0);
const increment = 0x1FFFFFFFF; // 2^33 - 1
const expectedIV = Buffer.from('000000000000000000000001FFFFFFFF', 'hex');
// Act
incrementIVFixed(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVFixed - Increment causing overflow of entire IV', t => {
const originalIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
const increment = 3;
const expectedIV = Buffer.from('00000000000000000000000000000002', 'hex');
incrementIVFixed(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVFixed - Increment by maximum possible value', t => {
const originalIV = Buffer.alloc(16, 0);
const increment = 0xffffffffffffffffffffffffffffffff; // 2^128 - 1
const expectedIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
incrementIVFixed(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
///////////////////
// BigInt below
///////////////////
test(`incrementIVBigInt - Increment by 1`, t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 1;
const expectedIV = Buffer.from('00000000000000000000000000000001', 'hex');
// Act
originalIV = incrementIVBigInt(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVBigInt - Incrementation causing transfer between segments ', t => {
// Arrange
let originalIV = Buffer.from('00000000FFFFFFFFFFFFFFFFFFFFFFFF', 'hex');
const increment = 1;
const expectedIV = Buffer.from('00000001000000000000000000000000', 'hex');
// Act
originalIV = incrementIVBigInt(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVBigInt - Increment by MAX_UINT32', t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 0xFFFFFFFF;
const expectedIV = Buffer.from('000000000000000000000000FFFFFFFF', 'hex');
// Act
originalIV = incrementIVBigInt(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVBigInt - Increment over 64 bits', t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 0x1_00000000; // 2^32
const expectedIV = Buffer.from('00000000000000000000000100000000', 'hex');
// Act
originalIV = incrementIVBigInt(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVBigInt - Increment by a big value', t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 0x1FFFFFFFF; // 2^33 - 1
const expectedIV = Buffer.from('000000000000000000000001FFFFFFFF', 'hex');
// Act
originalIV = incrementIVBigInt(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVBigInt - Increment causing overflow of entire IV', t => {
let originalIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
const increment = 3;
const expectedIV = Buffer.from('00000000000000000000000000000002', 'hex');
originalIV = incrementIVBigInt(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVBigInt - Increment by maximum possible value', t => {
let originalIV = Buffer.alloc(16, 0);
const increment = BigInt('0xffffffffffffffffffffffffffffffff'); // 2^128 - 1
const expectedIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
originalIV = incrementIVBigInt(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
///////////////////
// OpenSSL below - these takes dozen of minutes. Uncomment if you have a lot of time
///////////////////
// test(`incrementIVOpenSSL - Increment by 1`, t => {
// // Arrange
// const originalIV = Buffer.alloc(16, 0);
// const increment = 1;
// const expectedIV = Buffer.from('00000000000000000000000000000001', 'hex');
// // Act
// incrementIVOpenSSL(originalIV, increment);
// // Assert
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
// test('incrementIVOpenSSL - Incrementation causing transfer between segments ', t => {
// // Arrange
// const originalIV = Buffer.from('00000000FFFFFFFFFFFFFFFFFFFFFFFF', 'hex');
// const increment = 1;
// const expectedIV = Buffer.from('00000001000000000000000000000000', 'hex');
// // Act
// incrementIVOpenSSL(originalIV, increment);
// // Assert
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
// test('incrementIVOpenSSL - Increment by MAX_UINT32', t => {
// // Arrange
// const originalIV = Buffer.alloc(16, 0);
// const increment = 0xFFFFFFFF;
// const expectedIV = Buffer.from('000000000000000000000000FFFFFFFF', 'hex');
// // Act
// incrementIVOpenSSL(originalIV, increment);
// // Assert
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
// test('incrementIVOpenSSL - Increment over 64 bits', t => {
// // Arrange
// const originalIV = Buffer.alloc(16, 0);
// const increment = 0x1_00000000; // 2^32
// const expectedIV = Buffer.from('00000000000000000000000100000000', 'hex');
// // Act
// incrementIVOpenSSL(originalIV, increment);
// // Assert
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
// test('incrementIVOpenSSL - Increment by a big value', t => {
// // Arrange
// const originalIV = Buffer.alloc(16, 0);
// const increment = 0x1FFFFFFFF; // 2^33 - 1
// const expectedIV = Buffer.from('000000000000000000000001FFFFFFFF', 'hex');
// // Act
// incrementIVOpenSSL(originalIV, increment);
// // Assert
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
// test('incrementIVOpenSSL - Increment causing overflow of entire IV', t => {
// const originalIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
// const increment = 3;
// const expectedIV = Buffer.from('00000000000000000000000000000002', 'hex');
// incrementIVOpenSSL(originalIV, increment);
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
// // The below is not possible to test because it requires significant amount of time
// test.skip('incrementIVOpenSSL - Increment by maximum possible value', t => {
// const originalIV = Buffer.alloc(16, 0);
// const increment = BigInt('0xffffffffffffffffffffffffffffffff'); // 2^128 - 1
// const expectedIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
// incrementIVOpenSSL(originalIV, increment);
// t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
// });
///////////////////
// incrementIVCryptoAesCtr below
///////////////////
test(`incrementIVCryptoAesCtr - Increment by 1`, t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 1;
const expectedIV = Buffer.from('00000000000000000000000000000001', 'hex');
// Act
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVCryptoAesCtr - Incrementation causing transfer between segments ', t => {
// Arrange
let originalIV = Buffer.from('00000000FFFFFFFFFFFFFFFFFFFFFFFF', 'hex');
const increment = 1;
const expectedIV = Buffer.from('00000001000000000000000000000000', 'hex');
// Act
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVCryptoAesCtr - Increment by MAX_UINT32', t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 0xFFFFFFFF;
const expectedIV = Buffer.from('000000000000000000000000FFFFFFFF', 'hex');
// Act
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVCryptoAesCtr - Increment over 64 bits', t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 0x1_00000000; // 2^32
const expectedIV = Buffer.from('00000000000000000000000100000000', 'hex');
// Act
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVCryptoAesCtr - Increment by a big value', t => {
// Arrange
let originalIV = Buffer.alloc(16, 0);
const increment = 0x1FFFFFFFF; // 2^33 - 1
const expectedIV = Buffer.from('000000000000000000000001FFFFFFFF', 'hex');
// Act
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
// Assert
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVCryptoAesCtr - Increment causing overflow of entire IV', t => {
let originalIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
const increment = 3;
const expectedIV = Buffer.from('00000000000000000000000000000002', 'hex');
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
test('incrementIVCryptoAesCtr - Increment by maximum possible value', t => {
let originalIV = Buffer.alloc(16, 0);
const increment = 0xffffffffffffffffffffffffffffffff; // 2^128 - 1
const expectedIV = Buffer.from('ffffffffffffffffffffffffffffffff', 'hex');
originalIV = incrementIVCryptoAesCtr(originalIV, increment);
t.is(originalIV.toString('hex'), expectedIV.toString('hex'));
});
function incrementIVOriginal(iv, increment) {
if (iv.length !== 16) throw new Error('Only implemented for 16 bytes IV');
const MAX_UINT32 = 0xFFFFFFFF;
let incrementBig = ~~(increment / MAX_UINT32);
let incrementLittle = (increment % MAX_UINT32) - incrementBig;
// split the 128bits IV in 4 numbers, 32bits each
let overflow = 0;
for (let idx = 0; idx < 4; ++idx) {
let num = iv.readUInt32BE(12 - idx * 4);
let inc = overflow;
if (idx == 0) inc += incrementLittle;
if (idx == 1) inc += incrementBig;
num += inc;
let numBig = ~~(num / MAX_UINT32);
let numLittle = (num % MAX_UINT32) - numBig;
overflow = numBig;
iv.writeUInt32BE(numLittle, 12 - idx * 4);
}
}
function incrementIVFixed(iv, increment) {
if (iv.length !== 16) throw new Error('Only implemented for 16 bytes IV');
const MAX_UINT32 = 0xFFFFFFFF;
let incrementHigh = Math.floor(increment / (MAX_UINT32 + 1));
let incrementLow = increment % (MAX_UINT32 + 1);
let overflow = 0;
for (let idx = 3; idx >= 0; --idx) {
let num = iv.readUInt32BE(idx * 4);
let inc = overflow;
if (idx === 3) inc += incrementLow;
if (idx === 2) inc += incrementHigh;
num += inc;
overflow = num > MAX_UINT32 ? 1 : 0;
num = num >>> 0; // Convert to unsigned 32-bit integer
iv.writeUInt32BE(num, idx * 4);
}
}
function incrementIVBigInt(iv, increment) {
// Convert IV to BigInt
let ivBigInt = BigInt('0x' + iv.toString('hex'));
// Increment
ivBigInt += BigInt(increment);
// Modulo 2^128 to ensure 128-bit range
ivBigInt = ivBigInt % (BigInt(1) << BigInt(128));
// Convert back to buffer
let incrementedIVHex = ivBigInt.toString(16).padStart(32, '0');
return Buffer.from(incrementedIVHex, 'hex');
}
function incrementIVOpenSSL(iv, increment) {
for (let i = 0; i < increment; i++)
ctr128Inc(iv)
}
function ctr128Inc(counter) {
let c = 1;
let n = 16;
do {
n -= 1;
c += counter[n];
counter[n] = c & 0xFF;
c = c >> 8;
} while (n);
}
function incrementIVCryptoAesCtr(iv, increment) {
var i, len, mod;
len = iv.length;
i = len - 1;
while (increment !== 0) {
mod = (increment + iv[i]) % 256;
increment = Math.floor((increment + iv[i]) / 256);
iv[i] = mod;
i -= 1;
if (i < 0) {
i = len - 1;
}
}
return iv;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment