code wiki / _hdl_build / nx_u2048_smallops.nx

nx_u2048_smallops.nx

buildroot/runtime/_hdl_build/nx_u2048_smallops.nx

11434 B270 linesdepth 3pulls 3 transitivereach 5 importersview sourcekind tooltopic u2048
docsdependenciesstructsconstsfunctions

about

nx_u2048_smallops.nx -- F103e RUNG 6: big-by-SMALL arithmetic (mul, div, mod, add). WHY THIS SHAPE, and not a general extended GCD: RSA needs d = e^-1 mod lambda(n). The textbook route is a binary extended GCD over 2048-bit values, which needs (x + m) >> 1 -- and x + m OVERFLOWS 2048 bits, while u2048_shr1 has no carry-in. That is a real trap, not a style choice. The route taken instead exploits the fact that **e is small** (65537). Write: k*lambda + 1 = d*e with k in [1, e-1] Then k = -(lambda mod e)^-1 mod e -- an inverse of a SMALL number modulo a SMALL number, solvable in plain i64 -- and d = (k*lambda + 1)/e, which is a big-by-small multiply and a big-by-small divide. Every intermediate fits in an i64 because the limbs are 32-bit: divide: rem < m <= 2^31, so (rem << 32) | limb < 2^63 -- proven by the bound, not hoped multiply: (2^32-1)*(2^31-1) + carry < 2^63 ★★★★★★ **THE PRIMITIVE YOU NEED IS OFTEN NARROWER THAN THE ONE THE TEXTBOOK NAMES — AND THE NARROW ONE CAN BE EXACTLY THE ONE THAT FITS IN THE REGISTERS YOU HAVE.** A general u2048 modinv is a much larger, more dangerous organ than this, and RSA does not need it. ★THE ORACLE IS PLAIN i64 ARITHMETIC. Every tooth loads a value that fits in 64 bits, runs the u2048 path, and demands agreement with the `*`, `/`, `%` the compiler already gives us. Two independent implementations; no recalled constants anywhere. Usage: nx_u2048_smallops selftest Exit: 0 GREEN | 1 RED. Log -> knowledge/status/nishi_os.log, verdict= LAST. license_tier: ORIGINAL

dependencies 2 imports · 5 importers

nx_syscalls.nx nx_u2048.nx nx_u2048_smallops.nx nx_authenticode_sign.nx nx_efivars_enrol.nx nx_rsa_keygen.nx nx_rsa_pkcs1_sign.nx nx_x509_emit.nx

imports: nx_syscalls.nxnx_u2048.nx

imported by: nx_authenticode_sign.nxnx_efivars_enrol.nxnx_rsa_keygen.nxnx_rsa_pkcs1_sign.nxnx_x509_emit.nx

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

main so_selftest 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 ↻ so_set_i64 sys_mmap ↻ u2048_load_be u2048_div_small so_low64 u2048_mod_small so_p sys_write ↻ so_fn sys_mmap ↻ sys_write ↻ u2048_mul_small u2048_add_small i64_modinv_small sys_openat_append so_fp sys_write ↻ sys_close sys_exit ↻

structs

none

consts

27const SO_MAGIC_65537: i64 = 65537
28const SO_MAGIC_4294967295: i64 = 4294967295
29const SO_MAGIC_4294967296: i64 = 4294967296
30const SO_MAGIC_1099511627776: i64 = 1099511627776
31const SO_MAGIC_9007199254740993: i64 = 9007199254740993
32const SO_MAGIC_123456789012345: i64 = 123456789012345
33const SO_MAGIC_1000003: i64 = 1000003
34const SO_MAGIC_2147483647: i64 = 2147483647
35const SO_MAGIC_1000000007: i64 = 1000000007
36const SO_MAGIC_12345: i64 = 12345
38const SO_LIMB_MASK: i64 = 0xFFFFFFFF
39const SO_MAX_SMALL: i64 = 2147483647 // 2^31-1: the bound the overflow proofs above assume

functions

41func so_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: so_selftest calls 1: sys_write
42func so_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: so_selftest calls 1: sys_write
43func so_fn(fd: i64, v: i64) -> i64
called by 1: so_selftest calls 2: sys_mmapsys_write
54func so_set_i64(x: *i64, v: i64) -> i64
64func so_low64(x: *i64) -> i64
called by 1: so_selftest
69func u2048_mul_small(out: *i64, a: *i64, k: i64) -> i64
called by 1: so_selftest
84func u2048_div_small(out: *i64, a: *i64, m: i64) -> i64
99func u2048_mod_small(a: *i64, m: i64) -> i64
113func u2048_add_small(out: *i64, a: *i64, k: i64) -> i64
called by 1: so_selftest
129func i64_modinv_small(a: i64, m: i64) -> i64
150func so_selftest() -> i64
268func main(argc: i64, argv: *i64) -> i64
calls 1: so_selftest