code wiki / _hdl_build / nx_rsa_pkcs1_sign.nx

nx_rsa_pkcs1_sign.nx

buildroot/runtime/_hdl_build/nx_rsa_pkcs1_sign.nx

10503 B229 linesdepth 9pulls 17 transitivereach 3 importersview sourcekind tooltopic rsa
docsdependenciesstructsconstsfunctions

about

nx_rsa_pkcs1_sign.nx -- F103e RUNG 8: RSASSA-PKCS1-v1_5 SIGNING with SHA-256. The estate shipped the VERIFY half years-equivalent ago and never the sign half, because its modexp took the exponent as an i64 (fine for e = 65537, impossible for d ~2048 bits). Rung 4 removed that; rung 7 produces the key. This is the join. RFC 8017 EMSA-PKCS1-v1_5, k = 256 (RSA-2048): EM = 0x00 || 0x01 || PS(0xFF * 202) || 0x00 || DigestInfo(19) || H(32) = 256 bytes s = EM^d mod n ★THE 19-BYTE DIGESTINFO PREFIX IS COMPOSED, NOT RETYPED. `rsa_pkcs1_sha256_di_byte` already encodes it in the incumbent verifier; copying those bytes into this file by hand would be a recalled constant AND a second source of truth that can drift. ★★★★★★**IF THE VERIFIER AND THE SIGNER DISAGREE ABOUT A CONSTANT, EVERY SIGNATURE IS INVALID AND BOTH FILES LOOK CORRECT.** ★THE ORACLE IS THE INCUMBENT VERIFIER. Every tooth signs with this code and verifies with `rsa_pkcs1_v1_5_sha256_verify` -- two independently written halves meeting in the middle. That is a far stronger statement than any self-check, and it is why no golden vector is needed for the round trip. ⚠It does NOT prove byte-agreement with another implementation's signatures; PKCS#1 v1.5 is deterministic so that IS checkable later against a known vector, and is named as owed. Usage: nx_rsa_pkcs1_sign selftest (~5 min: generates a real 2048-bit modulus first) Exit: 0 GREEN | 1 RED. Log -> knowledge/status/nishi_os.log, verdict= LAST. license_tier: ORIGINAL

dependencies 12 imports · 3 importers

nx_syscalls.nx nx_sha256.nx nx_u2048.nx nx_u2048_mul.nx nx_rsa2048_mod.nx nx_rsa2048_mod_exp.nx nx_rsa2048_mont.nx nx_rsa2048_mod_exp_big.nx nx_rsa_pkcs1_v1_5_sha256.nx nx_u2048_millerrabin.nx nx_rsa_pkcs1_sign.nx nx_authenticode_sign.nx nx_efivars_enrol.nx nx_x509_emit.nx

diagram shows first 10 each side; +2 more imports, +0 more importers in the complete lists below.

imports: nx_syscalls.nxnx_sha256.nxnx_u2048.nxnx_u2048_mul.nxnx_rsa2048_mod.nxnx_rsa2048_mod_exp.nxnx_rsa2048_mont.nxnx_rsa2048_mod_exp_big.nxnx_rsa_pkcs1_v1_5_sha256.nxnx_u2048_millerrabin.nxnx_u2048_smallops.nxnx_rsa_keygen.nx

imported by: nx_authenticode_sign.nxnx_efivars_enrol.nxnx_x509_emit.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main ps_selftest ps_p sys_write u2048_alloc sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sys_mmap ↻ kg_keygen sys_mmap ↻ u2048_alloc ↻ u2048_one u2048_zero u2048_wide_alloc sys_mmap ↻ kg_gen_prime sys_mmap ↻ kg_fill nx_csprng_fill sys_mmap ↻ nx_csprng_urandom_path sys_openat_rd sys_read sys_close kg_rng_next u2048_load_be kg_trial_reject

structs

none

consts

37const PS_MAGIC_20260808: i64 = 20260808
38const PS_MAGIC_1024: i64 = 1024
39const PS_MAGIC_65537: i64 = 65537
41const PS_K: i64 = 256 // RSA-2048 modulus bytes
42const PS_TLEN: i64 = 51 // 19 DigestInfo + 32 SHA-256
43const PS_MINPAD: i64 = 8 // RFC 8017 floor for PS

functions

45func ps_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
called by 1: ps_selftest calls 1: sys_write
46func ps_fp(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
called by 1: ps_selftest calls 1: sys_write
47func ps_fn(fd: i64, v: i64) -> i64
called by 1: ps_selftest calls 2: sys_mmapsys_write
57func ps_eq_str(a: *u8, b: *u8) -> i64
65func rsa_pkcs1_v1_5_sha256_em(em: *u8, msg: *u8, msg_len: i64) -> i64
83func rsa_pkcs1_v1_5_sha256_sign(sig_out: *u8, msg: *u8, msg_len: i64, d: *i64, n: *i64) -> i64
95func ps_selftest() -> i64
227func main(argc: i64, argv: *i64) -> i64
calls 1: ps_selftest