//! SME-scoped Tip5 permutation.
//!
//! The public surface is [`tip5_permute_sme`], a batched permutation that
//! runs N independent Tip5 states inside a single [`Stream`] scope.
//!
//! ## Status (2026-05-22)
//!
//! Phase 1 โ API + correctness only. The current body opens a streaming-mode
//! context (so that downstream callers can rely on the lifetime contract and
//! the bit-identity gate is in place) and then permutes each state with the
//! existing scalar kernel. This guarantees the output is byte-identical to
//! N independent [`super::tip5_permute`] calls. Phase 2 (planned) replaces
//! the inner loop with batched SSVE arithmetic, which is the genuine
//! algorithmic win.
//!
//! ## Why a Stream is still useful at N=1
//!
//! Holding a live [`Stream`] is the contract under which any future SSVE /
//! SMOPA kernel can land here without changing callers. Stream construction
//! costs are ~30โ80 cycles (SMSTART + ZA enable), which dominates only on
//! very small batches; for the trisha Merkle-layer use (thousands of pairs
//! per batch) this is far below the per-permutation cost.
//!
//! ## Why SMOPA itself does not (yet) accelerate Tip5
//!
//! Tip5's MDS layer is implemented as a fixed 16-input butterfly network
//! (`Tip5::generated_function`) of `wrapping_add` / `wrapping_sub` /
//! `wrapping_mul` on `u64`. The multiplies all have small signed
//! coefficients (|c| < 2^17) but the operand is full 64-bit. The natural
//! SME widening primitive on M4 (SMOPA INT16 โ INT32) computes outer
//! products of pairs of INT16 lanes, which is structurally a matrix
//! multiply, not an element-wise wide-scalar broadcast. Mapping
//! `wrapping_mul(u64, i17_const)` onto SMOPA requires either reverting
//! `generated_function` to a direct 16ร16 matrix-vector product (which
//! breaks raw-Montgomery bit-identity with the reference) or carrying out
//! a four-limb decomposition that costs more than the original scalar
//! multiply. The honest path is therefore to leave the algorithm as-is
//! and harvest the parallel-lane win via SSVE (8ร u64 lanes per Z reg at
//! SVL=512), which is on the roadmap as phase 2.
use crateStream;
use tip5_permute;
/// Permute `N` independent Tip5 states inside one streaming-mode scope.
///
/// Bit-identical to calling [`tip5_permute`] `N` times. The streaming-mode
/// scope is opened once for the entire batch; per-permutation cost is the
/// scalar permute cost plus an amortized fraction of `SMSTART`/`SMSTOP`.
///
/// Returns an error only if the host lacks FEAT_SME; on every shipping
/// Apple SME implementation that path is taken cleanly.
///
/// # Example
///
/// ```no_run
/// use acpu::field::tip5::tip5_permute_sme;
///
/// let mut states = [[0u64; 16]; 8];
/// tip5_permute_sme::<8>(&mut states).expect("FEAT_SME required");
/// ```
// ---------------------------------------------------------------------------
// Tests โ correctness only. Performance is covered by `bench/tip5.rs`.
// ---------------------------------------------------------------------------