code wiki / _hdl_build / nx_social_auth_recover.nx

nx_social_auth_recover.nx source

↩ module page · 45 lines · 2854 B

1// nx_social_auth_recover.nx -- the WIRING that makes elderly social recovery REAL: it connects the Shamir 2// family-quorum primitive (nx_social_recovery) to actual account recovery (nx_modern_auth_recover), via the 3// BIP39 codec. The recovery secret IS the entropy behind the user's issued mnemonic, so: 4// ENROLL: decode the issued mnemonic -> its 256-bit entropy -> Shamir-split across N trusted contacts (K 5// threshold). The USER HOLDS NOTHING; the family holds shares. 6// RECOVER: K contacts reconstruct the entropy -> re-encode the mnemonic -> nx_modern_auth_recover (sets a 7// new passphrase, rotates the mnemonic). K-1 reconstruct GARBAGE -> a wrong mnemonic -> refused. 8// After a recovery the mnemonic rotates, so the caller MUST re-split the new mnemonic (nx_sar_enroll_split) 9// for the next cycle. No seed phrase is ever handed to the user; the family quorum is the backup. 10// Composes nx_social_recovery + nx_bip39 + nx_modern_auth_flow. license_tier: ORIGINAL 11import "nx_social_recovery.nx" 12import "hub/nx_bip39.nx" 13import "hub/nx_modern_auth_flow.nx" 14import "nx_syscalls.nx" 15 16const NX_SAR_OK: i64 = 0 17const NX_SAR_BAD_MNEMONIC: i64 = 1 // the issued mnemonic didn't decode to 256-bit entropy 18const NX_SAR_RECOVER_FAILED: i64 = 2 // the reconstructed entropy didn't recover the account (e.g. < K shares) 19 20// ENROLL: split the entropy behind `mn` across n contacts, threshold k. shares_out = n rows x SR_CHUNKS i64. 21func nx_sar_enroll_split(mn: *u8, mn_n: i64, n: i64, k: i64, shares_out: *i64) -> i64 { 22 let ent: *u8 = sys_mmap(64) 23 let ebox: *i64 = sys_mmap(8) as *i64 24 ebox[0] = 0 25 if nx_bip39_decode(mn, mn_n, ent, 64, ebox) != NX_B39_OK { return 0 - NX_SAR_BAD_MNEMONIC } 26 if ebox[0] != SR_KEY_BYTES { return 0 - NX_SAR_BAD_MNEMONIC } 27 if nx_sr_split(ent, n, k, shares_out) != 0 { return 0 - NX_SAR_BAD_MNEMONIC } 28 return NX_SAR_OK 29} 30 31// RECOVER: k contacts (xs[], shares_in = k rows x SR_CHUNKS) reconstruct the entropy -> mnemonic -> 32// nx_modern_auth_recover(set new_pw, rotate). new_mn_out gets the NEW rotated mnemonic (RE-SPLIT it next). 33func nx_sar_recover(ctx: *NxAuthContext, handle: *u8, handle_n: i64, 34 k: i64, xs: *i64, shares_in: *i64, 35 new_pw: *u8, new_pw_n: i64, 36 new_mn_out: *u8, new_mn_cap: i64, new_mn_n_out: *i64) -> i64 { 37 let ent: *u8 = sys_mmap(64) 38 nx_sr_reconstruct(k, xs, shares_in, ent) 39 let mn: *u8 = sys_mmap(512) 40 let mnbox: *i64 = sys_mmap(8) as *i64 41 mnbox[0] = 0 42 if nx_bip39_encode(ent, SR_KEY_BYTES, mn, 512, mnbox) != NX_B39_OK { return 0 - NX_SAR_RECOVER_FAILED } 43 if nx_modern_auth_recover(ctx, handle, handle_n, mn, mnbox[0], new_pw, new_pw_n, new_mn_out, new_mn_cap, new_mn_n_out) != NX_MAUTH_OK { return 0 - NX_SAR_RECOVER_FAILED } 44 return NX_SAR_OK 45}