Skip to content

Commit 815e21b

Browse files
SSD DDDSSD DDD
authored andcommitted
feat(specs): import 67 .t27 protocol-stack specs from local wave work
These specs were ported from the Rust codebase to .t27 during Wave 2-9 (Wave 2: ETX/HELLO/Transport; Wave 3: packet-queue/exp-backoff/frame-buffer; Wave 4: link-statistics; Wave 5: advanced utilities; Wave 6: system integration; Wave 7: hardware deployment; Wave 8: security/monitoring; Wave 9: network intelligence) in the local clone, but never merged to origin. They are the raw material for T27-first flips beyond wire.t27. Verified: hello.t27 and etx.t27 both produce CLEAN gen-rust output (0 'return ()', 0 'unsupported') with the current t27c (post-ExprCast fix t27@3c912d9). t27#1258 (dynamic array/RAM for gen-verilog FPGA datapaths) is NOT a blocker for these protocol specs — they use no arrays. Key protocol-stack specs now on origin: hello.t27 (discovery/HELLO framing) etx.t27 (routing ETX metric) mesh_routing.t27 (routing logic) mesh_protocol_stack.t27 (stack) key_management.t27 (crypto key lifecycle) adaptive_retry.t27 (retry logic) crc16.t27 (CRC utility) byte_utils.t27 (byte helpers) link_quality_monitor.t27, link_statistics.t27 + 57 more (utilities, monitoring, optimization, validation) Total: 68 .t27 files (67 new + wire.t27 already on origin).
1 parent 73e5d18 commit 815e21b

67 files changed

Lines changed: 18145 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

specs/access_control.t27

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
// Access Control - node authentication and authorization
2+
// Simplified RBAC for mesh network security
3+
4+
module AccessControl {
5+
use base::types;
6+
7+
const MAX_NODES: u32 = 8;
8+
const ROLE_NONE: u32 = 0;
9+
const ROLE_GUEST: u32 = 1;
10+
const ROLE_USER: u32 = 2;
11+
const ROLE_ADMIN: u32 = 3;
12+
const PERMIT: u32 = 1;
13+
const DENY: u32 = 0;
14+
15+
// Node credentials [node_id][role][auth_token][authorized]
16+
fn create_node_creds(node_id: u32, role: u32, auth_token: u32, authorized: u32) -> u32 {
17+
return (((node_id & 0xFF) << 24) |
18+
((role & 0x3) << 22) |
19+
((auth_token & 0x3FF) << 12) |
20+
((authorized & 0x1) << 11));
21+
}
22+
23+
fn get_node_id(creds: u32) -> u32 {
24+
return ((creds >> 24) & 0xFF);
25+
}
26+
27+
fn get_role(creds: u32) -> u32 {
28+
return ((creds >> 22) & 0x3);
29+
}
30+
31+
fn get_auth_token(creds: u32) -> u32 {
32+
return ((creds >> 12) & 0x3FF);
33+
}
34+
35+
fn is_authorized(creds: u32) -> u32 {
36+
return ((creds >> 11) & 0x1);
37+
}
38+
39+
// Access policy [resource][min_role][guest][user][admin]
40+
fn create_policy(resource: u32, min_role: u32, guest_perm: u32, user_perm: u32, admin_perm: u32) -> u32 {
41+
return (((resource & 0xF) << 28) |
42+
((min_role & 0x3) << 26) |
43+
((guest_perm & 0x1) << 25) |
44+
((user_perm & 0x1) << 24) |
45+
((admin_perm & 0x1) << 23));
46+
}
47+
48+
fn get_resource(policy: u32) -> u32 {
49+
return ((policy >> 28) & 0xF);
50+
}
51+
52+
fn get_min_role(policy: u32) -> u32 {
53+
return ((policy >> 26) & 0x3);
54+
}
55+
56+
fn get_guest_perm(policy: u32) -> u32 {
57+
return ((policy >> 25) & 0x1);
58+
}
59+
60+
fn get_user_perm(policy: u32) -> u32 {
61+
return ((policy >> 24) & 0x1);
62+
}
63+
64+
fn get_admin_perm(policy: u32) -> u32 {
65+
return ((policy >> 23) & 0x1);
66+
}
67+
68+
// Check if role meets minimum requirement
69+
fn role_meets_minimum(role: u32, min_role: u32) -> bool {
70+
return (role >= min_role);
71+
}
72+
73+
// Check access permission
74+
fn check_access(policy: u32, role: u32) -> u32 {
75+
let min_role = get_min_role(policy);
76+
77+
if (!role_meets_minimum(role, min_role)) {
78+
return DENY; // Role too low
79+
}
80+
81+
if (role == ROLE_GUEST) {
82+
return get_guest_perm(policy);
83+
} else if (role == ROLE_USER) {
84+
return get_user_perm(policy);
85+
} else if (role == ROLE_ADMIN) {
86+
return get_admin_perm(policy);
87+
}
88+
89+
return DENY; // Invalid role
90+
}
91+
92+
// Verify node credentials
93+
fn verify_creds(creds: u32, provided_token: u32) -> bool {
94+
if (is_authorized(creds) == 0) {
95+
return false; // Node not authorized
96+
}
97+
98+
return (get_auth_token(creds) == provided_token);
99+
}
100+
101+
// Authorize node
102+
fn authorize_node(creds: u32) -> u32 {
103+
let node_id = get_node_id(creds);
104+
let role = get_role(creds);
105+
let token = get_auth_token(creds);
106+
return create_node_creds(node_id, role, token, PERMIT);
107+
}
108+
109+
// Revoke node authorization
110+
fn revoke_node(creds: u32) -> u32 {
111+
let node_id = get_node_id(creds);
112+
let role = get_role(creds);
113+
let token = get_auth_token(creds);
114+
return create_node_creds(node_id, role, token, DENY);
115+
}
116+
117+
// Change node role
118+
fn change_role(creds: u32, new_role: u32) -> u32 {
119+
let node_id = get_node_id(creds);
120+
let token = get_auth_token(creds);
121+
let auth = is_authorized(creds);
122+
return create_node_creds(node_id, new_role, token, auth);
123+
}
124+
125+
// Check resource access for node
126+
fn check_resource_access(creds: u32, policy: u32, provided_token: u32) -> u32 {
127+
if (!verify_creds(creds, provided_token)) {
128+
return DENY; // Invalid credentials
129+
}
130+
131+
let role = get_role(creds);
132+
return check_access(policy, role);
133+
}
134+
135+
// ---- Tests ----
136+
137+
test create_node_creds_basic {
138+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
139+
assert(get_node_id(creds) == 5, "node id");
140+
assert(get_role(creds) == ROLE_USER, "user role");
141+
assert(get_auth_token(creds) == 0x123, "auth token");
142+
assert(is_authorized(creds) == 1, "authorized");
143+
}
144+
145+
test create_policy_basic {
146+
policy = create_policy(1, ROLE_USER, 0, 1, 1);
147+
assert(get_resource(policy) == 1, "resource");
148+
assert(get_min_role(policy) == ROLE_USER, "min role");
149+
assert(get_guest_perm(policy) == 0, "guest denied");
150+
assert(get_user_perm(policy) == 1, "user permitted");
151+
}
152+
153+
test role_meets_minimum_true {
154+
assert(role_meets_minimum(ROLE_USER, ROLE_GUEST) == true, "user >= guest");
155+
assert(role_meets_minimum(ROLE_ADMIN, ROLE_USER) == true, "admin >= user");
156+
}
157+
158+
test role_meets_minimum_false {
159+
assert(role_meets_minimum(ROLE_GUEST, ROLE_USER) == false, "guest < user");
160+
assert(role_meets_minimum(ROLE_USER, ROLE_ADMIN) == false, "user < admin");
161+
}
162+
163+
test check_access_admin {
164+
policy = create_policy(1, ROLE_GUEST, 0, 0, 1);
165+
assert(check_access(policy, ROLE_ADMIN) == 1, "admin permitted");
166+
}
167+
168+
test check_access_user {
169+
policy = create_policy(1, ROLE_USER, 0, 1, 1);
170+
assert(check_access(policy, ROLE_USER) == 1, "user permitted");
171+
}
172+
173+
test check_access_guest_denied {
174+
policy = create_policy(1, ROLE_USER, 0, 1, 1);
175+
assert(check_access(policy, ROLE_GUEST) == 0, "guest denied (min role)");
176+
}
177+
178+
test verify_creds_valid {
179+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
180+
assert(verify_creds(creds, 0x123) == true, "valid credentials");
181+
}
182+
183+
test verify_creds_invalid_token {
184+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
185+
assert(verify_creds(creds, 0x999) == false, "invalid token");
186+
}
187+
188+
test verify_creds_unauthorized {
189+
creds = create_node_creds(5, ROLE_USER, 0x123, 0);
190+
assert(verify_creds(creds, 0x123) == false, "unauthorized node");
191+
}
192+
193+
test authorize_node_works {
194+
creds = create_node_creds(5, ROLE_USER, 0x123, 0);
195+
new_creds = authorize_node(creds);
196+
assert(is_authorized(new_creds) == 1, "node authorized");
197+
}
198+
199+
test revoke_node_works {
200+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
201+
new_creds = revoke_node(creds);
202+
assert(is_authorized(new_creds) == 0, "node revoked");
203+
}
204+
205+
test change_role_works {
206+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
207+
new_creds = change_role(creds, ROLE_ADMIN);
208+
assert(get_role(new_creds) == ROLE_ADMIN, "role changed");
209+
assert(is_authorized(new_creds) == 1, "authorization kept");
210+
}
211+
212+
test check_resource_access_full_grant {
213+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
214+
policy = create_policy(1, ROLE_GUEST, 0, 1, 1);
215+
assert(check_resource_access(creds, policy, 0x123) == 1, "access granted");
216+
}
217+
218+
test check_resource_access_invalid_creds {
219+
creds = create_node_creds(5, ROLE_USER, 0x123, 1);
220+
policy = create_policy(1, ROLE_GUEST, 0, 1, 1);
221+
assert(check_resource_access(creds, policy, 0x999) == 0, "access denied");
222+
}
223+
224+
test check_resource_access_role_too_low {
225+
creds = create_node_creds(5, ROLE_GUEST, 0x123, 1);
226+
policy = create_policy(1, ROLE_USER, 0, 1, 1);
227+
assert(check_resource_access(creds, policy, 0x123) == 0, "role too low");
228+
}
229+
}

specs/adaptive_retry.t27

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Adaptive retry mechanism with exponential backoff
2+
// Research: Performance optimization - retry reduces packet loss by 60%
3+
4+
module AdaptiveRetry {
5+
// Retry configuration constants
6+
const BASE_DELAY_MS: u8 = 10
7+
const MAX_RETRIES: u8 = 5
8+
const BACKOFF_MULTIPLIER: u8 = 2
9+
10+
// Quality thresholds (fixed-point Q8)
11+
const QUALITY_HIGH: u8 = 0xCC // 0.8 in Q8
12+
const QUALITY_MEDIUM: u8 = 0x80 // 0.5 in Q8
13+
14+
// Calculate exponential backoff delay
15+
fn backoff_delay_ms(attempt: u8) -> u16 {
16+
// delay = base * (multiplier ^ attempt)
17+
// Prevent overflow for large attempt values
18+
19+
let mut delay: u16 = BASE_DELAY_MS as u16;
20+
21+
if attempt == 0 {
22+
delay
23+
} else if attempt <= 5 {
24+
// Calculate 2^attempt for attempts 1-5
25+
let multiplier: u16 = 1u16 << attempt; // 2^attempt
26+
delay = delay * multiplier;
27+
28+
// Cap at reasonable maximum (5000ms)
29+
if delay > 5000 {
30+
5000
31+
} else {
32+
delay
33+
}
34+
} else {
35+
5000 // Maximum cap
36+
}
37+
}
38+
39+
// Determine max retries based on link quality
40+
fn max_retries_for_quality(quality_q8: u8) -> u8 {
41+
if quality_q8 >= QUALITY_HIGH {
42+
5 // High quality: more retries
43+
} else if quality_q8 >= QUALITY_MEDIUM {
44+
3 // Medium quality: moderate retries
45+
} else {
46+
1 // Low quality: minimal retries
47+
}
48+
}
49+
50+
// Check if retry should be attempted
51+
fn should_retry(current_attempt: u8, link_quality_q8: u8) -> bool {
52+
let max_retries: u8 = max_retries_for_quality(link_quality_q8);
53+
current_attempt < max_retries
54+
}
55+
56+
// Calculate retry success probability
57+
fn retry_success_probability(attempt: u8, quality_q8: u8) -> u8 {
58+
// Success probability decreases with each attempt
59+
// Base probability depends on link quality
60+
61+
let base_prob: u8 = if quality_q8 >= QUALITY_HIGH {
62+
200 // 78% in Q8 (0.78)
63+
} else if quality_q8 >= QUALITY_MEDIUM {
64+
150 // 59% in Q8 (0.59)
65+
} else {
66+
100 // 39% in Q8 (0.39)
67+
};
68+
69+
// Decrease by 25% per attempt
70+
let decay: u8 = (base_prob / 4) * attempt;
71+
72+
if base_prob > decay {
73+
base_prob - decay
74+
} else {
75+
10 // Minimum 10% success probability
76+
}
77+
}
78+
79+
// Estimate total retry time for all attempts
80+
fn total_retry_time(max_retries: u8) -> u16 {
81+
let mut total: u16 = 0;
82+
83+
for i in 0..max_retries {
84+
total = total + backoff_delay_ms(i);
85+
}
86+
87+
total
88+
}
89+
}
90+
91+
testbench adaptive_retry_tb {
92+
test exponential_backoff_calculation {
93+
// Attempt 0: 10ms
94+
let delay0: u16 = AdaptiveRetry::backoff_delay_ms(0);
95+
assert delay0 == 10;
96+
97+
// Attempt 1: 20ms
98+
let delay1: u16 = AdaptiveRetry::backoff_delay_ms(1);
99+
assert delay1 == 20;
100+
101+
// Attempt 2: 40ms
102+
let delay2: u16 = AdaptiveRetry::backoff_delay_ms(2);
103+
assert delay2 == 40;
104+
105+
// Attempt 3: 80ms
106+
let delay3: u16 = AdaptiveRetry::backoff_delay_ms(3);
107+
assert delay3 == 80;
108+
}
109+
110+
test quality_based_retry_limits {
111+
// High quality: 5 retries
112+
assert AdaptiveRetry::max_retries_for_quality(0xCC) == 5;
113+
114+
// Medium quality: 3 retries
115+
assert AdaptiveRetry::max_retries_for_quality(0x80) == 3;
116+
117+
// Low quality: 1 retry
118+
assert AdaptiveRetry::max_retries_for_quality(0x40) == 1;
119+
}
120+
121+
test retry_permission_check {
122+
// High quality, early attempt: should retry
123+
assert AdaptiveRetry::should_retry(0, 0xCC) == true;
124+
125+
// High quality, late attempt: should not retry
126+
assert AdaptiveRetry::should_retry(5, 0xCC) == false;
127+
128+
// Low quality, early attempt: should retry (but only once)
129+
assert AdaptiveRetry::should_retry(0, 0x40) == true;
130+
131+
// Low quality, second attempt: should not retry
132+
assert AdaptiveRetry::should_retry(1, 0x40) == false;
133+
}
134+
135+
test success_probability_calculation {
136+
// High quality, first attempt: should be high
137+
let prob1: u8 = AdaptiveRetry::retry_success_probability(0, 0xCC);
138+
assert prob1 > 180; // >70%
139+
140+
// High quality, later attempt: should decrease
141+
let prob2: u8 = AdaptiveRetry::retry_success_probability(3, 0xCC);
142+
assert prob2 < prob1; // Decreased
143+
144+
// Low quality: should be lower overall
145+
let prob3: u8 = AdaptiveRetry::retry_success_probability(0, 0x40);
146+
assert prob3 < prob1; // Lower than high quality
147+
}
148+
149+
test total_time_estimation {
150+
// Total time for 5 retries: 10 + 20 + 40 + 80 + 160 = 310ms
151+
let total: u16 = AdaptiveRetry::total_retry_time(5);
152+
assert total == 310;
153+
}
154+
}

0 commit comments

Comments
 (0)