Swift API Reference

Complete API documentation for MetaMUI Crypto Primitives in Swift.

Installation

No package is published on a public registry yet (release candidate 1.0.0-rc.7); the coordinates below are the decided public names. Until the launch publishes them, build from the source tree (see the Installation Guide) or install a locally built candidate. The snippet was run against such a candidate; the run is recorded in the source repository’s documents/public-release/evidence/229-documentation.md.

// Package.swift — Apple platforms only (macOS 12+, iOS 15+, tvOS 15+, watchOS 8+)
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")])
]

In Xcode: File → Add Package Dependencies, enter the repository URL, choose the exact version and add the MetaMUICrypto product (or an algorithm product such as MetaMUIMLKem).

Quick Start

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)

API Documentation

For detailed API documentation, see:

Available Modules

Hash Functions

import MetaMUICrypto

// Simple hashing
let hash = SHA256.hash(data: messageData)
let blake3Hash = Blake3.hash(data: messageData)

// Streaming hash
var hasher = Blake3.Hasher()
hasher.update(data: chunk1)
hasher.update(data: chunk2)
let finalHash = hasher.finalize()

Digital Signatures

// Ed25519
let keypair = try Ed25519.generateKeypair()
let signature = try keypair.sign(message)
let isValid = try keypair.verify(signature: signature, message: message)

// Post-quantum signatures
let pqKeypair = try Dilithium.generateKeypair()
let pqSignature = try pqKeypair.sign(message)

Encryption

// ChaCha20-Poly1305
let key = ChaCha20Poly1305.generateKey()
let sealed = try ChaCha20Poly1305.seal(plaintext, using: key)
let decrypted = try ChaCha20Poly1305.open(sealed, using: key)

// AES-256-GCM
let aesKey = AES256.generateKey()
let aesSealed = try AES256.seal(plaintext, using: aesKey)

Key Exchange

// X25519 ECDH
let alice = try X25519.generateKeypair()
let bob = try X25519.generateKeypair()
let sharedSecret = try alice.computeSharedSecret(
    with: bob.publicKey
)

// Post-quantum KEM
let kemKeypair = try MLKem768.generateKeypair()
let (ciphertext, sharedSecret) = try MLKem768.encapsulate(
    to: kemKeypair.publicKey
)

Key Derivation

// Password hashing
let salt = Argon2.generateSalt()
let hash = try Argon2.hash(
    password: password,
    salt: salt,
    memory: 256 * 1024, // 256MB
    iterations: 4,
    parallelism: 2
)

// Key derivation
let derivedKey = try HKDF.deriveKey(
    from: inputKey,
    salt: salt,
    info: "encryption key".data(using: .utf8)!,
    outputByteCount: 32
)

SwiftUI Integration

import SwiftUI
import MetaMUICrypto

struct SecureView: View {
    @State private var isUnlocked = false
    @State private var password = ""
    
    private let secureStorage = SecureStorage()
    
    var body: some View {
        if isUnlocked {
            Text("Secure Content")
        } else {
            SecureField("Password", text: $password)
                .onSubmit {
                    unlock()
                }
        }
    }
    
    private func unlock() {
        Task {
            do {
                let isValid = try await secureStorage.verify(password)
                await MainActor.run {
                    isUnlocked = isValid
                }
            } catch {
                print("Unlock failed: \(error)")
            }
        }
    }
}

Combine Support

import Combine
import MetaMUICrypto

class CryptoService: ObservableObject {
    @Published var isEncrypting = false
    
    func encrypt(_ data: Data) -> AnyPublisher<Data, Error> {
        Future { promise in
            Task {
                do {
                    let key = ChaCha20Poly1305.generateKey()
                    let sealed = try ChaCha20Poly1305.seal(data, using: key)
                    promise(.success(sealed.combined))
                } catch {
                    promise(.failure(error))
                }
            }
        }
        .eraseToAnyPublisher()
    }
}

Async/Await

All CPU-intensive operations support async/await:

// Async key generation
let keypair = try await Ed25519.generateKeypair()

// Async encryption
let encrypted = try await ChaCha20Poly1305.seal(
    plaintext,
    using: key
)

// Async password hashing
let hash = try await Argon2.hash(
    password: password,
    salt: salt
)

Error Handling

enum CryptoError: Error {
    case invalidKey
    case decryptionFailed
    case verificationFailed
    case insufficientMemory
}

do {
    let decrypted = try ChaCha20Poly1305.open(sealed, using: key)
} catch CryptoError.decryptionFailed {
    print("Decryption failed - data may be corrupted")
} catch CryptoError.invalidKey {
    print("Invalid key provided")
} catch {
    print("Unexpected error: \(error)")
}

Keychain Integration

import Security

extension Ed25519.Keypair {
    func saveToKeychain(identifier: String) throws {
        let query: [String: Any] = [
            kSecClass as String: kSecClassKey,
            kSecAttrApplicationTag as String: identifier,
            kSecValueData as String: privateKey
        ]
        
        let status = SecItemAdd(query as CFDictionary, nil)
        guard status == errSecSuccess else {
            throw KeychainError.saveFailed(status)
        }
    }
    
    static func loadFromKeychain(identifier: String) throws -> Data {
        let query: [String: Any] = [
            kSecClass as String: kSecClassKey,
            kSecAttrApplicationTag as String: identifier,
            kSecReturnData as String: true
        ]
        
        var result: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &result)
        
        guard status == errSecSuccess,
              let data = result as? Data else {
            throw KeychainError.loadFailed(status)
        }
        
        return data
    }
}

Performance

Hardware Acceleration

// Automatically uses hardware acceleration when available
let hash = SHA256.hash(data: largeData) // Uses Apple's CryptoKit internally

// Force software implementation
let hash = SHA256.hash(data: largeData, useHardware: false)

Batch Operations

let signatures = try Ed25519.batchSign(
    messages: messages,
    privateKey: privateKey
)

let results = try Ed25519.batchVerify(
    signatures: signatures,
    messages: messages,
    publicKeys: publicKeys
)

Memory Security

// Secure memory allocation
let secureData = SecureData(count: 32)
defer { secureData.clear() }

// Automatic clearing with property wrapper
@SecureStorage var privateKey: Data

// Manual clearing
var sensitiveData = Data(repeating: 0, count: 32)
defer { sensitiveData.withUnsafeMutableBytes { $0.initializeMemory(as: UInt8.self, repeating: 0) } }

Examples

Secure File Storage

class SecureFileManager {
    private let key: SymmetricKey
    
    init(password: String) throws {
        let salt = UserDefaults.standard.data(forKey: "salt") ?? {
            let newSalt = Argon2.generateSalt()
            UserDefaults.standard.set(newSalt, forKey: "salt")
            return newSalt
        }()
        
        self.key = try Argon2.deriveKey(
            from: password,
            salt: salt,
            outputByteCount: 32
        )
    }
    
    func save(_ data: Data, to url: URL) throws {
        let sealed = try AES256.seal(data, using: key)
        try sealed.combined.write(to: url)
    }
    
    func load(from url: URL) throws -> Data {
        let sealedData = try Data(contentsOf: url)
        let sealedBox = try AES256.SealedBox(combined: sealedData)
        return try AES256.open(sealedBox, using: key)
    }
}

Network Security

class SecureAPIClient {
    private let signingKey: Ed25519.Keypair
    
    init() throws {
        self.signingKey = try Ed25519.generateKeypair()
    }
    
    func makeRequest(_ request: URLRequest) async throws -> Data {
        var signedRequest = request
        
        // Sign request body
        if let body = request.httpBody {
            let signature = try signingKey.sign(body)
            signedRequest.setValue(
                signature.base64EncodedString(),
                forHTTPHeaderField: "X-Signature"
            )
            signedRequest.setValue(
                signingKey.publicKey.base64EncodedString(),
                forHTTPHeaderField: "X-Public-Key"
            )
        }
        
        let (data, _) = try await URLSession.shared.data(for: signedRequest)
        return data
    }
}

See Also