Skip to main content

script/dom/webcrypto/subtlecrypto/
kangarootwelve_operation.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use k12::{CustomRefKt128, CustomRefKt256, ExtendableOutput, Update};
6
7use crate::dom::bindings::error::Error;
8use crate::dom::subtlecrypto::{CryptoAlgorithm, SubtleKangarooTwelveParams};
9
10/// <https://wicg.github.io/webcrypto-modern-algos/#kangarootwelve-operations-digest>
11pub(crate) fn digest(
12    normalized_algorithm: &SubtleKangarooTwelveParams,
13    message: &[u8],
14) -> Result<Vec<u8>, Error> {
15    // Step 1. Let outputLength be the outputLength member of normalizedAlgorithm.
16    let output_length = normalized_algorithm.output_length;
17
18    // Step 2. If outputLength is zero or is not a multiple of 8, then throw an OperationError.
19    if output_length == 0 || !output_length.is_multiple_of(8) {
20        return Err(Error::Operation(Some(
21            "The outputLength is zero or is not a multiple of 8".into(),
22        )));
23    }
24
25    // Step 3. Let customization be the customization member of normalizedAlgorithm if present or
26    // the empty octet string otherwise.
27    let customization = normalized_algorithm
28        .customization
29        .as_deref()
30        .unwrap_or_default();
31
32    // Step 4.
33    // If the name member of normalizedAlgorithm is a case-sensitive string match for "KT128":
34    //     Let result be the result of performing the KT128 function defined in Section 3 of
35    //     [RFC9861] using message as the M input parameter, customization as the C input parameter,
36    //     and outputLength divided by 8 as the L input parameter.
37    // If the name member of normalizedAlgorithm is a case-sensitive string match for "KT256":
38    //     Let result be the result of performing the KT256 function defined in Section 3 of
39    //     [RFC9861] using message as the M input parameter, customization as the C input parameter,
40    //     and outputLength divided by 8 as the L input parameter.
41    // Step 5. If performing the operation results in an error, then throw an OperationError.
42    let mut result = vec![0u8; output_length as usize / 8];
43    match normalized_algorithm.name {
44        CryptoAlgorithm::Kt128 => {
45            let mut hasher = CustomRefKt128::new_customized(customization);
46            hasher.update(message);
47            hasher.finalize_xof_into(&mut result);
48        },
49        CryptoAlgorithm::Kt256 => {
50            let mut hasher = CustomRefKt256::new_customized(customization);
51            hasher.update(message);
52            hasher.finalize_xof_into(&mut result);
53        },
54        algorithm_name => {
55            return Err(Error::NotSupported(Some(format!(
56                "{} is not supported",
57                algorithm_name.as_str()
58            ))));
59        },
60    }
61
62    // Step 6. Return result.
63    Ok(result)
64}