@ 261107.7
current
// META: title=WebCrypto API: supports method tests for algorithms in https://wicg.github.io/webcrypto-modern-algos/
// META: script=../util/helpers.js
// META: script=util/supports.js

'use strict';

const modernAlgorithms = {
  // Asymmetric algorithms
  'ML-DSA-44': {
    operations: ['generateKey', 'importKey', 'sign', 'verify', 'getPublicKey'],
  },
  'ML-DSA-65': {
    operations: ['generateKey', 'importKey', 'sign', 'verify', 'getPublicKey'],
  },
  'ML-DSA-87': {
    operations: ['generateKey', 'importKey', 'sign', 'verify', 'getPublicKey'],
  },
  'ML-KEM-512': {
    operations: [
      'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits',
      'decapsulateKey', 'decapsulateBits', 'getPublicKey'
    ],
  },
  'ML-KEM-768': {
    operations: [
      'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits',
      'decapsulateKey', 'decapsulateBits', 'getPublicKey'
    ],
  },
  'ML-KEM-1024': {
    operations: [
      'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits',
      'decapsulateKey', 'decapsulateBits', 'getPublicKey'
    ],
  },
  'MLKEM768-P256': {
    operations: [
      'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits',
      'decapsulateKey', 'decapsulateBits', 'getPublicKey'
    ],
  },
  'MLKEM768-X25519': {
    operations: [
      'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits',
      'decapsulateKey', 'decapsulateBits', 'getPublicKey'
    ],
  },
  'MLKEM1024-P384': {
    operations: [
      'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits',
      'decapsulateKey', 'decapsulateBits', 'getPublicKey'
    ],
  },

  // Symmetric algorithms
  'ChaCha20-Poly1305': {
    operations: ['generateKey', 'importKey', 'encrypt', 'decrypt'],
    encryptParams: {name: 'ChaCha20-Poly1305', iv: new Uint8Array(12)},
  },

};

const operations = [
  'generateKey',
  'importKey',
  'sign',
  'verify',
  'encrypt',
  'decrypt',
  'deriveBits',
  'digest',
  'encapsulateKey',
  'encapsulateBits',
  'decapsulateKey',
  'decapsulateBits',
  'getPublicKey',
];

// Test that supports method exists and is a static method
testSupportsMethod();


// Test standard WebCrypto algorithms for requested operations
runSupportsTests(modernAlgorithms, operations);

['ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87'].forEach(name => {
  ['sign', 'verify'].forEach(operation => {
    test(() => {
      assert_true(
        SubtleCrypto.supports(operation, {
          name,
          context: new Uint8Array(255),
        }),
        `${name} ${operation} supports a 255-byte context`
      );
      assert_false(
        SubtleCrypto.supports(operation, {
          name,
          context: new Uint8Array(256),
        }),
        `${name} ${operation} rejects a 256-byte context`
      );
    }, `supports validates ${name} ${operation} context length`);
  });
});

const mlKemImportedKeyCases = [
  {
    description: 'a matching HMAC length',
    additionalAlgorithm: {name: 'HMAC', hash: 'SHA-256', length: 256},
    expected: true,
  },
  {
    description: 'an algorithm without raw-secret import',
    additionalAlgorithm: 'Ed25519',
    expected: false,
  },
  {
    description: 'an HMAC length shorter than the shared secret',
    additionalAlgorithm: {name: 'HMAC', hash: 'SHA-256', length: 128},
    expected: false,
  },
  {
    description: 'an HMAC length longer than the shared secret',
    additionalAlgorithm: {name: 'HMAC', hash: 'SHA-256', length: 512},
    expected: false,
  },
];

['encapsulateKey', 'decapsulateKey'].forEach(operation => {
  mlKemImportedKeyCases.forEach(({
    description,
    additionalAlgorithm,
    expected,
  }) => {
    test(() => {
      assert_equals(
        SubtleCrypto.supports(
          operation,
          'ML-KEM-768',
          additionalAlgorithm
        ),
        expected,
        `ML-KEM-768 ${operation} with ${description}`
      );
    }, `supports ${operation} with ${description}`);
  });
});

// Test some algorithm objects with valid parameters
test(() => {
  assert_true(
      SubtleCrypto.supports('encrypt', {
        name: 'ChaCha20-Poly1305',
        iv: new Uint8Array(12),
        tagLength: 128,
      }),
      'ChaCha20-Poly1305 encrypt with valid tagLength');
}, 'supports returns true for algorithm objects with valid parameters');

// Test some algorithm objects with invalid parameters
test(() => {
  assert_false(
      SubtleCrypto.supports('encrypt', {
        name: 'ChaCha20-Poly1305',
        iv: new Uint8Array(12),
        tagLength: 100,
      }),
      'ChaCha20-Poly1305 encrypt with invalid tagLength');

  assert_false(
      SubtleCrypto.supports('encrypt', {
        name: 'ChaCha20-Poly1305',
        iv: new Uint8Array(10),
        tagLength: 128,
      }),
      'ChaCha20-Poly1305 encrypt with invalid iv');
}, 'supports returns false for algorithm objects with invalid parameters');


done();