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.

Aegis128XGeneric

AEGIS is a very fast authenticated encryption system built on top of the core AES function.

The 128 bits variants of AEGIS have a 128 bit key and a 128 bit nonce.

https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead/

aegis.Aegis128XGeneric
fn Aegis128XGeneric(comptime degree: u7, comptime tag_bits: u9) type

File

lib/std/crypto/aegis.zig:274

Code

fn Aegis128XGeneric(comptime degree: u7, comptime tag_bits: u9) type {
    comptime assert(degree > 0); // degree must be greater than 0
    comptime assert(tag_bits == 128 or tag_bits == 256); // tag must be 128 or 256 bits

    return struct {
        const State = State128X(degree);

        pub const tag_length = tag_bits / 8;
        pub const nonce_length = 16;
        pub const key_length = 16;
        pub const block_length = State.rate;

        const alignment = State.alignment;

        /// c: ciphertext: output buffer should be of size m.len
        /// tag: authentication tag: output MAC
        /// m: message
        /// ad: Associated Data
        /// npub: public nonce
        /// k: private key
        pub fn encrypt(c: []u8, tag: *[tag_length]u8, m: []const u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) void {
            assert(c.len == m.len);
            var state = State.init(key, npub);
            var src: [block_length]u8 align(alignment) = undefined;
            var dst: [block_length]u8 align(alignment) = undefined;
            var i: usize = 0;
            while (i + block_length <= ad.len) : (i += block_length) {
                state.absorb(ad[i..][0..block_length]);
            }
            if (ad.len % block_length != 0) {
                @memset(src[0..], 0);
                @memcpy(src[0 .. ad.len % block_length], ad[i..][0 .. ad.len % block_length]);
                state.absorb(&src);
            }
            i = 0;
            while (i + block_length <= m.len) : (i += block_length) {
                state.enc(c[i..][0..block_length], m[i..][0..block_length]);
            }
            if (m.len % block_length != 0) {
                @memset(src[0..], 0);
                @memcpy(src[0 .. m.len % block_length], m[i..][0 .. m.len % block_length]);
                state.enc(&dst, &src);
                @memcpy(c[i..][0 .. m.len % block_length], dst[0 .. m.len % block_length]);
            }
            tag.* = state.finalize(tag_bits, ad.len, m.len);
        }

        /// `m`: Message
        /// `c`: Ciphertext
        /// `tag`: Authentication tag
        /// `ad`: Associated data
        /// `npub`: Public nonce
        /// `k`: Private key
        /// Asserts `c.len == m.len`.
        ///
        /// Contents of `m` are undefined if an error is returned.
        pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) AuthenticationError!void {
            assert(c.len == m.len);
            var state = State.init(key, npub);
            var src: [block_length]u8 align(alignment) = undefined;
            var i: usize = 0;
            while (i + block_length <= ad.len) : (i += block_length) {
                state.absorb(ad[i..][0..block_length]);
            }
            if (ad.len % block_length != 0) {
                @memset(src[0..], 0);
                @memcpy(src[0 .. ad.len % block_length], ad[i..][0 .. ad.len % block_length]);
                state.absorb(&src);
            }
            i = 0;
            while (i + block_length <= m.len) : (i += block_length) {
                state.dec(m[i..][0..block_length], c[i..][0..block_length]);
            }
            if (m.len % block_length != 0) {
                state.decLast(m[i..], c[i..]);
            }
            var computed_tag = state.finalize(tag_bits, ad.len, m.len);
            const verify = crypto.timing_safe.eql([tag_length]u8, computed_tag, tag);
            if (!verify) {
                crypto.secureZero(u8, &computed_tag);
                @memset(m, undefined);
                return error.AuthenticationFailed;
            }
        }
    };
}