code wiki / (root) / nx_crc32_v1.nx

nx_crc32_v1.nx source

↩ module page · 97 lines · 3627 B

1// crc32.nx -- CRC-32 checksum (IEEE 802.3 + Castagnoli). 2// 3// Two widely-used variants: 4// 5// crc32 IEEE 802.3 polynomial 0xEDB88320 (reversed). 6// Used by: ZIP, PNG, gzip, Ethernet, PNG, Adler (old TCP). 7// 8// crc32c Castagnoli polynomial 0x82F63B78 (reversed). 9// Used by: iSCSI, SCTP, ZFS, BTRFS, Google Wire Format, 10// AWS S3 checksum-algorithm-CRC32C. Better error 11// detection + hardware-accelerated on x86 (CRC32Q op) 12// and ARMv8. 13// 14// Not cryptographic -- trivial to forge. Good only as an integrity 15// check against random bit-flips (storage, transmission). 16// 17// Algorithm: table-less bit-by-bit variant. 8 iterations per input 18// byte; each iteration xor-shifts the current CRC by 1 and 19// conditionally xors in the polynomial. ~50 CPU cycles per byte; 20// for high-throughput callers, a future 256-entry table lookup 21// lands when NishiLang gets proper const-array literals. 22// 23// Both variants start with CRC = 0xFFFFFFFF and end by xor'ing 24// with 0xFFFFFFFF (i.e., complement) -- matches every reference 25// implementation (zlib, CRC-32/BZIP2 identical handling). 26// 27// Invariants: 28// CRC1 Output is exact match for zlib's crc32() / crc32c() for 29// the same input. Known-answer: crc32("") = 0x00000000; 30// crc32("123456789") = 0xCBF43926; crc32c("123456789") = 31// 0xE3069283. 32// CRC2 Input read-only; returns u32 result packed into the low 33// 32 bits of i64. 34// CRC3 No branch on data: the "conditionally xor" is a mask- 35// multiply (0 or 1 times polynomial) -- not secret-time 36// critical (CRC isn't crypto) but keeps the loop shape 37// predictable. 38 39// nx_safety_envelope: 40// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 41// sil_target: SIL1 42// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 43// verdict: NOT_YET_EVALUATED 44 45import "nx_syscalls.nx" 46 47const CRC32_POLY: i64 = 0xEDB88320 48const CRC32C_POLY: i64 = 0x82F63B78 49const U32_MASK: i64 = 0xFFFFFFFF 50const U32_INIT: i64 = 0xFFFFFFFF 51 52// Core bit-by-bit CRC loop. Parameterised by polynomial so both 53// crc32 and crc32c share the kernel. 54func crc32_core(poly: i64, bytes: *u8, n: i64, initial: i64) -> i64 { 55 var crc: i64 = initial 56 var i: i64 = 0 57 while i < n { 58 crc = crc ^ bytes[i] 59 var bit: i64 = 0 60 while bit < 8 { 61 let lsb: i64 = crc & 1 62 let mask: i64 = 0 - lsb // 0 or all-ones 63 crc = ((crc >> 1) & 0x7FFFFFFFFFFFFFFF) ^ (mask & poly) 64 // NishiLang >> on i64 is arithmetic; mask high bits 65 // above 32 to keep the CRC a true u32. 66 crc = crc & U32_MASK 67 bit = bit + 1 68 } 69 i = i + 1 70 } 71 return crc & U32_MASK 72} 73 74// IEEE 802.3 / zlib CRC-32. 75func crc32(bytes: *u8, n: i64) -> i64 { 76 let raw: i64 = crc32_core(CRC32_POLY, bytes, n, U32_INIT) 77 return (raw ^ U32_INIT) & U32_MASK 78} 79 80// Castagnoli CRC-32C. 81func crc32c(bytes: *u8, n: i64) -> i64 { 82 let raw: i64 = crc32_core(CRC32C_POLY, bytes, n, U32_INIT) 83 return (raw ^ U32_INIT) & U32_MASK 84} 85 86// Compile-only smoke. Known answer crc32("123456789") = 0xCBF43926 87// from RFC 3720. We can't verify the numeric output without 88// execution; structure-check is what we have today. 89func main() -> i64 { 90 let msg: *u8 = "123456789" 91 let c1: i64 = crc32(msg, 9) 92 let c2: i64 = crc32c(msg, 9) 93 // Return xor of the two -- nonzero if they differ (they 94 // should; different polynomials). 95 if c1 == c2 { return 1 } 96 return 0 97}