Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

power2Round

Splits 0 ≤ a < Q into a0 and a1 with a = a1*2^D + a0 and -2^(D-1) < a0 ≤ 2^(D-1). Returns a0 + Q and a1. FIPS 204: Power2Round (Algorithm 19)

ml_dsa.power2Round
fn power2Round(a: u32) struct

File

lib/std/crypto/ml_dsa.zig:791

Code

fn power2Round(a: u32) struct { a0_plus_q: u32, a1: u32 } {
    // We effectively compute a0 = a mod± 2^D
    //                    and a1 = (a - a0) / 2^D
    var a0 = a & ((1 << D) - 1); // a mod 2^D

    // a0 is one of 0, 1, ..., 2^(D-1)-1, 2^(D-1), 2^(D-1)+1, ..., 2^D-1
    a0 -%= (1 << (D - 1)) + 1;
    // now a0 is -2^(D-1)-1, -2^(D-1), ..., -2, -1, 0, ..., 2^(D-1)-2

    // Next, add 2^D to those a0 that are negative (seen as i32)
    a0 +%= @as(u32, @bitCast(@as(i32, @bitCast(a0)) >> 31)) & (1 << D);
    // now a0 is 2^(D-1)-1, 2^(D-1), ..., 2^D-2, 2^D-1, 0, ..., 2^(D-1)-2

    a0 -%= (1 << (D - 1)) - 1;
    // now a0 is 0, 1, 2, ..., 2^(D-1)-1, 2^(D-1), -2^(D-1)+1, ..., -1

    const a0_plus_q = Q +% a0;
    const a1 = (a -% a0) >> D;

    return .{ .a0_plus_q = a0_plus_q, .a1 = a1 };
}