Skip to documentation
SLOP

tiny.reticulum.crypto.cbc

Reference tiny.reticulum crypto cbc

Defined in crypto.

API (5)

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

No direct callersNo direct callscryptocbc
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/reticulum/src/crypto/cbc.zig

zig
const std = @import("std");pub const block_length: u8 = 16;pub const max_input_length: u16 = 65_520;pub const CbcError = error{    InputTooLong,    InvalidLength,    OutputTooSmall,    OverlappingBuffers,};/// AES-128 in cipher block chaining mode for the sealed message format this/// package encrypts into (*token*) under a 32-byte key, following/// Reticulum@1.5.0 RNS/Cryptography/AES.py:43-76.pub const Aes128Cbc = Cbc(std.crypto.core.aes.Aes128);/// AES-256 in cipher block chaining mode for the sealed message format this/// package encrypts into (*token*) under a 64-byte key, following/// Reticulum@1.5.0 RNS/Cryptography/AES.py:78-111.pub const Aes256Cbc = Cbc(std.crypto.core.aes.Aes256);fn Cbc(comptime Cipher: type) type {    return struct {        pub const Key = [Cipher.key_bits / 8]u8;        pub fn encrypt(            key: Key,            iv: [block_length]u8,            plaintext: []const u8,            out: []u8,        ) CbcError![]u8 {            const result = try checkedOutput(plaintext, out);            const cipher = Cipher.initEnc(key);            var chain = iv;            var offset: usize = 0;            while (offset < plaintext.len) : (offset += block_length) {                var block = plaintext[offset..][0..block_length].*;                xor(&block, chain);                cipher.encrypt(result[offset..][0..block_length], &block);                chain = result[offset..][0..block_length].*;            }            return result;        }        pub fn decrypt(            key: Key,            iv: [block_length]u8,            ciphertext: []const u8,            out: []u8,        ) CbcError![]u8 {            const result = try checkedOutput(ciphertext, out);            const cipher = Cipher.initDec(key);            var chain = iv;            var offset: usize = 0;            while (offset < ciphertext.len) : (offset += block_length) {                const encrypted = ciphertext[offset..][0..block_length].*;                var block: [block_length]u8 = undefined;                cipher.decrypt(&block, &encrypted);                xor(&block, chain);                result[offset..][0..block_length].* = block;                chain = encrypted;            }            return result;        }    };}fn checkedOutput(input: []const u8, out: []u8) CbcError![]u8 {    if (input.len > max_input_length) return error.InputTooLong;    if (input.len % block_length != 0) return error.InvalidLength;    if (out.len < input.len) return error.OutputTooSmall;    const result = out[0..input.len];    if (partiallyOverlaps(input, result)) return error.OverlappingBuffers;    return result;}fn partiallyOverlaps(input: []const u8, output: []u8) bool {    if (input.len == 0) return false;    const input_start = @intFromPtr(input.ptr);    const output_start = @intFromPtr(output.ptr);    if (input_start == output_start) return false;    const input_end = input_start + input.len;    const output_end = output_start + output.len;    return input_start < output_end and output_start < input_end;}fn xor(block: *[block_length]u8, chain: [block_length]u8) void {    for (block, chain) |*byte, previous| byte.* ^= previous;}

Source: lib/reticulum/src/crypto/root.zig:45

zig
pub const cbc = @import("cbc.zig");

Audit

Definitions6
Public names6
Members4
Version26.7.0
Revisiondaab053ee433