Skip to content

Commit ea434ec

Browse files
author
devsamikhan
committed
feat(core,security): implement AETHER v4.0 capability sandbox, gas metering, Secret redaction, taint scanner, ChaCha20-AEAD, PBKDF2, cycle GC, and .aec bytecode cache
1 parent c8c58ae commit ea434ec

10 files changed

Lines changed: 1450 additions & 2 deletions
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ==============================================================================
2+
# AETHER v4.0 — Core Engine, Performance & Security Hardening Showcase
3+
# Demonstrates:
4+
# 1. Capability-Based Security Sandbox (FS blocking, Fuel/Gas metering, Call Depth)
5+
# 2. First-Class Redacted Secrets (Secret(...) & constant-time comparison)
6+
# 3. Static Taint & Vulnerability Scanner (Security.scan)
7+
# 4. Modern AEAD Cryptography (ChaCha20-Poly1305 RFC 8439, PBKDF2-HMAC-SHA256)
8+
# 5. Cycle-Detecting GC Collector & Global String Symbol Interner
9+
# 6. Precompiled Binary Bytecode Cache (.aec) with SHA-256 Source Verification
10+
# ==============================================================================
11+
12+
println("================================================================")
13+
println(" AETHER v4.0 — Core Engine, Technology & Security Showcase")
14+
println("================================================================")
15+
16+
# 1. Capability-Based Security Sandbox & Gas/Fuel Metering
17+
let safe_calc = Security.sandbox("let a = 12 * 12; a + 6", {"fuel": 5000})
18+
let fs_blocked_msg = "allowed"
19+
try {
20+
Security.sandbox("File.read('Cargo.toml')", {"fuel": 5000})
21+
} catch as err {
22+
fs_blocked_msg = "Blocked (PermissionDeniedError)"
23+
}
24+
25+
let dos_stopped_msg = "ran forever"
26+
try {
27+
Security.sandbox("while true { }", {"fuel": 250})
28+
} catch as err {
29+
dos_stopped_msg = "Halted at 250 fuel ticks (ResourceExhaustedError)"
30+
}
31+
println(f"[1] Sandbox & Gas Metering: result={safe_calc} | FS={fs_blocked_msg} | DoS={dos_stopped_msg}")
32+
33+
# 2. First-Class Redacted Secret Type
34+
let gemini_key = Secret("AIzaSyAetherSecretKey998877")
35+
println(f"[2] Redacted Secret Print: gemini_key = {gemini_key} (exposed len = {len(Security.expose(gemini_key))})")
36+
37+
# 3. Static Taint & Vulnerability Scanner
38+
let untrusted_snippet = '
39+
let api_key = "hardcoded-secret-123"
40+
let req_user = input("user")
41+
Sql.execute("SELECT * FROM accounts WHERE user = " + req_user)
42+
'
43+
let scan_report = Security.scan(untrusted_snippet)
44+
println(f"[3] Static Security Audit: Found {len(scan_report)} vulnerabilities -> {scan_report[0]['category']}, {scan_report[1]['category']}")
45+
46+
# 4. Modern AEAD Cryptography (ChaCha20-Poly1305 + PBKDF2-HMAC-SHA256)
47+
let derived_key = Crypto.pbkdf2("MasterPassphrase!2026", "aether-salt-v4", 2000, 32)
48+
let nonce = Crypto.random_hex(12)
49+
let ciphertext = Crypto.encrypt_aead(derived_key, nonce, "Classified Aether v4 Payload", "aad:v4-header")
50+
let decrypted = Crypto.decrypt_aead(derived_key, nonce, ciphertext, "aad:v4-header")
51+
println(f"[4] ChaCha20-AEAD & PBKDF2: decrypted='{decrypted}' | key_prefix={derived_key[0:12]}...")
52+
53+
# 5. Cycle-Detecting Reference Collector & String Interner
54+
let graph_node = {"title": "CyclicRoot"}
55+
graph_node["loop_back"] = graph_node
56+
let cycles_freed = GC.collect_cycles(graph_node)
57+
let s_id1 = GC.intern("fast_property_lookup")
58+
let s_id2 = GC.intern("fast_property_lookup")
59+
println(f"[5] Cycle-Detecting GC & Interner: cycles_broken={cycles_freed} | symbol_match={s_id1 == s_id2} (total interned={GC.interned_count()})")
60+
61+
# 6. Binary Bytecode Cache (.aec) Serialization & Instant Execution
62+
let mod_code = "fn cube(x) { return x * x * x }\ncube(5) + 25"
63+
let aec_binary = Bytecode.compile_aec(mod_code)
64+
let aec_output = Bytecode.run_aec(aec_binary, mod_code)
65+
println(f"[6] Precompiled .aec Bytecode Cache: size={len(aec_binary)} bytes (B64) -> output={aec_output}")
66+
println("================================================================")

‎src/vm/bytecode_cache.rs‎

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// ==============================================================================
2+
// AETHER v4.0 — Binary Bytecode Serializer & Precompiled `.aec` Cache
3+
// Pure Rust Standard Library — Zero External Crates
4+
// ==============================================================================
5+
6+
use std::sync::Arc;
7+
use super::bytecode::Chunk;
8+
use super::crypto::sha256_bytes;
9+
use super::value::{CompiledFunction, Value};
10+
use crate::syntax::span::Span;
11+
12+
const AEC_MAGIC: &[u8; 5] = b"AETH\x04";
13+
14+
pub fn serialize_compiled_function(
15+
func: &CompiledFunction,
16+
source_code: &str,
17+
) -> Result<Vec<u8>, String> {
18+
let mut buf = Vec::with_capacity(512);
19+
buf.extend_from_slice(AEC_MAGIC);
20+
let src_hash = sha256_bytes(source_code.as_bytes());
21+
buf.extend_from_slice(&src_hash);
22+
write_function(&mut buf, func)?;
23+
Ok(buf)
24+
}
25+
26+
pub fn deserialize_compiled_function(
27+
bytes: &[u8],
28+
expected_source: Option<&str>,
29+
) -> Result<CompiledFunction, String> {
30+
if bytes.len() < 37 || &bytes[0..5] != AEC_MAGIC {
31+
return Err("Invalid or corrupted .aec bytecode header".to_string());
32+
}
33+
let stored_hash = &bytes[5..37];
34+
if let Some(src) = expected_source {
35+
let actual_hash = sha256_bytes(src.as_bytes());
36+
if stored_hash != actual_hash {
37+
return Err("Bytecode cache stale: source SHA-256 mismatch".to_string());
38+
}
39+
}
40+
let mut cursor = 37;
41+
read_function(bytes, &mut cursor)
42+
}
43+
44+
fn write_u32(buf: &mut Vec<u8>, v: u32) {
45+
buf.extend_from_slice(&v.to_le_bytes());
46+
}
47+
48+
fn read_u32(bytes: &[u8], cursor: &mut usize) -> Result<u32, String> {
49+
if *cursor + 4 > bytes.len() {
50+
return Err("Unexpected EOF reading u32 in .aec".to_string());
51+
}
52+
let v = u32::from_le_bytes([
53+
bytes[*cursor],
54+
bytes[*cursor + 1],
55+
bytes[*cursor + 2],
56+
bytes[*cursor + 3],
57+
]);
58+
*cursor += 4;
59+
Ok(v)
60+
}
61+
62+
fn write_string(buf: &mut Vec<u8>, s: &str) {
63+
let b = s.as_bytes();
64+
write_u32(buf, b.len() as u32);
65+
buf.extend_from_slice(b);
66+
}
67+
68+
fn read_string(bytes: &[u8], cursor: &mut usize) -> Result<String, String> {
69+
let len = read_u32(bytes, cursor)? as usize;
70+
if *cursor + len > bytes.len() {
71+
return Err("Unexpected EOF reading string in .aec".to_string());
72+
}
73+
let s = std::str::from_utf8(&bytes[*cursor..*cursor + len])
74+
.map_err(|_| "Invalid UTF-8 string in .aec".to_string())?
75+
.to_string();
76+
*cursor += len;
77+
Ok(s)
78+
}
79+
80+
fn write_function(buf: &mut Vec<u8>, func: &CompiledFunction) -> Result<(), String> {
81+
write_string(buf, &func.name);
82+
write_u32(buf, func.arity as u32);
83+
write_u32(buf, func.max_arity as u32);
84+
write_u32(buf, func.param_names.len() as u32);
85+
for p in &func.param_names {
86+
write_string(buf, p);
87+
}
88+
buf.push(u8::from(func.has_varargs));
89+
if let Some(ref vp) = func.varargs_param {
90+
buf.push(1);
91+
write_string(buf, vp);
92+
} else {
93+
buf.push(0);
94+
}
95+
buf.push(u8::from(func.has_kwargs));
96+
if let Some(ref kp) = func.kwargs_param {
97+
buf.push(1);
98+
write_string(buf, kp);
99+
} else {
100+
buf.push(0);
101+
}
102+
write_u32(buf, func.upvalue_count as u32);
103+
104+
// Chunk code
105+
write_u32(buf, func.chunk.code.len() as u32);
106+
buf.extend_from_slice(&func.chunk.code);
107+
108+
// Chunk constants
109+
write_u32(buf, func.chunk.constants.len() as u32);
110+
for c in &func.chunk.constants {
111+
write_constant(buf, c)?;
112+
}
113+
114+
Ok(())
115+
}
116+
117+
fn read_function(bytes: &[u8], cursor: &mut usize) -> Result<CompiledFunction, String> {
118+
let name = read_string(bytes, cursor)?;
119+
let arity = read_u32(bytes, cursor)? as usize;
120+
let max_arity = read_u32(bytes, cursor)? as usize;
121+
let param_count = read_u32(bytes, cursor)? as usize;
122+
let mut param_names = Vec::with_capacity(param_count);
123+
for _ in 0..param_count {
124+
param_names.push(read_string(bytes, cursor)?);
125+
}
126+
if *cursor >= bytes.len() {
127+
return Err("Unexpected EOF in function flags".to_string());
128+
}
129+
let has_varargs = bytes[*cursor] != 0;
130+
*cursor += 1;
131+
let has_vp = bytes[*cursor] != 0;
132+
*cursor += 1;
133+
let varargs_param = if has_vp {
134+
Some(read_string(bytes, cursor)?)
135+
} else {
136+
None
137+
};
138+
139+
let has_kwargs = bytes[*cursor] != 0;
140+
*cursor += 1;
141+
let has_kp = bytes[*cursor] != 0;
142+
*cursor += 1;
143+
let kwargs_param = if has_kp {
144+
Some(read_string(bytes, cursor)?)
145+
} else {
146+
None
147+
};
148+
149+
let upvalue_count = read_u32(bytes, cursor)? as usize;
150+
let code_len = read_u32(bytes, cursor)? as usize;
151+
if *cursor + code_len > bytes.len() {
152+
return Err("Unexpected EOF reading chunk code".to_string());
153+
}
154+
let code = bytes[*cursor..*cursor + code_len].to_vec();
155+
*cursor += code_len;
156+
157+
let const_count = read_u32(bytes, cursor)? as usize;
158+
let mut constants = Vec::with_capacity(const_count);
159+
for _ in 0..const_count {
160+
constants.push(read_constant(bytes, cursor)?);
161+
}
162+
163+
let spans = vec![Span::default(); code.len()];
164+
Ok(CompiledFunction {
165+
name,
166+
arity,
167+
max_arity,
168+
param_names,
169+
has_varargs,
170+
varargs_param,
171+
has_kwargs,
172+
kwargs_param,
173+
upvalue_count,
174+
chunk: Chunk {
175+
code,
176+
constants,
177+
spans,
178+
},
179+
})
180+
}
181+
182+
fn write_constant(buf: &mut Vec<u8>, val: &Value) -> Result<(), String> {
183+
match val {
184+
Value::Nil => buf.push(0),
185+
Value::Bool(b) => {
186+
buf.push(1);
187+
buf.push(u8::from(*b));
188+
}
189+
Value::Int(i) => {
190+
buf.push(2);
191+
buf.extend_from_slice(&i.to_le_bytes());
192+
}
193+
Value::Float(f) => {
194+
buf.push(3);
195+
buf.extend_from_slice(&f.to_le_bytes());
196+
}
197+
Value::String(s) => {
198+
buf.push(4);
199+
write_string(buf, s);
200+
}
201+
Value::DefaultSentinel => buf.push(5),
202+
Value::Function(f) => {
203+
buf.push(6);
204+
write_function(buf, f)?;
205+
}
206+
other => {
207+
return Err(format!(
208+
"Cannot serialize non-literal constant of type '{}' in .aec",
209+
other.type_name()
210+
))
211+
}
212+
}
213+
Ok(())
214+
}
215+
216+
fn read_constant(bytes: &[u8], cursor: &mut usize) -> Result<Value, String> {
217+
if *cursor >= bytes.len() {
218+
return Err("Unexpected EOF reading constant tag".to_string());
219+
}
220+
let tag = bytes[*cursor];
221+
*cursor += 1;
222+
match tag {
223+
0 => Ok(Value::Nil),
224+
1 => {
225+
let b = bytes[*cursor] != 0;
226+
*cursor += 1;
227+
Ok(Value::Bool(b))
228+
}
229+
2 => {
230+
let mut arr = [0u8; 8];
231+
arr.copy_from_slice(&bytes[*cursor..*cursor + 8]);
232+
*cursor += 8;
233+
Ok(Value::Int(i64::from_le_bytes(arr)))
234+
}
235+
3 => {
236+
let mut arr = [0u8; 8];
237+
arr.copy_from_slice(&bytes[*cursor..*cursor + 8]);
238+
*cursor += 8;
239+
Ok(Value::Float(f64::from_le_bytes(arr)))
240+
}
241+
4 => Ok(Value::string(read_string(bytes, cursor)?)),
242+
5 => Ok(Value::DefaultSentinel),
243+
6 => Ok(Value::Function(Arc::new(read_function(bytes, cursor)?))),
244+
other => Err(format!("Unknown constant tag {} in .aec", other)),
245+
}
246+
}

0 commit comments

Comments
 (0)