code wiki / (root) / nx_hmac_sha512.nx

nx_hmac_sha512.nx source

↩ module page · 84 lines · 2647 B

1// hmac_sha512.nx -- HMAC-SHA-512 (RFC 2104 / FIPS 198-1). 2// 3// license_tier: INDEPENDENT_REDERIVE 4// genealogy_id: international-research-sources/nist/fips_198_1 5// 6// Completes the HMAC family: SHA-256, SHA-384, SHA-512. Used 7// where TLS cipher suites or key-derivation ladders want the 8// full 512-bit MAC width (relatively rare, but present in some 9// SSH / OpenPGP / JWT profiles). 10// 11// Differences from hmac.nx: 12// - Block size B = 128 bytes (SHA-512 block), not 64. 13// - Hash output = 64 bytes (SHA-512), not 32. 14// - Uses sha512_init instead of sha256_init. 15 16// nx_safety_envelope: 17// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 18// sil_target: SIL1 19// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 20// verdict: NOT_YET_EVALUATED 21 22import "nx_syscalls.nx" 23import "nx_sha512.nx" 24 25const HMAC512_BLOCK: i64 = 128 26const HMAC512_HASH: i64 = 64 27const IPAD_512: i64 = 0x36 28const OPAD_512: i64 = 0x5C 29 30func hmac_sha512(key: *u8, key_len: i64, msg: *u8, msg_len: i64, 31 out: *u8) -> i64 { 32 let kp: *u8 = sys_mmap(HMAC512_BLOCK) 33 var i: i64 = 0 34 while i < HMAC512_BLOCK { kp[i] = 0; i = i + 1 } 35 if key_len > HMAC512_BLOCK { 36 sha512_digest(key, key_len, kp) 37 } else { 38 var j: i64 = 0 39 while j < key_len { kp[j] = key[j]; j = j + 1 } 40 } 41 42 // Inner hash. 43 let inner_key: *u8 = sys_mmap(HMAC512_BLOCK) 44 let ii_raw: *u8 = sys_mmap(512) 45 let ii: *Sha512 = ii_raw as *Sha512 46 sha512_init(ii) 47 var b: i64 = 0 48 while b < HMAC512_BLOCK { 49 inner_key[b] = kp[b] ^ IPAD_512 50 b = b + 1 51 } 52 sha512_update(ii, inner_key, HMAC512_BLOCK) 53 sha512_update(ii, msg, msg_len) 54 let inner: *u8 = sys_mmap(HMAC512_HASH) 55 sha512_final(ii, inner) 56 57 // Outer hash. 58 let outer_key: *u8 = sys_mmap(HMAC512_BLOCK) 59 let oi_raw: *u8 = sys_mmap(512) 60 let oi: *Sha512 = oi_raw as *Sha512 61 sha512_init(oi) 62 b = 0 63 while b < HMAC512_BLOCK { 64 outer_key[b] = kp[b] ^ OPAD_512 65 b = b + 1 66 } 67 sha512_update(oi, outer_key, HMAC512_BLOCK) 68 sha512_update(oi, inner, HMAC512_HASH) 69 sha512_final(oi, out) 70 return 0 71} 72 73// Compile-only smoke. RFC 4231 test case 1: key = 0x0b*20, 74// data = "Hi There" -> 87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2 75// ce8f99401b2d9c29f88e3ac8 etc. 76func main() -> i64 { 77 let key: *u8 = sys_mmap(20) 78 let msg: *u8 = "Hi There" 79 let tag: *u8 = sys_mmap(64) 80 var i: i64 = 0 81 while i < 20 { key[i] = 0x0B; i = i + 1 } 82 hmac_sha512(key, 20, msg, 8, tag) 83 return tag[0] as i64 84}