code wiki / (root) / nx_connect_e2e_proof.nx

nx_connect_e2e_proof.nx source

↩ module page · 79 lines · 2972 B

1// nx_connect_e2e_proof.nx -- LIVE-LOOP witness for the full-E2E CONNECT proof: computes the EXACT bytes 2// the browser client produces (the wasm mcw_* API is a thin wrapper over these same native mc_* functions, 3// and the wasm is separately proven bit-exact vs RFC 8439 in nx_media_crypt_wasm_gate). Used to drive the 4// two-user proof over the PUBLIC edge: seal as Alice -> POST -> fetch as Bob -> open -> plaintext must 5// round-trip. license_tier: ORIGINAL 6// nx_connect_e2e_proof seal <keyhex64> <seq> <plaintext> -> ciphertext hex on stdout 7// nx_connect_e2e_proof open <keyhex64> <seq> <cthex> -> plaintext on stdout 8import "nx_syscalls.nx" 9import "nx_media_crypt.nx" 10 11const EP_MAX: i64 = 4096 12 13func ep_w(s: *u8, n: i64) -> i64 { sys_write(1, s, n); return 0 } 14func ep_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 15func ep_seq(a: *u8, b: *u8) -> i64 { 16 var i: i64=0 17 while a[i]!=(0 as u8) { if a[i]!=b[i] { return 0 } i=i+1 } 18 if b[i]!=(0 as u8) { return 0 } 19 return 1 20} 21func ep_atoi(s: *u8) -> i64 { 22 var v: i64=0 23 var i: i64=0 24 while s[i]!=(0 as u8) { 25 let c: i64 = s[i] as i64 26 if c>=48 { if c<=57 { v=v*10+(c-48) } } 27 i=i+1 28 } 29 return v 30} 31 32func main(argc: i64, argv: *i64) -> i64 { 33 if argc < 5 { sys_write(2, "usage: nx_connect_e2e_proof seal|open <keyhex64> <seq> <text|cthex>\n" as *u8, 68); return 2 } 34 let mode: *u8 = argv[1] as *u8 35 let keyhex: *u8 = argv[2] as *u8 36 let seqs: *u8 = argv[3] as *u8 37 let data: *u8 = argv[4] as *u8 38 if ep_slen(keyhex)!=64 { sys_write(2, "key must be 64 hex chars\n" as *u8, 25); return 2 } 39 let key: *u8 = sys_mmap(32) 40 mc_key(keyhex, 64, key) 41 let nonce: *u8 = sys_mmap(12) 42 mc_nonce("connect1" as *u8, ep_atoi(seqs), nonce) 43 let buf: *u8 = sys_mmap(EP_MAX) 44 let scratch: *u8 = sys_mmap(EP_MAX) 45 if ep_seq(mode, "seal" as *u8)==1 { 46 let n: i64 = ep_slen(data) 47 var i: i64=0 48 while i<n { buf[i]=data[i]; i=i+1 } 49 mc_xform(key, nonce, 0, buf, n, scratch) 50 let hexout: *u8 = sys_mmap(EP_MAX*2) 51 i=0 52 while i<n { 53 let b: i64 = buf[i] as i64 54 var hi: i64 = (b>>4)&0xf 55 var lo: i64 = b&0xf 56 if hi<10 { hexout[i*2]=(48+hi) as u8 } else { hexout[i*2]=(87+hi) as u8 } 57 if lo<10 { hexout[i*2+1]=(48+lo) as u8 } else { hexout[i*2+1]=(87+lo) as u8 } 58 i=i+1 59 } 60 ep_w(hexout, n*2) 61 ep_w("\n" as *u8, 1) 62 return 0 63 } 64 if ep_seq(mode, "open" as *u8)==1 { 65 let hn: i64 = ep_slen(data) 66 let n: i64 = hn/2 67 var i: i64=0 68 while i<n { 69 buf[i]=((mc_hexval(data[i*2] as i64)<<4)|mc_hexval(data[i*2+1] as i64)) as u8 70 i=i+1 71 } 72 mc_xform(key, nonce, 0, buf, n, scratch) 73 ep_w(buf, n) 74 ep_w("\n" as *u8, 1) 75 return 0 76 } 77 sys_write(2, "unknown mode\n" as *u8, 13) 78 return 2 79}