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.
Zig › std/ › crypto/ › ml_dsa.zig › Poly
Poly
ml_dsa.Poly
const Poly = struct
File
Code
const Poly = struct {
cs : [N ]u32 ,
const zero : Poly = .{ .cs = @splat (0 ) };
fn add (a : Poly , b : Poly ) Poly {
var ret : Poly = undefined ;
for (0 ..N ) |i | {
ret .cs [i ] = a .cs [i ] + b .cs [i ];
}
return ret ;
}
fn sub (a : Poly , b : Poly ) Poly {
var ret : Poly = undefined ;
for (0 ..N ) |i | {
ret .cs [i ] = a .cs [i ] +% (@as (u32 , 2 * Q ) -% b .cs [i ]);
}
return ret ;
}
fn reduceLe2Q (p : Poly ) Poly {
var ret = p ;
for (0 ..N ) |i | {
ret .cs [i ] = le2Q (ret .cs [i ]);
}
return ret ;
}
fn normalize (p : Poly ) Poly {
var ret = p ;
for (0 ..N ) |i | {
ret .cs [i ] = modQ (ret .cs [i ]);
}
return ret ;
}
fn normalizeAssumingLe2Q (p : Poly ) Poly {
var ret = p ;
for (0 ..N ) |i | {
ret .cs [i ] = le2qModQ (ret .cs [i ]);
}
return ret ;
}
fn mulHat (a : Poly , b : Poly ) Poly {
var ret : Poly = undefined ;
for (0 ..N ) |i | {
ret .cs [i ] = montReduceLe2Q (@as (u64 , a .cs [i ]) * @as (u64 , b .cs [i ]));
}
return ret ;
}
fn ntt (p : Poly ) Poly {
var ret = p ;
ret .nttInPlace ();
return ret ;
}
fn nttInPlace (p : *Poly ) void {
var k : usize = 0 ;
var l : usize = N / 2 ;
while (l > 0 ) : (l >>= 1 ) {
var offset : usize = 0 ;
while (offset < N - l ) : (offset += 2 * l ) {
k += 1 ;
const zeta : u64 = zetas [k ];
for (offset ..offset + l ) |j | {
const t = montReduceLe2Q (zeta * @as (u64 , p .cs [j + l ]));
p .cs [j + l ] = p .cs [j ] +% (2 * Q -% t );
p .cs [j ] +%= t ;
}
}
}
}
fn invNTT (p : Poly ) Poly {
var ret = p ;
ret .invNTTInPlace ();
return ret ;
}
fn invNTTInPlace (p : *Poly ) void {
var k : usize = 0 ;
var l : usize = 1 ;
while (l < N ) : (l <<= 1 ) {
var offset : usize = 0 ;
while (offset < N - l ) : (offset += 2 * l ) {
const zeta : u64 = inv_zetas [k ];
k += 1 ;
for (offset ..offset + l ) |j | {
const t = p .cs [j ];
p .cs [j ] = t +% p .cs [j + l ];
p .cs [j + l ] = montReduceLe2Q (zeta * @as (u64 , t +% 256 * Q -% p .cs [j + l ]));
}
}
}
for (0 ..N ) |j | {
p .cs [j ] = montReduceLe2Q (@as (u64 , R_OVER_256 ) * @as (u64 , p .cs [j ]));
}
}
fn power2RoundPoly (p : Poly ) struct { t0 : Poly , t1 : Poly } {
var t0 = Poly .zero ;
var t1 = Poly .zero ;
for (0 ..N ) |i | {
const result = power2Round (p .cs [i ]);
t0 .cs [i ] = result .a0_plus_q ;
t1 .cs [i ] = result .a1 ;
}
return .{ .t0 = t0 , .t1 = t1 };
}
fn exceeds (p : Poly , bound : u32 ) bool {
var result : u32 = 0 ;
for (0 ..N ) |i | {
const x = @as (i32 , @intCast ((Q - 1 ) / 2 )) - @as (i32 , @intCast (p .cs [i ]));
const abs_x = x ^ (x >> 31 );
const norm = @as (i32 , @intCast ((Q - 1 ) / 2 )) - abs_x ;
const exceeds_bit = @intFromBool (@as (u32 , @intCast (norm )) >= bound );
result |= exceeds_bit ;
}
return result != 0 ;
}
}