Add the dependency
In your project’s ziran.toml; pin ref to a commit for reproducible builds.
[dependencies.crypto]
git = "https://github.com/ziranlang/crypto.git"
ref = "master"crypto/src/crypto.zi
crypto
Import with #import "crypto/crypto".
Equal :: (a: []u8, b: []u8) -> boolWipe :: (bytes: []u8)Pbkdf2 :: (password: []u8, salt: []u8, iterations: s32, output: []u8) -> boolArbitrary salt length and output length; no silent truncation.
crypto/src/sha256.zi
sha256
Ordinary library procedures retain package-qualified native symbols. A consuming executable owns any explicit C ABI it chooses to export. SHA-256 and HMAC-SHA-256, extracted from Waozi’s Daochi implementation. Portable Ziran; no foreign cryptographic implementation.
Import with #import "crypto/sha256".
Sha256Context :: struct { state: [8]u32; bit_length: u64; block: [64]u8; block_length: s32; words: [64]u32; }Sha256RoundConstants: [64]u32Sha256RotateRight :: (value: u32, bits: u32) -> u32Sha256Transform :: (context: *Sha256Context)The buffered block. Each loader reads the block's 16 big-endian words where it lies; Sha256Rounds hashes them.
Sha256TransformBlock :: (context: *Sha256Context, block: []u8)One 64-byte block from a slice, so portable bundles can hash too.
Sha256TransformAt :: (context: *Sha256Context, block: *u8)One 64-byte block read in place at BLOCK, for the pointer forms. Without a bounds check per byte, a package hashes as fast on phones, which build at -Oz, as it did with Daochi Client's own SHA-256.
Sha256Rounds :: (context: *Sha256Context)The message schedule from the block's first 16 words, then the 64 rounds.
Sha256Initialize :: (context: *Sha256Context)Sha256Update :: (context: *Sha256Context, data: *u8, length: s64)Sha256UpdateBytes :: (context: *Sha256Context, data: []u8)Bytes from a slice, for portable bundles; Sha256Update takes a pointer.
Sha256Finish :: (context: *Sha256Context, output: *u8)Sha256FinishBytes :: (context: *Sha256Context, output: []u8)The digest into a slice of 32 bytes, for portable bundles.
Sha256 :: (data: *u8, length: s64, output: *u8)HexCharacter :: (value: u8) -> u8HexNibble :: (value: u8) -> s32BytesToHex :: (bytes: *u8, length: s64, output: *u8, output_size: s64) -> s32HexToBytes :: (hex: string, output: *u8, output_size: s64) -> s32Sha256Hex :: (data: *u8, length: s64, output: *u8)HmacBlockBytes :: 64HMAC-SHA-256 and PBKDF2 keep the account key-file derivation format. Historical PBKDF2 exports included at most 32 salt bytes.
Sha256DigestBytes :: 32Sha256UpdateText :: (context: *Sha256Context, value: string)HmacSha256Input :: (key: *u8, key_length: s64, key_text: string, use_key_text: bool, data: *u8, data_length: s64, text: string, use_text: bool, output: *u8) -> s32HmacSha256 :: (key: *u8, key_length: s64, data: *u8, data_length: s64, output: *u8) -> s32HmacSha256Text :: (key: *u8, key_length: s64, data: string, output: *u8) -> s32Sha256Of :: (data: string) -> [32]u8String forms, by value, for callers that hash text: a string's digest, HMAC-SHA-256 under a string key, and PBKDF2-HMAC-SHA-256's first block, such as a vault key. Each matches the byte forms above.
HmacSha256Of :: (key: string, message: string) -> [32]u8Pbkdf2Sha256 :: (password: string, salt: string, iterations: s32) -> [32]u8HmacSha256TextKey :: (key: string, data: *u8, data_length: s64, output: *u8) -> s32crypto/src/sha1.zi
sha1
SHA-1 is used only where Telegram's legacy key-exchange format requires it.
Import with #import "crypto/sha1".
Context :: struct { state: [5]u32; block: [64]u8; used: s32; length: u64; }Rotate :: (x: u32, n: u32) -> u32Transform :: (c: *Context)Start :: (c: *Context)Update :: (c: *Context, bytes: []u8)Finish :: (c: *Context, output: []u8) -> boolSha1 :: (bytes: []u8, output: []u8) -> boolcrypto/src/aes.zi
aes
FIPS 197 AES-256. The S-box uses fixed field arithmetic, avoiding secret-indexed lookup tables. The IGE mode is Telegram's specified mode.
Import with #import "crypto/aes".
Key :: struct { bytes: [240]u8; valid: bool; }Multiply :: (left: u8, right: u8) -> u8Inverse :: (x: u8) -> u8Rotate :: (x: u8, n: u32) -> u8Sub :: (x: u8) -> u8Unsub :: (x: u8) -> u8Expand :: (bytes: []u8) -> KeyAdd :: (state: []u8, key: *Key, round: s32)Shift :: (state: []u8, decrypt: bool)Mix :: (state: []u8, decrypt: bool)Block :: (key: *Key, input: []u8, output: []u8, decrypt: bool) -> boolIge :: (key_bytes: []u8, iv: []u8, input: []u8, output: []u8, decrypt: bool) -> boolcrypto/src/bigint.zi
bigint
Fixed-width unsigned 2048-bit Montgomery arithmetic. Sixteen-bit limbs keep every product within u64 on all native targets. Exponent bits select results with masks; both multiplications execute for every bit.
Import with #import "crypto/bigint".
Integer :: struct { limbs: [128]u32; }Modulus :: struct { value: Integer; squared: Integer; inverse: u32; valid: bool; }FromBytes :: (bytes: []u8) -> IntegerToBytes :: (value: *Integer, bytes: []u8) -> boolCompare :: (a: *Integer, b: *Integer) -> s32Subtract :: (a: *Integer, b: *Integer) -> IntegerReduce :: (value: *Integer, modulus: *Integer, high: u32) -> IntegerDouble :: (value: *Integer, modulus: *Integer) -> IntegerPrepare :: (bytes: []u8) -> ModulusMultiply :: (a: *Integer, b: *Integer, modulus: *Modulus) -> IntegerPower :: (base_bytes: []u8, exponent: []u8, modulus: *Modulus, output: []u8) -> boolProduct :: (left: []u8, right: []u8, modulus: *Modulus, output: []u8) -> boolDifference :: (left: []u8, right: []u8, modulus: *Modulus, output: []u8) -> boolcrypto/src/sha512.zi
sha512
FIPS 180-4 SHA-512 and HMAC-SHA-512 in portable Ziran.
Import with #import "crypto/sha512".
Context :: struct { state: [8]u64; block: [128]u8; used: s32; length: u64; }The 80 round constants as high and low 32-bit halves, as portable
ConstantHalves: [160]u32Constant :: (index: s32) -> u64Rotate :: (x: u64, n: u64) -> u64Transform :: (context: *Context)Start :: (context: *Context)Update :: (context: *Context, bytes: []u8)Finish :: (context: *Context, output: []u8) -> boolSha512 :: (input: []u8, output: []u8) -> boolHmac :: (key: []u8, input: []u8, output: []u8) -> boolPbkdf2 :: (password: []u8, salt: []u8, iterations: s32, output: []u8) -> bool