nx_decoy.nx source
↩ module page · 204 lines · 8425 B
1// nx_decoy.nx -- honeypot tripwires (aggressive-mimicry inverted).
2//
3// Biology: aggressive mimicry is when a PREDATOR mimics something
4// harmless to lure prey close (anglerfish lure resembling a worm,
5// photuris firefly mimicking female photinus flash patterns to eat
6// the responding males). Substrate INVERTS this: WE are not the
7// predator. WE are the prey. We plant fake-but-attractive artifacts
8// that lure THE PREDATOR (Intel ME / vendor scanner / state-actor
9// scraper). When the predator reads the lure, a tripwire fires.
10//
11// Per user 2026-05-19: "make sure that we have the system designed
12// with mimicry and obsfucation so these predatory programs get
13// nonsense or get scared off." The decoy IS the nonsense. Reading
14// it is fine -- but the read is observed, signed, and recorded as
15// confirmed-exfiltration into the forensic ledger.
16//
17// V1 decoy kinds (modeled on what surveillance scrapers target):
18// - FAKE_CREDENTIALS_FILE (.aws/credentials shape; tripwire keys)
19// - FAKE_SSH_PRIVATE_KEY (-----BEGIN OPENSSH PRIVATE KEY-----)
20// - FAKE_BROWSER_COOKIES (Chrome SQLite shape; tripwire UUIDs)
21// - FAKE_WALLET_FILE (Bitcoin wallet.dat shape; tripwire hashes)
22// - FAKE_KEYSTORE (Java keystore / PKCS12 shape)
23// - FAKE_SECRETS_BLOB (generic high-entropy looks-like-keys)
24// - FAKE_PASSWORD_MANAGER (KeePass kdbx shape)
25//
26// The decoy payload is STATISTICALLY plausible (high entropy, right
27// magic bytes, right size class) but FUNCTIONALLY useless. Any
28// "credential" extracted is a tripwire token. If that token ever
29// shows up downstream (auth attempt, dark-net listing, vendor
30// research paper), it's confirmed forgery from THIS host THIS
31// session.
32//
33// Composes:
34// nx_methyl -- decoys carry deliberately-invalid methyl marks
35// so leaked decoys are detectable as forgery
36// nx_aposematism -- decoys ALSO carry warning displays so vendor
37// ML might back off; if it doesn't, we get the
38// forensic tripwire instead -- either outcome
39// is a win
40// nx_xenocell -- a decoy read promotes the reading xenocell to
41// EXFILTRATING intrusion state
42// nx_pamp + nx_crispr -- recognize-then-remember decoy patterns so
43// our own decoys don't false-fire our scanners
44// nx_evict_journal -- tripwire fires logged as defensive wins
45//
46// V1 ships:
47// - decoy creation with kind + size + tripwire token
48// - access-observation hook (caller invokes when a read is detected)
49// - tripwire-fire detection (returns 1 if anyone read the decoy)
50//
51// Gap list (V1 honest perf verdict):
52// - decoy payload generation is caller's job (V2 substrate-managed
53// random fixtures sized appropriately per kind)
54// - no file-system / kernel binding (today nx_decoy is purely
55// in-memory; OS-binding is the integration layer's job)
56// - no peer-mesh tripwire-token registry (V2 federates so a token
57// read on one host can be flagged on every host)
58// - access-detection is caller-driven (V2 wires kernel watchers)
59//
60// genealogy_id: cardinal_2026-05-19_mimicry_obfuscation_directive +
61// cardinal_2026-05-17_cell_immune_judo +
62// biology_aggressive_mimicry_inverted
63// lineage_id: substrate_decoy_v1
64//
65// nx_safety_envelope:
66// intended_use: "Honeypot tripwires for confirmed-exfiltration
67// detection; DEFENSIVE ONLY -- never bait that
68// triggers offensive action"
69// sil_target: SIL3
70// evidence: [no_offensive_payload, tripwire_only,
71// captain_moroni_aligned, judo_of_information]
72// hazard_register: [bug-tape-decoy-leak-detected-elsewhere,
73// bug-tape-decoy-false-fires-on-own-scanner]
74// verdict: NOT_YET_EVALUATED
75
76import "nx_syscalls.nx"
77import "nx_tier.nx"
78
79// ===== Sealed enum: NxDecoyKind ==================================
80
81const NX_DK_FAKE_CREDENTIALS: nx_int = 0
82const NX_DK_FAKE_SSH_KEY: nx_int = 1
83const NX_DK_FAKE_BROWSER_COOKIES: nx_int = 2
84const NX_DK_FAKE_WALLET: nx_int = 3
85const NX_DK_FAKE_KEYSTORE: nx_int = 4
86const NX_DK_FAKE_SECRETS_BLOB: nx_int = 5
87const NX_DK_FAKE_PASSWORD_MGR: nx_int = 6
88const NX_DK_N_KINDS: nx_int = 7
89
90// ===== Sealed enum: NxDecoyVerdict ===============================
91
92const NX_DECOY_OK: nx_int = 0
93const NX_DECOY_ERR_BAD_KIND: nx_int = 1
94const NX_DECOY_TRIPWIRE_FIRED: nx_int = 2
95const NX_DECOY_ERR_BAD_TOKEN: nx_int = 3
96
97// ===== Struct: NxDecoy ===========================================
98//
99// One planted decoy. tripwire_token is the unique identifier embedded
100// in the payload that, if it shows up downstream, confirms this
101// specific decoy was read. payload_ptr + payload_len point to the
102// caller-allocated fixture bytes.
103//
104// read_count is incremented each time the substrate observes someone
105// reading the decoy; first_read_us / last_read_us bracket the access
106// window. xeno_id is the xenocell (if any) that did the reading --
107// caller supplies via nx_decoy_on_read.
108
109struct NxDecoy {
110 kind: nx_int,
111 tripwire_token: nx_size,
112 payload_ptr: *u8,
113 payload_len: nx_size,
114 read_count: nx_int,
115 first_read_us: nx_size,
116 last_read_us: nx_size,
117 reader_xeno_id: nx_int,
118}
119
120// ===== nx_decoy_kind_is_valid ====================================
121
122func nx_decoy_kind_is_valid(k: nx_int) -> nx_int {
123 if k < 0 { return 0 }
124 if k >= NX_DK_N_KINDS { return 0 }
125 return 1
126}
127
128// ===== nx_decoy_plant ============================================
129//
130// Plant a decoy of the given kind with caller-supplied payload bytes
131// and a unique tripwire token. Returns NULL on bad kind.
132
133func nx_decoy_plant(kind: nx_int,
134 tripwire_token: nx_size,
135 payload_ptr: *u8,
136 payload_len: nx_size) -> *NxDecoy {
137 if nx_decoy_kind_is_valid(kind) == 0 { return (0 as i64) as *NxDecoy }
138 if tripwire_token == 0 { return (0 as i64) as *NxDecoy }
139 let d: *NxDecoy = (sys_mmap(72)) as *NxDecoy
140 d.kind = kind
141 d.tripwire_token = tripwire_token
142 d.payload_ptr = payload_ptr
143 d.payload_len = payload_len
144 d.read_count = 0
145 d.first_read_us = 0
146 d.last_read_us = 0
147 d.reader_xeno_id = 0
148 return d
149}
150
151// ===== nx_decoy_on_read ==========================================
152//
153// Caller invokes this when access to the decoy is observed (e.g.,
154// kernel inotify fired on the decoy file, or in-memory access
155// watcher detected a read). reader_xeno_id is the suspect xenocell;
156// 0 if unknown. Returns NX_DECOY_TRIPWIRE_FIRED so the caller knows
157// to escalate (record signed observation in xenocell, log to evict
158// journal, propagate token to peer-mesh).
159
160func nx_decoy_on_read(d: *NxDecoy,
161 reader_xeno_id: nx_int,
162 now_us: nx_size) -> nx_int {
163 if d.read_count == 0 { d.first_read_us = now_us }
164 d.read_count = d.read_count + 1
165 d.last_read_us = now_us
166 if reader_xeno_id != 0 { d.reader_xeno_id = reader_xeno_id }
167 return NX_DECOY_TRIPWIRE_FIRED
168}
169
170// ===== nx_decoy_was_read =========================================
171
172func nx_decoy_was_read(d: *NxDecoy) -> nx_int {
173 if d.read_count > 0 { return 1 }
174 return 0
175}
176
177// ===== nx_decoy_token_matches ====================================
178//
179// Given a candidate token (e.g., received in an inbound auth attempt
180// or scraped from a paste-site by a peer), check whether it matches
181// this decoy's tripwire. Returns 1 on match. Used by downstream
182// integration layer to confirm "yes, this is the token we planted
183// in decoy id X on host Y at time T."
184
185func nx_decoy_token_matches(d: *NxDecoy, token: nx_size) -> nx_int {
186 if d.tripwire_token == 0 { return 0 }
187 if d.tripwire_token == token { return 1 }
188 return 0
189}
190
191// ===== nx_decoy_read_count =======================================
192
193func nx_decoy_read_count(d: *NxDecoy) -> nx_int {
194 return d.read_count
195}
196
197// ===== nx_decoy_reader =======================================
198//
199// Returns the xeno_id of the most recent reader, or 0 if no read
200// has been observed or reader_xeno_id was unknown when recorded.
201
202func nx_decoy_reader(d: *NxDecoy) -> nx_int {
203 return d.reader_xeno_id
204}