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}