Skip to main content

basil_cose/
hash.rs

1// SPDX-FileCopyrightText: 2026 OpenBasil Contributors
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! SHA3-256 request-hash helper (claim `-70002`).
6
7use sha3::{Digest, Sha3_256};
8
9/// A SHA3-256 digest of the complete tagged request bytes.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct RequestHash(pub [u8; 32]);
12
13/// SHA3-256 over the complete tagged request `COSE_Sign1` bytes.
14///
15/// Used by a responder when building the `-70002` claim and by a requester
16/// when checking a response against the request it sent.
17#[must_use]
18pub fn request_hash(request_cose_sign1: &[u8]) -> RequestHash {
19    RequestHash(Sha3_256::digest(request_cose_sign1).into())
20}
21
22#[cfg(test)]
23mod tests {
24    use super::*;
25
26    #[test]
27    fn matches_known_sha3_256_vector() {
28        // SHA3-256("") = a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
29        let RequestHash(digest) = request_hash(b"");
30        assert_eq!(
31            digest[..4],
32            [0xa7, 0xff, 0xc6, 0xf8],
33            "SHA3-256 empty-string prefix"
34        );
35        assert_eq!(digest[28..], [0x80, 0xf8, 0x43, 0x4a]);
36    }
37
38    #[test]
39    fn distinct_inputs_distinct_hashes() {
40        assert_ne!(request_hash(b"a").0, request_hash(b"b").0);
41        assert_eq!(request_hash(b"a").0, request_hash(b"a").0);
42    }
43}