code wiki / _hdl_build / nx_social_auth_recover_gate.nx

nx_social_auth_recover_gate.nx source

↩ module page · 94 lines · 4906 B

1// nx_social_auth_recover_gate.nx -- REFEREE for the elderly social-recovery-to-account wiring: a family 2// quorum RESETS the account, the user holds no seed phrase, and less-than-quorum cannot. End-to-end through 3// the REAL Modern Auth: arm a realm -> register (issues a mnemonic) -> enroll-split its entropy across 3 4// contacts (K=2) -> exercise recovery: 5// T1 single contact (K-1) -> recovery REFUSED (garbage entropy -> wrong mnemonic -> mismatch) 6// T2 two contacts (quorum) -> account RECOVERED (new passphrase set, mnemonic rotated) 7// T3 login with the family-set passphrase -> OK 8// T4 login with the OLD passphrase -> dead (rotated) 9// GREEN iff T1..T4. Sovereign: nx_social_auth_recover (+ nx_social_recovery + nx_bip39 + nx_modern_auth_flow). 10// license_tier: ORIGINAL 11import "nx_social_auth_recover.nx" 12import "hub/nx_modern_auth_flow.nx" 13import "nx_syscalls.nx" 14 15func g_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 16func g_row(name: *u8, ok: i64) -> i64 { 17 if ok == 1 { g_w(" PASS " as *u8) } 18 if ok != 1 { g_w(" FAIL " as *u8) } 19 g_w(name); g_w("\n" as *u8) 20 return ok 21} 22func g_trunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x180); if fd >= 0 { sys_close(fd) } return 0 } 23 24func main() -> i64 { 25 g_w("social-auth-recover gate: family quorum RESETS the account; user holds NO seed phrase\n" as *u8) 26 let store_path: *u8 = "/tmp/nx_sar_store.log" as *u8 27 let keys_path: *u8 = "/tmp/nx_sar_keys.log" as *u8 28 g_trunc(store_path) 29 g_trunc(keys_path) 30 31 let oprf_seed: *u8 = sys_mmap(32) 32 let akp: *u8 = sys_mmap(32) 33 let akb: *u8 = sys_mmap(33) 34 let edp: *u8 = sys_mmap(32) 35 let edb: *u8 = sys_mmap(32) 36 if nx_uas_server_keys_load_or_init(keys_path, oprf_seed, akp, akb, edp, edb) != NX_UAS_OK { g_w("KEYS FAIL\n" as *u8); sys_exit(1) } 37 let realm: *u8 = "nishi_elder_acct" as *u8 38 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext 39 if nx_auth_context_init(ctx, realm, 16, realm, 16, store_path as i64, oprf_seed, edp, edb, 900, 8192, 1, 1, 5, 1) != NX_MAUTH_OK { g_w("CTX FAIL\n" as *u8); sys_exit(1) } 40 41 let handle: *u8 = "elder" as *u8 42 let pw0: *u8 = "correct horse battery staple" as *u8 43 let mn0: *u8 = sys_mmap(512) 44 let mn0_box: *i64 = sys_mmap(8) as *i64 45 mn0_box[0] = 0 46 if nx_modern_auth_register(ctx, handle, 5, pw0, 28, mn0, 512, mn0_box) != NX_MAUTH_OK { g_w("REGISTER FAIL\n" as *u8); sys_exit(1) } 47 48 // ENROLL: split the mnemonic's entropy across 3 contacts, K=2 (the user keeps nothing) 49 let shares: *i64 = sys_mmap(3 * SR_CHUNKS * 8) as *i64 50 if nx_sar_enroll_split(mn0, mn0_box[0], 3, 2, shares) != NX_SAR_OK { g_w("ENROLL-SPLIT FAIL\n" as *u8); sys_exit(1) } 51 52 let new_mn: *u8 = sys_mmap(512) 53 let new_mn_box: *i64 = sys_mmap(8) as *i64 54 var pass: i64 = 0 55 56 // ---- T1: single contact (K-1) -> REFUSED ---- 57 let xs1: *i64 = sys_mmap(8) as *i64 58 xs1[0] = 1 59 let sin1: *i64 = sys_mmap(SR_CHUNKS * 8) as *i64 60 var c1: i64 = 0 61 while c1 < SR_CHUNKS { sin1[c1] = shares[c1]; c1 = c1 + 1 } 62 var t1: i64 = 0 63 if nx_sar_recover(ctx, handle, 5, 1, xs1, sin1, "hacker wont get in" as *u8, 18, new_mn, 512, new_mn_box) == (0 - NX_SAR_RECOVER_FAILED) { t1 = 1 } 64 pass = pass + g_row("T1 single contact (K-1) -> recovery REFUSED\x00" as *u8, t1) 65 66 // ---- T2: two contacts (quorum) -> RECOVERED ---- 67 let xs2: *i64 = sys_mmap(16) as *i64 68 xs2[0] = 1 69 xs2[1] = 2 70 let sin2: *i64 = sys_mmap(2 * SR_CHUNKS * 8) as *i64 71 var c2: i64 = 0 72 while c2 < SR_CHUNKS { sin2[c2] = shares[c2]; sin2[SR_CHUNKS + c2] = shares[SR_CHUNKS + c2]; c2 = c2 + 1 } 73 let new_pw: *u8 = "family recovered me 2026" as *u8 74 var t2: i64 = 0 75 if nx_sar_recover(ctx, handle, 5, 2, xs2, sin2, new_pw, 24, new_mn, 512, new_mn_box) == NX_SAR_OK { t2 = 1 } 76 pass = pass + g_row("T2 two contacts (quorum) -> account RECOVERED\x00" as *u8, t2) 77 78 // ---- T3: login with the family-set passphrase -> OK ---- 79 let tok: *u8 = sys_mmap(NX_MAUTH_SESSION_TOKEN_BYTES) 80 let tok_n: *i64 = sys_mmap(8) as *i64 81 var t3: i64 = 0 82 if nx_modern_auth_login(ctx, handle, 5, new_pw, 24, tok, NX_MAUTH_SESSION_TOKEN_BYTES, tok_n) == NX_MAUTH_OK { t3 = 1 } 83 pass = pass + g_row("T3 login with the family-set passphrase -> OK\x00" as *u8, t3) 84 85 // ---- T4: old passphrase dead (rotated) ---- 86 var t4: i64 = 0 87 if nx_modern_auth_login(ctx, handle, 5, pw0, 28, tok, NX_MAUTH_SESSION_TOKEN_BYTES, tok_n) == (0 - NX_MAUTH_WRONG_PASSPHRASE) { t4 = 1 } 88 pass = pass + g_row("T4 old passphrase -> dead (rotated)\x00" as *u8, t4) 89 90 if pass == 4 { g_w("SOCIAL-AUTH-RECOVER GATE GREEN 4/4 (family quorum resets the account; K-1 cannot; no seed phrase held)\n" as *u8); sys_exit(0) } 91 g_w("SOCIAL-AUTH-RECOVER GATE RED\n" as *u8) 92 sys_exit(1) 93 return 1 94}