Skip to main content

gmcrypto_core/
traits.rs

1//! In-crate streaming primitive traits.
2//!
3//! v0.3 W5 ships a small **in-crate** trait surface — [`Hash`],
4//! [`Mac`], [`BlockCipher`] — that the SM3 / HMAC-SM3 / SM4
5//! implementations all satisfy. Per Q7.3 / Q7.10, `RustCrypto`
6//! trait fit (`digest::Digest`, `digest::Mac`,
7//! `cipher::BlockEncrypt`/`BlockDecrypt`) is **deferred to v0.4**
8//! behind an opt-in feature flag. v0.3 stays `no_std` +
9//! zero-runtime-deps.
10//!
11//! # Posture
12//!
13//! These traits exist for ergonomic generic-over-our-types wiring,
14//! NOT as bound-on-public-API constraints. Don't take `T: Hash` on
15//! a public function — that would be a v1.0 `SemVer` surface.
16//! Implementations of these traits on types in this crate are
17//! additive; consumers can opt in if they want.
18//!
19//! # Lifecycle
20//!
21//! All three traits use the same shape:
22//!
23//! - `new()` (or `new(key)` for `Mac` / `BlockCipher`) constructs a
24//!   fresh instance.
25//! - `update(&mut self, &[u8])` absorbs input bytes (where applicable).
26//! - `finalize(self) -> Self::Output` consumes the instance and
27//!   produces the result (digest, MAC, or ciphertext).
28//!
29//! `BlockCipher` is shape-different: it operates per-block via
30//! `encrypt_block` / `decrypt_block` rather than a streaming
31//! update/finalize. Higher-level streaming modes (CBC, CTR) compose
32//! on top.
33
34/// A streaming hash function.
35pub trait Hash {
36    /// The fixed-size digest output.
37    type Output;
38
39    /// Construct a fresh hasher.
40    #[must_use]
41    fn new() -> Self;
42
43    /// Absorb input bytes.
44    fn update(&mut self, data: &[u8]);
45
46    /// Consume the hasher and produce the final digest.
47    fn finalize(self) -> Self::Output;
48}
49
50/// A streaming MAC (message authentication code).
51pub trait Mac {
52    /// The fixed-size MAC tag output.
53    type Output;
54
55    /// Construct a fresh MAC keyed with `key`.
56    #[must_use]
57    fn new(key: &[u8]) -> Self;
58
59    /// Absorb message bytes.
60    fn update(&mut self, data: &[u8]);
61
62    /// Consume the MAC instance and produce the final tag.
63    fn finalize(self) -> Self::Output;
64
65    /// Verify a candidate tag against the computed one in
66    /// constant-time. Returns `true` on match. Implementations MUST
67    /// use a constant-time comparison primitive (e.g.
68    /// `subtle::ConstantTimeEq`).
69    fn verify(self, expected: &Self::Output) -> bool
70    where
71        Self: Sized;
72}
73
74/// A symmetric block cipher (single-block primitive).
75///
76/// Higher-level modes (CBC, CTR, GCM) compose on top by chaining
77/// `encrypt_block` / `decrypt_block` calls; see
78/// [`crate::sm4::mode_cbc`] for the v0.2 single-shot CBC and
79/// [`crate::sm4::cbc_streaming`] for the v0.3 W5 streaming
80/// `Sm4CbcEncryptor` / `Sm4CbcDecryptor`.
81pub trait BlockCipher {
82    /// Block size in bytes (e.g. 16 for SM4).
83    const BLOCK_SIZE: usize;
84
85    /// Construct a cipher instance from a key.
86    #[must_use]
87    fn new(key: &[u8]) -> Self;
88
89    /// Encrypt one block in place.
90    fn encrypt_block(&self, block: &mut [u8]);
91
92    /// Decrypt one block in place.
93    fn decrypt_block(&self, block: &mut [u8]);
94}