Quick Start Guide

Side-channel claim limit. Nothing on this page claims constant-time behaviour or side-channel resistance for any target: the side-channel harness covers nothing (finding A48) and no measurement exists. The Rust and C cores are designed for constant time and unmeasured; managed runtimes (JIT, GC, bounds checks) make no timing claim. Where this page names constant-time or side-channel techniques, in prose or in code, they are design intent or recommendations, not measured properties.

One post-quantum round trip per language, through the package each target ships. Every snippet on this page was run against a locally built candidate of the 1.0.0-rc.7 tree (the runs are recorded in the source repository’s documents/public-release/evidence/229-documentation.md); the coordinates are the decided public names, which resolve nowhere until the launch publishes them. See the Installation Guide for building from source. A Korean draft of this page, awaiting owner review, is at 빠른 시작.

Profiles are explicit: ml-kem-768, ml-dsa-65, falcon-512.r3-padded and the other catalog identifiers name one algorithm, one parameter set and one wire encoding each, and a family name (ml-dsa) is refused rather than substituted. ML-DSA, SLH-DSA, HAETAE and AIMer sign under a context string of at most 255 bytes; a signature made under one context does not verify under another.

Rust

[dependencies]
metamui-crypto = "1.0.0-rc.7"
rand = "0.8"
use metamui_crypto::{falcon512, mldsa65, mlkem768, Profile};

fn main() -> Result<(), metamui_crypto::Error> {
    let mut rng = rand::rngs::OsRng;

    let kp = falcon512::generate_keypair(&mut rng)?;
    let sig = falcon512::sign_padded(&kp.secret_key, b"hello", &mut rng)?;
    falcon512::verify_padded(&kp.public_key, b"hello", &sig)?;

    let kem = mlkem768::generate_keypair(&mut rng)?;
    let (ct, ss) = mlkem768::encapsulate(&kem.encapsulation_key, &mut rng)?;
    assert_eq!(mlkem768::decapsulate(&kem.decapsulation_key, &ct)?, ss);

    let dsa = mldsa65::generate_keypair(&mut rng)?;
    let sig = mldsa65::sign(&dsa.secret_key, b"hello", b"my-protocol/v1", &mut rng)?;
    mldsa65::verify(&dsa.public_key, b"hello", b"my-protocol/v1", &sig)?;
    assert!(mldsa65::verify(&dsa.public_key, b"hello", b"", &sig).is_err()); // another context

    assert!(Profile::parse("haetae").is_err()); // a family is not a profile
    Ok(())
}

Python

pip install metamui-crypto==1.0.0rc7
from metamui_crypto.facade import profile

sig = profile("ml-dsa-65")
keys = sig.generate_keypair()
signature = sig.sign(keys.secret_key, b"message", context=b"my-app")
sig.verify(keys.public_key, b"message", signature, context=b"my-app")   # raises InvalidSignatureError on failure

kem = profile("ml-kem-768")
ek, dk = kem.generate_keypair()
ct, ss = kem.encapsulate(ek)
assert kem.decapsulate(dk, ct) == ss

TypeScript

npm install @metamui/crypto@1.0.0-rc.7
import { falcon512, mldsa65, mlkem768, init } from '@metamui/crypto';

await init();   // optional: compiles the WebAssembly up front

const message = new TextEncoder().encode('hello');
const signer = await falcon512.generateKeyPair();
const signature = await falcon512.signPadded(signer.secretKey, message);
await falcon512.verifyPadded(signer.publicKey, message, signature);   // throws InvalidSignatureError if wrong

const ctx = new TextEncoder().encode('metamui/example/v1');
const dsa = await mldsa65.generateKeyPair();
const sig = await mldsa65.sign(dsa.secretKey, message, ctx);
await mldsa65.verify(dsa.publicKey, message, ctx, sig);

const receiver = await mlkem768.generateKeyPair();
const { ciphertext, sharedSecret } = await mlkem768.encapsulate(receiver.encapsulationKey);
const same = await mlkem768.decapsulate(receiver.decapsulationKey, ciphertext);

Swift

// Package.swift
dependencies: [
    .package(url: "https://github.com/SovereignWallet-Network/metamui-crypto", exact: "1.0.0-rc.7")
],
targets: [
    .executableTarget(name: "app", dependencies: [.product(name: "MetaMUICrypto", package: "metamui-crypto")])
]
import Foundation
import MetaMUICrypto

let message = Data("hello".utf8)

let profile = try Profile.parse("ml-dsa-65")          // exact id; "ml-dsa" is refused
let dsa = profile.contextSignature!                   // nil for a KEM profile
let keys = try dsa.generateKeyPair()
let context = Data("my-protocol/v1".utf8)            // required: "" is the empty context
let signature = try dsa.sign(message: message, context: context, secretKey: keys.secretKey)
try dsa.verify(message: message, context: context, signature: signature, publicKey: keys.publicKey)

let kem = try Profile.parse("ml-kem-768").kem!
let pair = try kem.generateKeyPair()
let enc = try kem.encapsulate(publicKey: pair.publicKey)
let shared = try kem.decapsulate(secretKey: pair.secretKey, ciphertext: enc.ciphertext)
assert(shared == enc.sharedSecret)

Go

go get github.com/SovereignWallet-Network/metamui-crypto/metamui-crypto-go@v1.0.0-rc.7
package main

import (
	"bytes"
	"fmt"

	"github.com/SovereignWallet-Network/metamui-crypto/metamui-crypto-go/mlkem"
)

func main() {
	kem := mlkem.New(mlkem.MLKEM768)
	pk, sk, err := kem.GenerateKeyPair()
	if err != nil {
		panic(err)
	}
	ct, ss, err := kem.Encapsulate(pk)
	if err != nil {
		panic(err)
	}
	ss2, err := kem.Decapsulate(sk, ct)
	if err != nil {
		panic(err)
	}
	fmt.Println(bytes.Equal(ss, ss2))
}

Java

<dependency>
  <groupId>id.metamui.crypto</groupId>
  <artifactId>metamui-pqc</artifactId>
  <version>1.0.0-rc7</version>   <!-- what the reactor builds; not on Maven Central yet -->
</dependency>
import id.metamui.crypto.mlkem.MLKem;
import id.metamui.crypto.mlkem.MLKem768;

public class App {
    public static void main(String[] args) {
        MLKem kem = new MLKem768();
        MLKem.KeyPair keys = kem.generateKeyPair();
        MLKem.EncapsulationResult enc = kem.encapsulate(keys.getPublicKey());
        byte[] shared = kem.decapsulate(keys.getSecretKey(), enc.getCiphertext());
        System.out.println(java.util.Arrays.equals(shared, enc.getSharedSecret()));
    }
}

Kotlin

dependencies {
    implementation("id.metamui.crypto:metamui-crypto-kotlin:1.0.0-rc7")   // what the build publishes; not on Maven Central yet
}
import id.metamui.crypto.mlkem.MLKem768

fun main() {
    val kem = MLKem768()
    val keys = kem.generateKeypair()
    val (ciphertext, shared) = kem.encapsulate(keys.publicKey)
    val recovered = kem.decapsulate(keys.privateKey, ciphertext)
    println(recovered == shared)
}

C#

dotnet add package MetaMUI.Crypto.MLKEM --version 1.0.0-rc.7
using MetaMUI.Crypto.MLKEM;

var kem = new MLKEM768();                                         // ML-KEM-768 (FIPS 203)
(byte[] publicKey, byte[] privateKey) = kem.GenerateKeyPair();
(byte[] ciphertext, byte[] sharedSecret) = kem.Encapsulate(publicKey);
byte[] recovered = kem.Decapsulate(ciphertext, privateKey);
Console.WriteLine(sharedSecret.AsSpan().SequenceEqual(recovered));

C

The C API reference carries the build, install and linking recipe and compiled examples for each module; its code blocks are quoted from files the C tree compiles and runs under ctest.

What these examples do not show

What’s next?

  1. Supported algorithms — the catalog’s 49 profiles in 16 families
  2. Platform guides
  3. API reference
  4. Security scope

Need help?