An arm64-compatible Swift Package for Argon2 password hashing and key derivation.
Every existing Swift Argon2 package chains to P-H-C/phc-winner-argon2 as a remote
SPM dependency using .branch("master"). That upstream package includes
blamka-round-opt.h, which unconditionally includes <emmintrin.h> (SSE2). On
arm64 — iOS devices and Apple Silicon simulators — Clang cannot load the
_Builtin_intrinsics.intel.sse2 module, producing a fatal build error:
Module '_Builtin_intrinsics.intel.sse2' requires feature 'x86'
This package fixes the problem by vendoring the argon2 C reference sources directly
(ref.c, not opt.c) and never placing SSE2 headers anywhere in the include tree.
It has zero transitive dependencies, so SPM resolution is instant and hermetic.
| Platform | Minimum version |
|---|---|
| iOS | 16.0 |
| macOS | 13.0 |
| tvOS | 16.0 |
| watchOS | 9.0 |
Swift 5.7 or later. Swift Package Manager only.
// Package.swift
.package(url: "https://github.com/dugleelabs/swift-argon2", from: "1.0.0")
// Target dependency
.product(name: "Argon2", package: "swift-argon2")import Argon2
// Derive a 32-byte key from a password (production parameters)
// Always call from a background thread — this is CPU-intensive.
let key = try await Task.detached(priority: .userInitiated) {
try Argon2.hash(
password: Data("my-password".utf8),
salt: saltData, // 32 random bytes, stored server-side
iterations: 3,
memory: 524_288, // 512 MiB in KiB
parallelism: 4,
outputLength: 32,
variant: .id // Argon2id — recommended
)
}.valuepublic enum Argon2 {
public enum Variant { case d, i, id }
public enum Error: Swift.Error {
case hashingFailed(code: Int32, message: String)
}
/// Derives a fixed-length key from a password.
public static func hash(
password: Data,
salt: Data,
iterations: Int,
memory: Int, // KiB
parallelism: Int,
outputLength: Int = 32,
variant: Variant = .id
) throws -> Data
}| Parameter | Recommended | Notes |
|---|---|---|
variant |
.id |
RFC 9106 and OWASP default; use .i only if side-channel resistance required without GPU resistance |
iterations |
3 | Increase to raise time cost; protocol-defined — don't change unilaterally |
memory |
524_288 | 512 MiB; reduces to fit device constraints only with protocol agreement |
parallelism |
4 | Should match available CPU threads |
outputLength |
32 | 32 bytes = 256-bit key |
salt |
32 random bytes | Generate with var salt = [UInt8](repeating: 0, count: 32); SecRandomCopyBytes(kSecRandomDefault, 32, &salt) |
- Output is byte-identical to Python
argon2.low_level.hash_secret_rawat identical parameters — both call the same C reference implementation. - This package uses
ref.c(reference compression function) rather thanopt.c(x86 SSE2-optimised). There is no performance difference on arm64 (the optimised path cannot run there); on x86 the reference path is measurably slower, which is an accepted trade-off for arm64 compatibility. - Argon2 version 1.3 (
0x13) is hardcoded. Version 1.0 is not supported. - For background reading: RFC 9106, OWASP Password Storage Cheat Sheet.
The phc-winner-argon2 C sources are vendored at commit
f57e61e19229e23c4445b85494dbf7c07de721cb (2021-06-25) under CC0 1.0 / Apache-2.0.
See Sources/CArgon2/VENDORED.md for the full file
list and update procedure.
This package is released under the Apache License 2.0.
The bundled C sources (Sources/CArgon2/) are copyright their original authors
(Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, Samuel Neves) and are
available under CC0 1.0 Universal / Apache License 2.0.