code wiki / _hdl_build / nx_social_recovery_gate.nx

nx_social_recovery_gate.nx source

↩ module page · 82 lines · 3571 B

1// nx_social_recovery_gate.nx -- REFEREE for elderly-friendly social recovery (N=3 contacts, K=2 quorum over a 2// 256-bit secret). Security code MUST prove the quorum holds AND that less-than-quorum learns nothing. 3// T1 contacts {1,2} reconstruct == secret T4 a single share (K-1) != secret (no quorum -> nothing) 4// T2 contacts {1,3} reconstruct == secret T5 a tampered share != secret (one bad share = garbage) 5// T3 contacts {2,3} reconstruct == secret 6// GREEN iff T1..T5. Sovereign: nx_social_recovery + nx_vault_shamir + nx_csprng + nx_syscalls. license_tier: ORIGINAL 7import "nx_social_recovery.nx" 8import "nx_syscalls.nx" 9 10func 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 } 11func g_row(name: *u8, ok: i64) -> i64 { 12 if ok == 1 { g_w(" PASS " as *u8) } 13 if ok != 1 { g_w(" FAIL " as *u8) } 14 g_w(name) 15 g_w("\n" as *u8) 16 return ok 17} 18func g_eq32(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while i < SR_KEY_BYTES { if (a[i] as i64) != (b[i] as i64) { return 0 } i = i + 1 } return 1 } 19 20// load contacts a,b (0-based) into xs/shares_in for a k=2 reconstruct. 21func g_pick2(shares: *i64, a: i64, b: i64, xs: *i64, sin: *i64) -> i64 { 22 xs[0] = a + 1 23 xs[1] = b + 1 24 var c: i64 = 0 25 while c < SR_CHUNKS { 26 sin[0 * SR_CHUNKS + c] = shares[a * SR_CHUNKS + c] 27 sin[1 * SR_CHUNKS + c] = shares[b * SR_CHUNKS + c] 28 c = c + 1 29 } 30 return 0 31} 32 33func main() -> i64 { 34 g_w("social-recovery gate: N=3 trusted contacts, K=2 quorum over a 256-bit secret\n" as *u8) 35 let secret: *u8 = sys_mmap(SR_KEY_BYTES) 36 var i: i64 = 0 37 while i < SR_KEY_BYTES { secret[i] = ((i * 7 + 3) & 0xff) as u8; i = i + 1 } 38 39 let shares: *i64 = sys_mmap(3 * SR_CHUNKS * 8) as *i64 40 if nx_sr_split(secret, 3, 2, shares) != 0 { g_w("SPLIT FAIL\n" as *u8); sys_exit(1) } 41 42 let xs: *i64 = sys_mmap(2 * 8) as *i64 43 let sin: *i64 = sys_mmap(2 * SR_CHUNKS * 8) as *i64 44 let rec: *u8 = sys_mmap(SR_KEY_BYTES) 45 var pass: i64 = 0 46 47 g_pick2(shares, 0, 1, xs, sin) 48 nx_sr_reconstruct(2, xs, sin, rec) 49 pass = pass + g_row("T1 contacts {1,2} -> reconstruct == secret\x00" as *u8, g_eq32(rec, secret)) 50 51 g_pick2(shares, 0, 2, xs, sin) 52 nx_sr_reconstruct(2, xs, sin, rec) 53 pass = pass + g_row("T2 contacts {1,3} -> reconstruct == secret\x00" as *u8, g_eq32(rec, secret)) 54 55 g_pick2(shares, 1, 2, xs, sin) 56 nx_sr_reconstruct(2, xs, sin, rec) 57 pass = pass + g_row("T3 contacts {2,3} -> reconstruct == secret\x00" as *u8, g_eq32(rec, secret)) 58 59 // ---- T4: a single share (K-1) reveals NOTHING -> != secret ---- 60 let xs1: *i64 = sys_mmap(8) as *i64 61 xs1[0] = 1 62 let sin1: *i64 = sys_mmap(SR_CHUNKS * 8) as *i64 63 var c4: i64 = 0 64 while c4 < SR_CHUNKS { sin1[c4] = shares[0 * SR_CHUNKS + c4]; c4 = c4 + 1 } 65 nx_sr_reconstruct(1, xs1, sin1, rec) 66 var t4: i64 = 0 67 if g_eq32(rec, secret) == 0 { t4 = 1 } 68 pass = pass + g_row("T4 single share (K-1) -> NOT the secret\x00" as *u8, t4) 69 70 // ---- T5: a tampered share -> garbage != secret ---- 71 g_pick2(shares, 0, 1, xs, sin) 72 sin[0] = sin[0] ^ 1 73 nx_sr_reconstruct(2, xs, sin, rec) 74 var t5: i64 = 0 75 if g_eq32(rec, secret) == 0 { t5 = 1 } 76 pass = pass + g_row("T5 tampered share -> garbage, NOT the secret\x00" as *u8, t5) 77 78 if pass == 5 { g_w("SOCIAL-RECOVERY GATE GREEN 5/5 (quorum rebuilds exactly; less-than-quorum learns nothing)\n" as *u8); sys_exit(0) } 79 g_w("SOCIAL-RECOVERY GATE RED\n" as *u8) 80 sys_exit(1) 81 return 1 82}