Skip to main content

Module bitsliced

Module bitsliced 

Source
Available on crate feature 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 every D(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.rs is checked against the table it came from over its entire input domain;
  • tests/bitsliced_differential.rs compares batch output against crate::scramble / crate::descramble over randomised payloads and lengths, in both directions;
  • tests/golden_vectors.rs runs 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 LANES payloads per pass with one control word.
scramble_batch
Scramble (encrypt) up to LANES payloads per pass with one control word.