Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
318 changes: 318 additions & 0 deletions ext/nettle/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
const std = @import("std");

// Builds GNU Nettle's symmetric/hash library (libnettle) from the gnutls/nettle
// source tarball. Only the `nettle_SOURCES` set is compiled: it covers the SHA,
// RIPEMD160, AES (ECB/CBC) and CMAC/CTR primitives that urcrypt needs, and none
// of it depends on GMP (that's libhogweed, which we don't build).
//
// The upstream git tarball ships no `configure`, so `config.h` and `version.h`
// (normally produced by configure) are vendored under `gen/`. They were
// generated with:
//
// ./.bootstrap && ./configure --disable-shared --disable-assembler \
// --disable-fat --disable-documentation --disable-openssl
//
// The result is a portable, pure-C build (no per-CPU assembly, runtime CPU
// dispatch disabled). The vendored config.h is valid for 64-bit little-endian
// unix targets (macos/linux, aarch64/x86_64).
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const dep_c = b.dependency("nettle", .{
.target = target,
.optimize = optimize,
});

const lib = b.addLibrary(.{
.name = "nettle",
.root_module = b.createModule(.{ .target = target, .optimize = optimize }),
});

lib.linkLibC();

// SIZEOF_LONG / SIZEOF_SIZE_T are target-dependent (long is 4 bytes on
// LLP64 Windows, 8 on LP64 unix), so they're derived from the target here
// rather than hardcoded in the vendored config.h.
const long_bytes = target.result.cTypeByteSize(.long);
const size_t_bytes = target.result.ptrBitWidth() / 8;

// alloca lives in <alloca.h> on unix but in <malloc.h> on Windows; pick the
// header the same target-driven way (config.h's alloca block keys off these).
const is_windows = target.result.os.tag == .windows;
const has_alloca_h: u1 = if (is_windows) 0 else 1;
const has_malloc_h: u1 = if (is_windows) 1 else 0;

// vendored config.h + version.h (see comment above)
lib.addIncludePath(b.path("gen"));
// nettle source root (nettle-types.h, sha2.h, macros.h, ...)
lib.addIncludePath(dep_c.path(""));

lib.addCSourceFiles(.{
.root = dep_c.path(""),
.flags = &.{
"-O2",
"-fno-omit-frame-pointer",
"-fno-sanitize=all",
"-DHAVE_CONFIG_H=1",
b.fmt("-DSIZEOF_LONG={d}", .{long_bytes}),
b.fmt("-DSIZEOF_SIZE_T={d}", .{size_t_bytes}),
b.fmt("-DHAVE_ALLOCA_H={d}", .{has_alloca_h}),
b.fmt("-DHAVE_MALLOC_H={d}", .{has_malloc_h}),
},
.files = &.{
"aes-decrypt-internal.c",
"aes-decrypt-table.c",
"aes128-decrypt.c",
"aes192-decrypt.c",
"aes256-decrypt.c",
"aes-encrypt-internal.c",
"aes-encrypt-table.c",
"aes128-encrypt.c",
"aes192-encrypt.c",
"aes256-encrypt.c",
"aes-invert-internal.c",
"aes-set-key-internal.c",
"aes128-set-encrypt-key.c",
"aes128-set-decrypt-key.c",
"aes128-meta.c",
"aes192-set-encrypt-key.c",
"aes192-set-decrypt-key.c",
"aes192-meta.c",
"aes256-set-encrypt-key.c",
"aes256-set-decrypt-key.c",
"aes256-meta.c",
"nist-keywrap.c",
"arcfour.c",
"arctwo.c",
"arctwo-meta.c",
"blowfish.c",
"blowfish-bcrypt.c",
"balloon.c",
"balloon-sha1.c",
"balloon-sha256.c",
"balloon-sha384.c",
"balloon-sha512.c",
"base16-encode.c",
"base16-decode.c",
"base64-encode.c",
"base64-decode.c",
"base64url-encode.c",
"base64url-decode.c",
"buffer.c",
"buffer-init.c",
"camellia-crypt-internal.c",
"camellia-table.c",
"camellia-absorb.c",
"camellia-invert-key.c",
"camellia128-set-encrypt-key.c",
"camellia128-crypt.c",
"camellia128-set-decrypt-key.c",
"camellia128-meta.c",
"camellia192-meta.c",
"camellia256-set-encrypt-key.c",
"camellia256-crypt.c",
"camellia256-set-decrypt-key.c",
"camellia256-meta.c",
"cast128.c",
"cast128-meta.c",
"cbc.c",
"cbc-aes128-encrypt.c",
"cbc-aes192-encrypt.c",
"cbc-aes256-encrypt.c",
"ccm.c",
"ccm-aes128.c",
"ccm-aes192.c",
"ccm-aes256.c",
"cfb.c",
"siv-cmac.c",
"siv-cmac-aes128.c",
"siv-cmac-aes256.c",
"siv-gcm.c",
"siv-gcm-aes128.c",
"siv-gcm-aes256.c",
"cnd-memcpy.c",
"chacha-crypt.c",
"chacha-core-internal.c",
"chacha-poly1305.c",
"chacha-poly1305-meta.c",
"chacha-set-key.c",
"chacha-set-nonce.c",
"ctr.c",
"ctr16.c",
"des.c",
"des3.c",
"eax.c",
"eax-aes128.c",
"eax-aes128-meta.c",
"ghash-set-key.c",
"ghash-update.c",
"siv-ghash-set-key.c",
"siv-ghash-update.c",
"gcm.c",
"gcm-aes128.c",
"gcm-aes128-meta.c",
"gcm-aes192.c",
"gcm-aes192-meta.c",
"gcm-aes256.c",
"gcm-aes256-meta.c",
"gcm-camellia128.c",
"gcm-camellia128-meta.c",
"gcm-camellia256.c",
"gcm-camellia256-meta.c",
"gcm-sm4.c",
"gcm-sm4-meta.c",
"cmac.c",
"cmac64.c",
"cmac-aes128.c",
"cmac-aes256.c",
"cmac-des3.c",
"cmac-aes128-meta.c",
"cmac-aes256-meta.c",
"cmac-des3-meta.c",
"gost28147.c",
"gosthash94.c",
"gosthash94-meta.c",
"hmac-internal.c",
"hmac-gosthash94.c",
"hmac-md5.c",
"hmac-ripemd160.c",
"hmac-sha1.c",
"hmac-sha224.c",
"hmac-sha256.c",
"hmac-sha384.c",
"hmac-sha512.c",
"hmac-streebog.c",
"hmac-sm3.c",
"hmac-md5-meta.c",
"hmac-ripemd160-meta.c",
"hmac-sha1-meta.c",
"hmac-sha224-meta.c",
"hmac-sha256-meta.c",
"hmac-sha384-meta.c",
"hmac-sha512-meta.c",
"hmac-gosthash94-meta.c",
"hmac-streebog-meta.c",
"hmac-sm3-meta.c",
"knuth-lfib.c",
"hkdf.c",
"md2.c",
"md2-meta.c",
"md4.c",
"md4-meta.c",
"md5.c",
"md5-meta.c",
"memeql-sec.c",
"memxor.c",
"memxor3.c",
"nettle-lookup-hash.c",
"nettle-meta-aeads.c",
"nettle-meta-ciphers.c",
"nettle-meta-hashes.c",
"nettle-meta-macs.c",
"ocb.c",
"ocb-aes128.c",
"pbkdf2.c",
"pbkdf2-hmac-gosthash94.c",
"pbkdf2-hmac-sha1.c",
"pbkdf2-hmac-sha256.c",
"pbkdf2-hmac-sha384.c",
"pbkdf2-hmac-sha512.c",
"poly1305-aes.c",
"poly1305-internal.c",
"poly1305-update.c",
"realloc.c",
"ripemd160.c",
"ripemd160-compress.c",
"ripemd160-meta.c",
"salsa20-core-internal.c",
"salsa20-crypt-internal.c",
"salsa20-crypt.c",
"salsa20r12-crypt.c",
"salsa20-set-key.c",
"salsa20-set-nonce.c",
"salsa20-128-set-key.c",
"salsa20-256-set-key.c",
"sha1.c",
"sha1-compress.c",
"sha1-meta.c",
"sha256.c",
"sha256-compress-n.c",
"sha224-meta.c",
"sha256-meta.c",
"sha512.c",
"sha512-compress.c",
"sha384-meta.c",
"sha512-meta.c",
"sha512-224-meta.c",
"sha512-256-meta.c",
"sha3.c",
"sha3-permute.c",
"sha3-224.c",
"sha3-224-meta.c",
"sha3-256.c",
"sha3-256-meta.c",
"sha3-384.c",
"sha3-384-meta.c",
"sha3-512.c",
"sha3-512-meta.c",
"sha3-shake.c",
"shake128.c",
"shake256.c",
"sm3.c",
"sm3-meta.c",
"serpent-set-key.c",
"serpent-encrypt.c",
"serpent-decrypt.c",
"serpent-meta.c",
"streebog.c",
"streebog-meta.c",
"twofish.c",
"twofish-meta.c",
"sm4.c",
"sm4-meta.c",
"umac-nh.c",
"umac-nh-n.c",
"umac-l2.c",
"umac-l3.c",
"umac-poly64.c",
"umac-poly128.c",
"umac-set-key.c",
"umac32.c",
"umac64.c",
"umac96.c",
"umac128.c",
"version.c",
"write-be32.c",
"write-le32.c",
"write-le64.c",
"yarrow256.c",
"yarrow_key_event.c",
"xts.c",
"xts-aes128.c",
"xts-aes256.c",
"drbg-ctr-aes256.c",
"slh-shake.c",
"slh-sha256.c",
"slh-fors.c",
"slh-merkle.c",
"slh-wots.c",
"slh-xmss.c",
"slh-dsa.c",
"slh-dsa-128s.c",
"slh-dsa-128f.c",
"slh-dsa-shake-128s.c",
"slh-dsa-shake-128f.c",
"slh-dsa-sha2-128s.c",
"slh-dsa-sha2-128f.c",
},
});

// public headers, consumed as <nettle/foo.h>
lib.installHeadersDirectory(dep_c.path(""), "nettle", .{
.include_extensions = &.{".h"},
});
lib.installHeader(b.path("gen/version.h"), "nettle/version.h");

b.installArtifact(lib);
}
14 changes: 14 additions & 0 deletions ext/nettle/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.{
.name = .nettle,
.fingerprint = 0x91db718f652369c8,
.version = "0.0.1",
.dependencies = .{
.nettle = .{
.url = "https://github.com/gnutls/nettle/archive/refs/tags/nettle_4.0_release_20260205.tar.gz",
.hash = "N-V-__8AAHcjZwChQdAC62bRM5ZDzApJg_-9Z2TqoX8_fJok",
},
},
.paths = .{
"",
},
}
Loading
Loading