Add the dependency

In your project’s ziran.toml; pin ref to a commit for reproducible builds.

[dependencies.oqs]
git = "https://github.com/ziranlang/oqs.git"
ref = "master"

Overview

ziran add https://github.com/ziranlang/oqs.git
#import "oqs/Oqs"

Sign :: (message: []u8) -> bool {
    public_key: [MlDsa44PublicKeyBytes]u8
    secret_key: [MlDsa44SecretKeyBytes]u8
    signature: [MlDsa44SignatureBytes]u8
    if !MlDsa44KeyPair(public_key[:], secret_key[:]) { return false }
    length := MlDsa44Sign(signature[:], message, secret_key[:])
    return length > 0 &&
        MlDsa44Verify(message, signature[0:length], public_key[:])
}
Procedure Does
MlDsa44KeyPair(public_key, secret_key) Makes an ML-DSA-44 (FIPS 204) key pair
MlDsa44Sign(signature, message, secret_key) Signs; returns the signature's length, or -1
MlDsa44Verify(message, signature, public_key) Checks a signature
RandomBytes(output) Fills bytes from the system's secure random source
Cleanse(memory) Zeroes secrets in a way the compiler keeps

MlKem768KeyPair, MlKem768Encapsulate, and MlKem768Decapsulate provide ML-KEM-768 (FIPS 203) key exchange. Their key, ciphertext and shared-secret sizes are the MlKem768*Bytes constants. Decapsulation of an altered ciphertext produces a different shared secret; its success result alone does not authenticate a peer.

The wrappers take slices and refuse buffers too small for keys, signatures, ciphertexts or shared secrets, and lengths a 32-bit size_t cannot hold. The current API covers ML-DSA-44 and ML-KEM-768, secure random bytes and secret cleansing. It does not expose every algorithm in liboqs.

Linking liboqs

The repository contains the Ziran API. The complete original liboqs source is a Git source dependency pinned to an exact commit in ziran.lock; ziran fetch --locked retrieves it and ziran pkg path liboqs locates it. This serves the same purpose as an upstream submodule through Ziran's package system.

Build the pinned static and shared libraries on Linux:

make native

Then link with LDFLAGS=-L/path/to/build/native LDLIBS=-loqs. Go uses cgo (CGO_ENABLED=1); Rust carries the flags in its generated Cargo project. Python uses ctypes and the shared liboqs.so; add that directory to LD_LIBRARY_PATH when running it. C and C++ call the same native ABI.

make check builds the libraries and exercises signing, tamper rejection, empty messages, key exchange, random bytes, cleansing and short-buffer rejection on C, C++, Go, Rust and Python, from source and saved .zir. make check TARGET=go selects one backend. A C compiler, CMake, Python, Go and Cargo are required for the full check. The portable .zib VM does not call arbitrary C libraries; this package requires a native backend.

oqs/src/Oqs.zi

Oqs

Post-quantum signatures and key exchange from liboqs for Ziran. The package pins liboqs as a source dependency; a build links the static library it builds from `ziran pkg path liboqs`. The Makefile enables ML-DSA-44 signatures and ML-KEM-768 key exchange. Lengths cross into C as size_t, which is 32 bits on some targets, so the wrappers take slices and refuse lengths that do not fit.

Import with #import "oqs/Oqs".

MlDsa44PublicKeyBytes :: 1312

Sizes of ML-DSA-44 (FIPS 204) keys and signatures, in bytes.

MlDsa44SecretKeyBytes :: 2560
MlDsa44SignatureBytes :: 2420
MlKem768PublicKeyBytes :: 1184
MlKem768SecretKeyBytes :: 2400
MlKem768CiphertextBytes :: 1088
MlKem768SharedSecretBytes :: 32
OqsSuccess :: 0
MlDsa44KeyPair :: (public_key: []u8, secret_key: []u8) -> bool

Fills a new key pair. Both slices must be at least the key sizes.

MlDsa44Sign :: (signature: []u8, message: []u8, secret_key: []u8) -> s64

Signs `message` with `secret_key` into `signature`, which must hold MlDsa44SignatureBytes. Returns the signature's length, or -1.

MlDsa44Verify :: (message: []u8, signature: []u8, public_key: []u8) -> bool

Whether `signature` signs `message` for `public_key`.

RandomBytes :: (output: []u8)

Fills `output` from the system's secure random source.

Cleanse :: (memory: []u8)

Zeroes `memory` in a way the compiler does not remove, for keys and other secrets about to be released.

MlKem768KeyPair :: (public_key: []u8, secret_key: []u8) -> bool

ML-KEM-768 (FIPS 203) exchanges a 32-byte shared secret.

MlKem768Encapsulate :: (ciphertext: []u8, shared_secret: []u8, public_key: []u8) -> bool
MlKem768Decapsulate :: (shared_secret: []u8, ciphertext: []u8, secret_key: []u8) -> bool

Source ↗