Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
crypto: rename CShakeParams and KmacParams length to outputLength
PR-URL: #61875
Backport-PR-URL: #62539
Refs: web-platform-tests/wpt#57802
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
panva authored and aduh95 committed Apr 3, 2026
commit 2395fc0f4dcac414a1a82897edcd7ae7d9de2f0b
50 changes: 29 additions & 21 deletions doc/api/webcrypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -1868,19 +1868,27 @@ the message.

<!-- YAML
added: v24.7.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/61875
description: Renamed `cShakeParams.length` to `cShakeParams.outputLength`.
-->

#### `cShakeParams.customization`
#### `cShakeParams.name`

<!-- YAML
added: v24.7.0
-->

* Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined}
* Type: {string} Must be `'cSHAKE128'`[^modern-algos] or `'cSHAKE256'`[^modern-algos]

The `customization` member represents the customization string.
The Node.js Web Crypto API implementation only supports zero-length customization
which is equivalent to not providing customization at all.
#### `cShakeParams.outputLength`

<!-- YAML
added: REPLACEME
-->

* Type: {number} represents the requested output length in bits.

#### `cShakeParams.functionName`

Expand All @@ -1895,21 +1903,17 @@ functions based on cSHAKE.
The Node.js Web Crypto API implementation only supports zero-length functionName
which is equivalent to not providing functionName at all.

#### `cShakeParams.length`
#### `cShakeParams.customization`

<!-- YAML
added: v24.7.0
-->

* Type: {number} represents the requested output length in bits.

#### `cShakeParams.name`

<!-- YAML
added: v24.7.0
-->
* Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined}

* Type: {string} Must be `'cSHAKE128'`[^modern-algos] or `'cSHAKE256'`[^modern-algos]
The `customization` member represents the customization string.
The Node.js Web Crypto API implementation only supports zero-length customization
which is equivalent to not providing customization at all.

### Class: `EcdhKeyDeriveParams`

Expand Down Expand Up @@ -2386,6 +2390,10 @@ added: v24.8.0

<!-- YAML
added: v24.8.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/61875
description: Renamed `kmacParams.length` to `kmacParams.outputLength`.
-->

#### `kmacParams.algorithm`
Expand All @@ -2396,25 +2404,25 @@ added: v24.8.0

* Type: {string} Must be `'KMAC128'` or `'KMAC256'`.

#### `kmacParams.customization`
#### `kmacParams.outputLength`

<!-- YAML
added: v24.8.0
added: REPLACEME
-->

* Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined}
* Type: {number}

The `customization` member represents the optional customization string.
The length of the output in bytes. This must be a positive integer.

#### `kmacParams.length`
#### `kmacParams.customization`

<!-- YAML
added: v24.8.0
-->

* Type: {number}
* Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined}

The length of the output in bytes. This must be a positive integer.
The `customization` member represents the optional customization string.

### Class: `Pbkdf2Params`

Expand Down
2 changes: 1 addition & 1 deletion lib/internal/crypto/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ async function asyncDigest(algorithm, data) {
kCryptoJobAsync,
normalizeHashName(algorithm.name),
data,
algorithm.length));
algorithm.outputLength));
}

throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/crypto/mac.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ function kmacSignVerify(key, data, algorithm, signature) {
key[kKeyObject][kHandle],
algorithm.name,
algorithm.customization,
algorithm.length / 8,
algorithm.outputLength / 8,
data,
signature));
}
Expand Down
8 changes: 4 additions & 4 deletions lib/internal/crypto/webidl.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,14 +589,14 @@ converters.CShakeParams = createDictionaryConverter(
'CShakeParams', [
...new SafeArrayIterator(dictAlgorithm),
{
key: 'length',
key: 'outputLength',
converter: (V, opts) =>
converters['unsigned long'](V, { ...opts, enforceRange: true }),
validator: (V, opts) => {
// The Web Crypto spec allows for SHAKE output length that are not multiples of
// 8. We don't.
if (V % 8)
throw lazyDOMException('Unsupported CShakeParams length', 'NotSupportedError');
throw lazyDOMException('Unsupported CShakeParams outputLength', 'NotSupportedError');
},
required: true,
},
Expand Down Expand Up @@ -879,13 +879,13 @@ converters.KmacParams = createDictionaryConverter(
'KmacParams', [
...new SafeArrayIterator(dictAlgorithm),
{
key: 'length',
key: 'outputLength',
converter: (V, opts) =>
converters['unsigned long'](V, { ...opts, enforceRange: true }),
validator: (V, opts) => {
// The Web Crypto spec allows for KMAC output length that are not multiples of 8. We don't.
if (V % 8)
throw lazyDOMException('Unsupported KmacParams length', 'NotSupportedError');
throw lazyDOMException('Unsupported KmacParams outputLength', 'NotSupportedError');
},
required: true,
},
Expand Down
12 changes: 6 additions & 6 deletions test/fixtures/crypto/kmac.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = function() {
]),
data: Buffer.from([0x00, 0x01, 0x02, 0x03]),
customization: undefined,
length: 256,
outputLength: 256,
expected: Buffer.from([
0xe5, 0x78, 0x0b, 0x0d, 0x3e, 0xa6, 0xf7, 0xd3, 0xa4, 0x29, 0xc5, 0x70,
0x6a, 0xa4, 0x3a, 0x00, 0xfa, 0xdb, 0xd7, 0xd4, 0x96, 0x28, 0x83, 0x9e,
Expand All @@ -30,7 +30,7 @@ module.exports = function() {
]),
data: Buffer.from([0x00, 0x01, 0x02, 0x03]),
customization: Buffer.from('My Tagged Application'),
length: 256,
outputLength: 256,
expected: Buffer.from([
0x3b, 0x1f, 0xba, 0x96, 0x3c, 0xd8, 0xb0, 0xb5, 0x9e, 0x8c, 0x1a, 0x6d,
0x71, 0x88, 0x8b, 0x71, 0x43, 0x65, 0x1a, 0xf8, 0xba, 0x0a, 0x70, 0x70,
Expand All @@ -47,7 +47,7 @@ module.exports = function() {
]),
data: Buffer.from(Array.from({ length: 200 }, (_, i) => i)), // 0x00-0xC7
customization: Buffer.from('My Tagged Application'),
length: 256,
outputLength: 256,
expected: Buffer.from([
0x1f, 0x5b, 0x4e, 0x6c, 0xca, 0x02, 0x20, 0x9e, 0x0d, 0xcb, 0x5c, 0xa6,
0x35, 0xb8, 0x9a, 0x15, 0xe2, 0x71, 0xec, 0xc7, 0x60, 0x07, 0x1d, 0xfd,
Expand All @@ -64,7 +64,7 @@ module.exports = function() {
]),
data: Buffer.from([0x00, 0x01, 0x02, 0x03]),
customization: Buffer.from('My Tagged Application'),
length: 512,
outputLength: 512,
expected: Buffer.from([
0x20, 0xc5, 0x70, 0xc3, 0x13, 0x46, 0xf7, 0x03, 0xc9, 0xac, 0x36, 0xc6,
0x1c, 0x03, 0xcb, 0x64, 0xc3, 0x97, 0x0d, 0x0c, 0xfc, 0x78, 0x7e, 0x9b,
Expand All @@ -84,7 +84,7 @@ module.exports = function() {
]),
data: Buffer.from(Array.from({ length: 200 }, (_, i) => i)), // 0x00-0xC7
customization: undefined,
length: 512,
outputLength: 512,
expected: Buffer.from([
0x75, 0x35, 0x8c, 0xf3, 0x9e, 0x41, 0x49, 0x4e, 0x94, 0x97, 0x07, 0x92,
0x7c, 0xee, 0x0a, 0xf2, 0x0a, 0x3f, 0xf5, 0x53, 0x90, 0x4c, 0x86, 0xb0,
Expand All @@ -104,7 +104,7 @@ module.exports = function() {
]),
data: Buffer.from(Array.from({ length: 200 }, (_, i) => i)), // 0x00-0xC7
customization: Buffer.from('My Tagged Application'),
length: 512,
outputLength: 512,
expected: Buffer.from([
0xb5, 0x86, 0x18, 0xf7, 0x1f, 0x92, 0xe1, 0xd5, 0x6c, 0x1b, 0x8c, 0x55,
0xdd, 0xd7, 0xcd, 0x18, 0x8b, 0x97, 0xb4, 0xca, 0x4d, 0x99, 0x83, 0x1e,
Expand Down
24 changes: 12 additions & 12 deletions test/fixtures/webcrypto/supports-modern-algorithms.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ const X25519 = await subtle.generateKey('X25519', false, ['deriveBits', 'deriveK
export const vectors = {
'digest': [
[false, 'cSHAKE128'],
[shake128, { name: 'cSHAKE128', length: 128 }],
[shake128, { name: 'cSHAKE128', length: 128, functionName: Buffer.alloc(0), customization: Buffer.alloc(0) }],
[false, { name: 'cSHAKE128', length: 128, functionName: Buffer.alloc(1) }],
[false, { name: 'cSHAKE128', length: 128, customization: Buffer.alloc(1) }],
[false, { name: 'cSHAKE128', length: 127 }],
[shake128, { name: 'cSHAKE128', outputLength: 128 }],
[shake128, { name: 'cSHAKE128', outputLength: 128, functionName: Buffer.alloc(0), customization: Buffer.alloc(0) }],
[false, { name: 'cSHAKE128', outputLength: 128, functionName: Buffer.alloc(1) }],
[false, { name: 'cSHAKE128', outputLength: 128, customization: Buffer.alloc(1) }],
[false, { name: 'cSHAKE128', outputLength: 127 }],
[false, 'cSHAKE256'],
[shake256, { name: 'cSHAKE256', length: 256 }],
[shake256, { name: 'cSHAKE256', length: 256, functionName: Buffer.alloc(0), customization: Buffer.alloc(0) }],
[false, { name: 'cSHAKE256', length: 256, functionName: Buffer.alloc(1) }],
[false, { name: 'cSHAKE256', length: 256, customization: Buffer.alloc(1) }],
[false, { name: 'cSHAKE256', length: 255 }],
[shake256, { name: 'cSHAKE256', outputLength: 256 }],
[shake256, { name: 'cSHAKE256', outputLength: 256, functionName: Buffer.alloc(0), customization: Buffer.alloc(0) }],
[false, { name: 'cSHAKE256', outputLength: 256, functionName: Buffer.alloc(1) }],
[false, { name: 'cSHAKE256', outputLength: 256, customization: Buffer.alloc(1) }],
[false, { name: 'cSHAKE256', outputLength: 255 }],
],
'sign': [
[pqc, 'ML-DSA-44'],
Expand All @@ -44,8 +44,8 @@ export const vectors = {
[false, 'Argon2id'],
[false, 'KMAC128'],
[false, 'KMAC256'],
[kmac, { name: 'KMAC128', length: 256 }],
[kmac, { name: 'KMAC256', length: 256 }],
[kmac, { name: 'KMAC128', outputLength: 256 }],
[kmac, { name: 'KMAC256', outputLength: 256 }],
],
'generateKey': [
[pqc, 'ML-DSA-44'],
Expand Down
14 changes: 7 additions & 7 deletions test/parallel/test-webcrypto-digest.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const kTests = [

if (!process.features.openssl_is_boringssl) {
kTests.push(
[{ name: 'cSHAKE128', length: 256 }, ['shake128', { outputLength: 256 >> 3 }], 256],
[{ name: 'cSHAKE256', length: 512 }, ['shake256', { outputLength: 512 >> 3 }], 512],
[{ name: 'cSHAKE128', outputLength: 256 }, ['shake128', { outputLength: 256 >> 3 }], 256],
[{ name: 'cSHAKE256', outputLength: 512 }, ['shake256', { outputLength: 512 >> 3 }], 512],
['SHA3-256', ['sha3-256'], 256],
['SHA3-384', ['sha3-384'], 384],
['SHA3-512', ['sha3-512'], 512],
Expand Down Expand Up @@ -223,10 +223,10 @@ async function testDigest(size, alg) {

function applyXOF(name) {
if (name.match(/cshake128/i)) {
return { name, length: 256 };
return { name, outputLength: 256 };
}
if (name.match(/cshake256/i)) {
return { name, length: 512 };
return { name, outputLength: 512 };
}
return name;

Expand Down Expand Up @@ -259,13 +259,13 @@ function applyXOF(name) {
if (getHashes().includes('shake128')) {
(async () => {
assert.deepStrictEqual(
new Uint8Array(await subtle.digest({ name: 'cSHAKE128', length: 0 }, Buffer.alloc(1))),
new Uint8Array(await subtle.digest({ name: 'cSHAKE128', outputLength: 0 }, Buffer.alloc(1))),
new Uint8Array(0),
);

await assert.rejects(subtle.digest({ name: 'cSHAKE128', length: 7 }, Buffer.alloc(1)), {
await assert.rejects(subtle.digest({ name: 'cSHAKE128', outputLength: 7 }, Buffer.alloc(1)), {
name: 'NotSupportedError',
message: 'Unsupported CShakeParams length',
message: 'Unsupported CShakeParams outputLength',
});
})().then(common.mustCall());
}
10 changes: 5 additions & 5 deletions test/parallel/test-webcrypto-sign-verify-kmac.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async function testVerify({ algorithm,
key,
data,
customization,
length,
outputLength,
expected }) {
const [
verifyKey,
Expand All @@ -46,7 +46,7 @@ async function testVerify({ algorithm,

const signParams = {
name: algorithm,
length,
outputLength,
customization,
};

Expand Down Expand Up @@ -112,7 +112,7 @@ async function testVerify({ algorithm,
{
assert(!(await subtle.verify({
...signParams,
length: length === 256 ? 512 : 256,
outputLength: outputLength === 256 ? 512 : 256,
}, verifyKey, expected, data)));
}
}
Expand All @@ -121,7 +121,7 @@ async function testSign({ algorithm,
key,
data,
customization,
length,
outputLength,
expected }) {
const [
signKey,
Expand All @@ -148,7 +148,7 @@ async function testSign({ algorithm,

const signParams = {
name: algorithm,
length,
outputLength,
customization,
};

Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-webcrypto-sign-verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ if (hasOpenSSL(3)) {

const signature = await subtle.sign({
name,
length: 256,
outputLength: 256,
}, key, ec.encode(data));

assert(await subtle.verify({
name,
length: 256,
outputLength: 256,
}, key, signature, ec.encode(data)));
}

Expand Down
Loading