referredBlockIndex method
Finds a block using rules describes in the specification.
Implementation
@visibleForTesting
(int, int) referredBlockIndex({
required int iteration,
required int slice,
required int lane,
required int index,
required int j1,
required int j2,
}) {
final blocksPerLane = blockCount ~/ parallelism;
final blocksPerSegment = blocksPerLane ~/ 4;
// In the RFC 9106:
// l = J_2 mod p
//
// During the first segment of the first iteration,
// the current lane is used.
var referenceLane = j2 % parallelism;
if (iteration == 0 && slice == 0) {
referenceLane = lane;
}
// Index of the first possible block.
var candidatesStart = 0;
// Number of possible blocks.
var candidatesLength = 0;
if (iteration == 0) {
if (slice == 0 || referenceLane == lane) {
candidatesLength = slice * blocksPerSegment + index - 1;
} else {
candidatesLength = slice * blocksPerSegment;
if (index == 0) {
candidatesLength--;
}
}
} else {
// This is not the first iteration.
candidatesStart = ((slice + 1) % 4) * blocksPerSegment;
candidatesLength = 3 * blocksPerSegment;
// The previous blocks of the same segment are candidates if:
// * This is the first slice of the first iteration
// * OR the current lane is the reference lane
if (referenceLane == lane) {
candidatesLength += index - 1;
} else if (index == 0) {
candidatesLength--;
}
}
final zz = referredBlockIndexZZ(j1, candidatesLength);
final z = (candidatesStart + candidatesLength - 1 - zz) % blocksPerLane;
return (referenceLane, z);
}