bitsliced only.Expand description
Bitsliced fast path — LANES payloads scrambled or descrambled at once.
§What is actually parallel in CSA2
Bitslicing transposes the data so that bit i of every lane lives in one
machine word, then evaluates the cipher as a boolean circuit; every gate
then operates on all LANES lanes at once. That only pays off where the
algorithm has real independence, and CSA2 has less of it than it looks:
- Block cipher, scramble.
C[i] = E(P[i] ^ C[i+1])— a reverse CBC. Block i cannot start until block i+1 is finished, so there is no parallelism within one payload. - Block cipher, descramble.
P[i] = D(C[i]) ^ C[i+1]. The chaining XOR uses the ciphertext of the next block, which is already in the buffer, so everyD(C[i])is independent — this half is parallel within a single payload. - Stream cipher. Two chained 40-bit shift registers; round n+1 needs round n’s state. Sequential within one payload, in both directions.
Two of those three are sequential within a payload, and the stream cipher —
the sequential one — is about two thirds of the total work. So the honest
unit of parallelism for CSA2 is the payload, not the block: this module
exposes a batch API that scrambles or descrambles up to LANES
independent payloads (TS packets, typically) in one pass. There is no
bitsliced single-payload entry point, because for a single payload there is
nothing worth slicing.
§Correctness
The bitsliced path is bit-exact with the scalar path — it is the same cipher, re-expressed. Three independent gates hold it there:
- every generated circuit in
src/bitsliced/circuits.rsis checked against the table it came from over its entire input domain; tests/bitsliced_differential.rscompares batch output againstcrate::scramble/crate::descrambleover randomised payloads and lengths, in both directions;tests/golden_vectors.rsruns the libdvbcsa known-answer vectors through the batch API too, so the fast path answers to the external oracle and not merely to our own scalar code.
§Example
use dvb_csa::{ControlWord, bitsliced, descramble, scramble};
let cw = ControlWord::from_bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
let mut packets = [[0xAAu8; 184], [0xBBu8; 184], [0xCCu8; 184]];
let expected = packets;
let mut batch: [&mut [u8]; 3] = {
let [a, b, c] = &mut packets;
[a.as_mut_slice(), b.as_mut_slice(), c.as_mut_slice()]
};
bitsliced::scramble_batch(&cw, &mut batch);
bitsliced::descramble_batch(&cw, &mut batch);
assert_eq!(packets, expected);Constants§
- LANES
- Number of payloads processed per bitsliced pass — the slicing width.
Functions§
- descramble_
batch - Descramble (decrypt) up to
LANESpayloads per pass with one control word. - scramble_
batch - Scramble (encrypt) up to
LANESpayloads per pass with one control word.