code wiki / (root) / nx_x25519.nx

nx_x25519.nx

buildroot/runtime/nx_x25519.nx

21500 B541 linesdepth 3pulls 3 transitivereach 915 importersview sourcekind tooltopic x25519
docsdependenciesstructsconstsfunctions

about

x25519.nx -- Bernstein's Curve25519 X25519 (RFC 7748). Elliptic-curve Diffie-Hellman on Curve25519 in Montgomery form. Primary classical KEX for TLS 1.3, SSH, Signal, WireGuard, and every modern protocol that cares about correctness. Hybrid- deploys alongside ML-KEM-768 for post-quantum TLS 1.3 (RFC 9578 X25519Kyber768Draft00). Field: GF(p) with p = 2^255 - 19. Curve equation: y^2 = x^3 + 486662*x^2 + x (Montgomery form). Scalar input: 32 bytes, clamped per RFC 7748 §5. u-coordinate input: 32 bytes, high bit cleared per §5. Output: 32-byte shared secret. Representation: 10 x 25.5-bit limbs (Bernstein ref10 style). Offsets: 0, 26, 51, 77, 102, 128, 153, 179, 204, 230 (bits). Limb widths alternate 26 / 25 bits so 10 * 25.5 = 255 bits. Each limb fits in i64 comfortably (26 bits plus headroom). Multiplication of two limbs: 26 + 26 = 52 bits -- well within i64 range. Accumulating up to 10 partial products per output digit: ~56 bits peak -- still within i64. Why 10x25.5 and not 5x51: NishiLang has no u128 / 128-bit multiply. 5x51-bit limbs give 102-bit products that don't fit in i64. The 10x25.5 layout avoids this entirely; every intermediate fits in a plain i64. Constant-time discipline: X25519 MUST run in time independent of scalar/u bits (leaking would recover the private key). The Montgomery ladder + cswap achieves this naturally: same instruction sequence regardless of bit values; conditional swap via bitmask select rather than branch. No table lookups on secret bits. No divisions (used only in fe_invert, which runs over a fixed chain of squarings and multiplications regardless of input). Invariants (enforced, not hoped): XC1 Scalar clamping applied once at entry per RFC 7748 §5: scalar[0] &= 0xf8; scalar[31] &= 0x7f; scalar[31] |= 0x40. XC2 u-coordinate high bit cleared at entry (RFC 7748 §5).

dependencies 2 imports · 42 importers

nx_syscalls.nx nx_u256.nx nx_x25519.nx nx_doc_seal.nx nx_e2e.nx nx_ed25519_arith.nx nx_ed25519_arith_test.nx nx_ed25519_field.nx nx_ed25519_field_test.nx nx_ed25519_point.nx nx_ed25519_point_test.nx nx_ed25519_scalar_test.nx nx_ed25519_signature.nx

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

imports: nx_syscalls.nxnx_u256.nx

imported by: nx_doc_seal.nxnx_e2e.nxnx_ed25519_arith.nxnx_ed25519_arith_test.nxnx_ed25519_field.nxnx_ed25519_field_test.nxnx_ed25519_point.nxnx_ed25519_point_test.nxnx_ed25519_scalar_test.nxnx_ed25519_signature.nxnx_ed25519_signature_test.nxnx_edge_serve_static_test.nxnx_handshake_crypto_bench.nxnx_https_get_happy_test.nxnx_https_loopback_test.nxnx_tls13_client_session.nxnx_tls13_client_session_recv_sh.nxnx_tls13_full_tcp_test.nxnx_tls13_handshake.nxnx_tls13_handshake_io.nxnx_tls13_handshake_tcp_test.nxnx_tls13_handshake_test.nxnx_tls13_loopback_test.nxnx_tls13_server_full_handshake_test.nxnx_tls13_server_session.nxnx_tls13_server_session_app_data_test.nxnx_tls13_server_session_derive_hs_test.nxnx_tls13_server_session_derive_traffic_test.nxnx_tls13_server_session_emit_certificate_test.nxnx_tls13_server_session_emit_cv_test.nxnx_tls13_server_session_emit_ee_test.nxnx_tls13_server_session_emit_sf_test.nxnx_tls13_server_session_emit_sh_test.nxnx_tls13_server_session_recv_cf_test.nxnx_tls13_server_session_recv_ch_test.nxnx_tls13_server_session_test.nxnx_tor_ntor_gate.nxnx_x25519_ephemeral.nxnx_x25519_extvec_gate.nxnx_x25519_kat_gate.nxnx_x25519_test.nxnx_x25519mlkem768.nx

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

main sys_mmap x25519 nx_scratch_save nx_scratch_init sys_mmap ↻ nx_scratch nx_scratch_init ↻ nx_scratch_oom sys_write sys_exit sys_mmap ↻ fe_alloc nx_scratch ↻ fe_from_bytes fe_one fe_zero fe_zero ↻ fe_copy x25519_ladder_step fe_cswap nx_scratch_save ↻ fe_alloc ↻ fe_add fe_sq fe_mul fe_sub fe_mul ↻ fe_mul_a24 nx_scratch_save ↻ fe_alloc ↻ fe_mul ↻ nx_scratch_restore nx_scratch_restore ↻ fe_cswap ↻ fe_invert nx_scratch_save ↻ fe_alloc ↻ fe_sq ↻ fe_mul ↻

structs

none

consts

81const FE_MAGIC_121665: i64 = 121665
89const FE_LIMBS: i64 = 10

functions

91func fe_alloc() -> *i64
97func fe_copy(dst: *i64, src: *i64) -> i64
103func fe_zero(h: *i64) -> i64
109func fe_one(h: *i64) -> i64
121func fe_add(h: *i64, f: *i64, g: *i64) -> i64
127func fe_sub(h: *i64, f: *i64, g: *i64) -> i64
146func fe_mul(h: *i64, f: *i64, g: *i64) -> i64
229func fe_sq(h: *i64, f: *i64) -> i64
235func fe_mul_a24(h: *i64, f: *i64) -> i64
252func fe_cswap(f: *i64, g: *i64, swap: i64) -> i64
267func fe_cmov(dst: *i64, src: *i64, flag: i64) -> i64
called by 1: ge_p3_cmov
283func fe_invert(out: *i64, z: *i64) -> i64
326func fe_from_bytes(h: *i64, s: *u8) -> i64
345func fe_to_bytes(s: *u8, h_in: *i64) -> i64
418func x25519_ladder_step(x1: *i64,
472func x25519(scalar: *u8, u: *u8, out: *u8) -> i64
533func main() -> i64
calls 2: sys_mmapx25519