qvm: recover complete bomb defuse callback
Browse files- docs/FINDINGS.md +2 -0
- docs/PROVISIONAL_TODO.md +2 -0
- docs/RESEARCH_LEDGER.md +4 -0
- docs/REVERSE_ENGINEERING_TODO.md +2 -0
- docs/research/QVM_DEFUSE_COMPLETE.md +5 -0
- docs/research/README.md +2 -0
- docs/research/qvm-defuse-complete.json +0 -0
- docs/research/qvm-resumer-audit.json +95 -1
- scripts/analyze_qvm_defuse_complete.py +12 -0
- scripts/qvm_defuse_oracle.py +13 -0
- scripts/qvm_defuse_support.py +73 -1
- scripts/test_qvm_defuse_complete.py +13 -0
- xtask/checks.tsv +4 -0
docs/FINDINGS.md
CHANGED
|
@@ -1977,3 +1977,5 @@ RE-1017: Rust matches48 far/unflagged cancellation cases. Any nonzero busy state
|
|
| 1977 |
RE-1018: Thirty-two source cases recover active completion when signed wrapped elapsed reaches duration*1000, including equality, negative duration and overflow. Waiting preserves every field. Completion logs first, latches35000396=1, clears clock/busy and owned flags, allocates event84 payload1 with mask32, then requests teleport205260 and award283463 value5. Weapon/animation and neighboring event fields survive. Native nested effects remain captured or supplied. [Evidence](research/QVM_DEFUSE_FINISH.md).
|
| 1978 |
|
| 1979 |
RE-1019: Rust matches32 active source completion cases with signed wrapped elapsed/duration arithmetic and equality completion. The original log/event84/teleport/award order is preserved as plans. Inactive selected state reuses start policy; waiting avoids unused index evaluation, while ready invalid client indices reject before mutation. Unit cases cover exact and wrapped completion, high-bit preservation and waiting/error atomicity. [Evidence](research/RUST_DEFUSE_FINISH.md).
|
|
|
|
|
|
|
|
|
| 1977 |
RE-1018: Thirty-two source cases recover active completion when signed wrapped elapsed reaches duration*1000, including equality, negative duration and overflow. Waiting preserves every field. Completion logs first, latches35000396=1, clears clock/busy and owned flags, allocates event84 payload1 with mask32, then requests teleport205260 and award283463 value5. Weapon/animation and neighboring event fields survive. Native nested effects remain captured or supplied. [Evidence](research/QVM_DEFUSE_FINISH.md).
|
| 1978 |
|
| 1979 |
RE-1019: Rust matches32 active source completion cases with signed wrapped elapsed/duration arithmetic and equality completion. The original log/event84/teleport/award order is preserved as plans. Inactive selected state reuses start policy; waiting avoids unused index evaluation, while ready invalid client indices reject before mutation. Unit cases cover exact and wrapped completion, high-bit preservation and waiting/error atomicity. [Evidence](research/RUST_DEFUSE_FINISH.md).
|
| 1980 |
+
|
| 1981 |
+
RE-1020: Ninety-six source scenarios connect original admission/teammate scan to actual276433 bomb hash lookup and65655 distance, then start/wait/cancel/complete transitions. Three selectors, radius75 equality, zero/64 teammate counts, inactive/classless/hash-mismatched decoys, wrapped time, completed latch and missing bomb are covered. Missing lookup stops before original2319 fatal handler. Native sqrt is modeled; event/native effect feedback is captured or supplied, not executed. [Evidence](research/QVM_DEFUSE_COMPLETE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -2036,3 +2036,5 @@ RE-974–983 completed routing, command rewrite, inactivity, movement-parameter
|
|
| 2036 |
- [x] RE-1018 Recover timed bomb-defuse completion and effect order ([evidence](research/QVM_DEFUSE_FINISH.md)).
|
| 2037 |
|
| 2038 |
- [x] RE-1019 Port timed bomb-defuse completion and captured effects ([evidence](research/RUST_DEFUSE_FINISH.md)).
|
|
|
|
|
|
|
|
|
| 2036 |
- [x] RE-1018 Recover timed bomb-defuse completion and effect order ([evidence](research/QVM_DEFUSE_FINISH.md)).
|
| 2037 |
|
| 2038 |
- [x] RE-1019 Port timed bomb-defuse completion and captured effects ([evidence](research/RUST_DEFUSE_FINISH.md)).
|
| 2039 |
+
|
| 2040 |
+
- [x] RE-1020 Recover complete mode8 bomb-defuse callback ([evidence](research/QVM_DEFUSE_COMPLETE.md)).
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -2751,3 +2751,7 @@ Thirty-two source cases recover active completion when signed wrapped elapsed re
|
|
| 2751 |
## 2026-10-29 — RE-1019 Port timed bomb-defuse completion and captured effects
|
| 2752 |
|
| 2753 |
Rust matches32 active source completion cases with signed wrapped elapsed/duration arithmetic and equality completion. The original log/event84/teleport/award order is preserved as plans. Inactive selected state reuses start policy; waiting avoids unused index evaluation, while ready invalid client indices reject before mutation. Unit cases cover exact and wrapped completion, high-bit preservation and waiting/error atomicity. Focused `cargo xtask test-group rust-defuse-finish` passes with deterministic report regeneration and selected regressions. Full suite deferred to task ten. Original assets unchanged; Python uses the flake-declared Nix runtime.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2751 |
## 2026-10-29 — RE-1019 Port timed bomb-defuse completion and captured effects
|
| 2752 |
|
| 2753 |
Rust matches32 active source completion cases with signed wrapped elapsed/duration arithmetic and equality completion. The original log/event84/teleport/award order is preserved as plans. Inactive selected state reuses start policy; waiting avoids unused index evaluation, while ready invalid client indices reject before mutation. Unit cases cover exact and wrapped completion, high-bit preservation and waiting/error atomicity. Focused `cargo xtask test-group rust-defuse-finish` passes with deterministic report regeneration and selected regressions. Full suite deferred to task ten. Original assets unchanged; Python uses the flake-declared Nix runtime.
|
| 2754 |
+
|
| 2755 |
+
## 2026-10-29 — RE-1020 Recover complete mode8 bomb-defuse callback
|
| 2756 |
+
|
| 2757 |
+
Ninety-six source scenarios connect original admission/teammate scan to actual276433 bomb hash lookup and65655 distance, then start/wait/cancel/complete transitions. Three selectors, radius75 equality, zero/64 teammate counts, inactive/classless/hash-mismatched decoys, wrapped time, completed latch and missing bomb are covered. Missing lookup stops before original2319 fatal handler. Native sqrt is modeled; event/native effect feedback is captured or supplied, not executed. Focused `cargo xtask test-group qvm-defuse-complete` passes with deterministic report regeneration and selected regressions. Full suite deferred to task ten. Original assets unchanged; Python uses the flake-declared Nix runtime.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -2073,3 +2073,5 @@ RE-974–983 recover routing, command rewriting, inactivity and composed setup t
|
|
| 2073 |
- [x] RE-1018 Recover timed bomb-defuse completion and effect order ([evidence](research/QVM_DEFUSE_FINISH.md)).
|
| 2074 |
|
| 2075 |
- [x] RE-1019 Port timed bomb-defuse completion and captured effects ([evidence](research/RUST_DEFUSE_FINISH.md)).
|
|
|
|
|
|
|
|
|
| 2073 |
- [x] RE-1018 Recover timed bomb-defuse completion and effect order ([evidence](research/QVM_DEFUSE_FINISH.md)).
|
| 2074 |
|
| 2075 |
- [x] RE-1019 Port timed bomb-defuse completion and captured effects ([evidence](research/RUST_DEFUSE_FINISH.md)).
|
| 2076 |
+
|
| 2077 |
+
- [x] RE-1020 Recover complete mode8 bomb-defuse callback ([evidence](research/QVM_DEFUSE_COMPLETE.md)).
|
docs/research/QVM_DEFUSE_COMPLETE.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Recover complete mode8 bomb-defuse callback
|
| 2 |
+
|
| 3 |
+
RE-1020. Focused validation: `cargo xtask test-group qvm-defuse-complete`. [Machine report](qvm-defuse-complete.json).
|
| 4 |
+
|
| 5 |
+
Ninety-six source scenarios connect original admission/teammate scan to actual276433 bomb hash lookup and65655 distance, then start/wait/cancel/complete transitions. Three selectors, radius75 equality, zero/64 teammate counts, inactive/classless/hash-mismatched decoys, wrapped time, completed latch and missing bomb are covered. Missing lookup stops before original2319 fatal handler. Native sqrt is modeled; event/native effect feedback is captured or supplied, not executed.
|
docs/research/README.md
CHANGED
|
@@ -1605,3 +1605,5 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 1605 |
- [RE-1018: Recover timed bomb-defuse completion and effect order](QVM_DEFUSE_FINISH.md).
|
| 1606 |
|
| 1607 |
- [RE-1019: Port timed bomb-defuse completion and captured effects](RUST_DEFUSE_FINISH.md).
|
|
|
|
|
|
|
|
|
| 1605 |
- [RE-1018: Recover timed bomb-defuse completion and effect order](QVM_DEFUSE_FINISH.md).
|
| 1606 |
|
| 1607 |
- [RE-1019: Port timed bomb-defuse completion and captured effects](RUST_DEFUSE_FINISH.md).
|
| 1608 |
+
|
| 1609 |
+
- [RE-1020: Recover complete mode8 bomb-defuse callback](QVM_DEFUSE_COMPLETE.md).
|
docs/research/qvm-defuse-complete.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
docs/research/qvm-resumer-audit.json
CHANGED
|
@@ -8939,6 +8939,100 @@
|
|
| 8939 |
"repeated_calls_opt_in": true,
|
| 8940 |
"repeated_calls_setting": "literal_true"
|
| 8941 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8942 |
{
|
| 8943 |
"backward_conditional_branches": [],
|
| 8944 |
"calls": [],
|
|
@@ -10546,7 +10640,7 @@
|
|
| 10546 |
}
|
| 10547 |
},
|
| 10548 |
"summary": {
|
| 10549 |
-
"call_expressions":
|
| 10550 |
"files": 163,
|
| 10551 |
"legacy_expressions": 158,
|
| 10552 |
"nonliteral_ranges": 31,
|
|
|
|
| 8939 |
"repeated_calls_opt_in": true,
|
| 8940 |
"repeated_calls_setting": "literal_true"
|
| 8941 |
},
|
| 8942 |
+
{
|
| 8943 |
+
"backward_conditional_branches": [
|
| 8944 |
+
153595
|
| 8945 |
+
],
|
| 8946 |
+
"calls": [
|
| 8947 |
+
{
|
| 8948 |
+
"dynamic_store_requires_review": false,
|
| 8949 |
+
"implicit_local_offset": 56,
|
| 8950 |
+
"instruction": 153602,
|
| 8951 |
+
"stores_result": true,
|
| 8952 |
+
"target": 276433
|
| 8953 |
+
},
|
| 8954 |
+
{
|
| 8955 |
+
"dynamic_store_requires_review": false,
|
| 8956 |
+
"implicit_local_offset": null,
|
| 8957 |
+
"instruction": 153615,
|
| 8958 |
+
"stores_result": false,
|
| 8959 |
+
"target": 2319
|
| 8960 |
+
},
|
| 8961 |
+
{
|
| 8962 |
+
"dynamic_store_requires_review": false,
|
| 8963 |
+
"implicit_local_offset": 60,
|
| 8964 |
+
"instruction": 153629,
|
| 8965 |
+
"stores_result": true,
|
| 8966 |
+
"target": 65655
|
| 8967 |
+
},
|
| 8968 |
+
{
|
| 8969 |
+
"dynamic_store_requires_review": false,
|
| 8970 |
+
"implicit_local_offset": null,
|
| 8971 |
+
"instruction": 153670,
|
| 8972 |
+
"stores_result": false,
|
| 8973 |
+
"target": 7259
|
| 8974 |
+
},
|
| 8975 |
+
{
|
| 8976 |
+
"dynamic_store_requires_review": false,
|
| 8977 |
+
"implicit_local_offset": 72,
|
| 8978 |
+
"instruction": 153721,
|
| 8979 |
+
"stores_result": true,
|
| 8980 |
+
"target": 277695
|
| 8981 |
+
},
|
| 8982 |
+
{
|
| 8983 |
+
"dynamic_store_requires_review": false,
|
| 8984 |
+
"implicit_local_offset": null,
|
| 8985 |
+
"instruction": 153762,
|
| 8986 |
+
"stores_result": false,
|
| 8987 |
+
"target": 205260
|
| 8988 |
+
},
|
| 8989 |
+
{
|
| 8990 |
+
"dynamic_store_requires_review": false,
|
| 8991 |
+
"implicit_local_offset": null,
|
| 8992 |
+
"instruction": 153770,
|
| 8993 |
+
"stores_result": false,
|
| 8994 |
+
"target": 283463
|
| 8995 |
+
},
|
| 8996 |
+
{
|
| 8997 |
+
"dynamic_store_requires_review": false,
|
| 8998 |
+
"implicit_local_offset": 84,
|
| 8999 |
+
"instruction": 153890,
|
| 9000 |
+
"stores_result": true,
|
| 9001 |
+
"target": 277695
|
| 9002 |
+
},
|
| 9003 |
+
{
|
| 9004 |
+
"dynamic_store_requires_review": false,
|
| 9005 |
+
"implicit_local_offset": null,
|
| 9006 |
+
"instruction": 153923,
|
| 9007 |
+
"stores_result": false,
|
| 9008 |
+
"target": 193620
|
| 9009 |
+
},
|
| 9010 |
+
{
|
| 9011 |
+
"dynamic_store_requires_review": false,
|
| 9012 |
+
"implicit_local_offset": 72,
|
| 9013 |
+
"instruction": 153980,
|
| 9014 |
+
"stores_result": true,
|
| 9015 |
+
"target": 277695
|
| 9016 |
+
},
|
| 9017 |
+
{
|
| 9018 |
+
"dynamic_store_requires_review": false,
|
| 9019 |
+
"implicit_local_offset": 72,
|
| 9020 |
+
"instruction": 154061,
|
| 9021 |
+
"stores_result": true,
|
| 9022 |
+
"target": 277695
|
| 9023 |
+
}
|
| 9024 |
+
],
|
| 9025 |
+
"explicit_result_offsets": null,
|
| 9026 |
+
"helper": "qvm_trace_support.resume",
|
| 9027 |
+
"line": 120,
|
| 9028 |
+
"literal_range": [
|
| 9029 |
+
153420,
|
| 9030 |
+
154088
|
| 9031 |
+
],
|
| 9032 |
+
"path": "scripts/qvm_defuse_support.py",
|
| 9033 |
+
"repeated_calls_opt_in": true,
|
| 9034 |
+
"repeated_calls_setting": "literal_true"
|
| 9035 |
+
},
|
| 9036 |
{
|
| 9037 |
"backward_conditional_branches": [],
|
| 9038 |
"calls": [],
|
|
|
|
| 10640 |
}
|
| 10641 |
},
|
| 10642 |
"summary": {
|
| 10643 |
+
"call_expressions": 214,
|
| 10644 |
"files": 163,
|
| 10645 |
"legacy_expressions": 158,
|
| 10646 |
"nonliteral_ranges": 31,
|
scripts/analyze_qvm_defuse_complete.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Verified original movement-context source contract."""
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from analyze_qvm import write_json
|
| 4 |
+
from qvm_research_support import source
|
| 5 |
+
from qvm_defuse_support import seed,full,full_fixtures
|
| 6 |
+
|
| 7 |
+
def main():
|
| 8 |
+
q,raw,h,ins=source();probes=[]
|
| 9 |
+
for a in full_fixtures():
|
| 10 |
+
m,b=seed(raw,h,a);m,p,b=full(ins,m,b,a);p['input']=a;probes.append(p)
|
| 11 |
+
write_json(Path('docs/research/qvm-defuse-complete.json'),dict(source=q['source'],sha256=q['sha256'],probes=probes,limits='Complete153419 effects through154087 or missing-bomb fatal boundary153612, with actual276433 and65655; finite native sqrt modeled. Event allocation supplied and log/sound/teleport/award captured.'))
|
| 12 |
+
if __name__=='__main__':main()
|
scripts/qvm_defuse_oracle.py
CHANGED
|
@@ -18,3 +18,16 @@ def finish(a):
|
|
| 18 |
if signed((a['tick']-a['clock'])&0xffffffff)>=signed((a['duration']*1000)&0xffffffff):
|
| 19 |
out.update(flags=a['flags']&~4,flags104=a['flags104']&~16,busy=0,clock=0,complete=1,event=[1,0x80000021],events=[dict(op='log',format=b'Bomb was defused by %i!\n'.hex(),slot=2),dict(op='allocate',event=84),dict(op='teleport',slot=2),dict(op='award',slot=2,value=5)])
|
| 20 |
return out
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
if signed((a['tick']-a['clock'])&0xffffffff)>=signed((a['duration']*1000)&0xffffffff):
|
| 19 |
out.update(flags=a['flags']&~4,flags104=a['flags104']&~16,busy=0,clock=0,complete=1,event=[1,0x80000021],events=[dict(op='log',format=b'Bomb was defused by %i!\n'.hex(),slot=2),dict(op='allocate',event=84),dict(op='teleport',slot=2),dict(op='award',slot=2,value=5)])
|
| 20 |
return out
|
| 21 |
+
|
| 22 |
+
from qvm_move_callbacks_oracle import word,f32
|
| 23 |
+
def full(a):
|
| 24 |
+
from qvm_move_callbacks_oracle import eligibility
|
| 25 |
+
gate=eligibility(dict(a,own_busy=a['busy']))['eligible'];out=initial(a);out.update(events=[],lookups=[],distances=[],missing=False)
|
| 26 |
+
if not gate:return out
|
| 27 |
+
bomb=None if a['bomb_missing'] else 5 if a['bomb_first'] else 4;out['lookups']=[bomb]
|
| 28 |
+
if bomb is None:out['missing']=True;return out
|
| 29 |
+
d=f32(a['distance'] if bomb==4 else 30.);distance=f32(__import__('math').sqrt(f32(d*d)));out['distances']=[word(distance)]
|
| 30 |
+
if distance>=75 or not a['flags']&32768:out.update(cancel(a))
|
| 31 |
+
elif a['busy']:out.update(finish(a))
|
| 32 |
+
else:out.update(begin(a))
|
| 33 |
+
return out
|
scripts/qvm_defuse_support.py
CHANGED
|
@@ -19,7 +19,7 @@ def state_seed(m,a):
|
|
| 19 |
m.update({CLIENT+220:a['flags'],CLIENT+104:a['flags104'],CLIENT+6164:a['busy'],35000484:a['clock'],35000396:a['complete'],CLIENT+148:a['animation'],CLIENT+144:a['index'],CLIENT+312+4*a['index']:a['weapon'],34992532:a['tick'],34080132:a['duration'],ALLOC+184:7,ALLOC+180:0xaabbccdd,ALLOC+188:0x11223344})
|
| 20 |
def handlers(events):
|
| 21 |
def allocate(i,m,a,b):
|
| 22 |
-
assert a[8]==
|
| 23 |
events.append(dict(op='allocate',event=a[12]));return m,ALLOC,{'supplied_event_entity':True}
|
| 24 |
def sound(i,m,a,b):
|
| 25 |
assert a[8]==7 and a[12]==ENTITY
|
|
@@ -48,3 +48,75 @@ def finish_fixtures():
|
|
| 48 |
from itertools import product
|
| 49 |
return [dict(defaults(),busy=1,flags=f,tick=tick,clock=clock,duration=d) for f,(tick,clock),d in product([0x80008004,0xffffffff],[(10000,5000),(10000,5001),(10000,10001),(10,0xfffffff0)],[0,5,0xffffffff,0x80000000])]
|
| 50 |
def finish(ins,m,b,a):return fragment(ins,m,b,a,153644)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
m.update({CLIENT+220:a['flags'],CLIENT+104:a['flags104'],CLIENT+6164:a['busy'],35000484:a['clock'],35000396:a['complete'],CLIENT+148:a['animation'],CLIENT+144:a['index'],CLIENT+312+4*a['index']:a['weapon'],34992532:a['tick'],34080132:a['duration'],ALLOC+184:7,ALLOC+180:0xaabbccdd,ALLOC+188:0x11223344})
|
| 20 |
def handlers(events):
|
| 21 |
def allocate(i,m,a,b):
|
| 22 |
+
assert a[8]==m[BASE+32]+24 and a[12] in [83,84]
|
| 23 |
events.append(dict(op='allocate',event=a[12]));return m,ALLOC,{'supplied_event_entity':True}
|
| 24 |
def sound(i,m,a,b):
|
| 25 |
assert a[8]==7 and a[12]==ENTITY
|
|
|
|
| 48 |
from itertools import product
|
| 49 |
return [dict(defaults(),busy=1,flags=f,tick=tick,clock=clock,duration=d) for f,(tick,clock),d in product([0x80008004,0xffffffff],[(10000,5000),(10000,5001),(10000,10001),(10,0xfffffff0)],[0,5,0xffffffff,0x80000000])]
|
| 50 |
def finish(ins,m,b,a):return fragment(ins,m,b,a,153644)
|
| 51 |
+
|
| 52 |
+
import math,copy
|
| 53 |
+
HASH=(-82007226)&0xffffffff
|
| 54 |
+
|
| 55 |
+
def full_fixtures():
|
| 56 |
+
profiles=list(range(32));rows=[]
|
| 57 |
+
for profile in profiles:
|
| 58 |
+
for selector in [0,1,2]:
|
| 59 |
+
a=dict(defaults(),profile=profile,entity=1,client=1,enabled_a=1,enabled_b=1,start=8000,delay=1,connection=2,health=1,follow=0,team=0,other_busy=0,other_connection=2,other_health=1,other_follow=0,other_team=0,count=3,busy_slot=0,selector=selector,distance=10.,bomb_first=0,bomb_missing=0)
|
| 60 |
+
if profile==1:a['busy']=1;a['clock']=9000
|
| 61 |
+
if profile==2:a['busy']=1;a['clock']=5000
|
| 62 |
+
if profile==3:a['distance']=75.;a['busy']=1
|
| 63 |
+
if profile==4:a['distance']=74.999
|
| 64 |
+
if profile==5:a['flags']&=~32768;a['busy']=1
|
| 65 |
+
if profile==6:a['enabled_a']=0
|
| 66 |
+
if profile==7:a['enabled_b']=0
|
| 67 |
+
if profile==8:a['start']=9000
|
| 68 |
+
if profile==9:a['complete']=1;a['busy']=1
|
| 69 |
+
if profile==10:a['connection']=1
|
| 70 |
+
if profile==11:a['health']=0
|
| 71 |
+
if profile==12:a['follow']=1
|
| 72 |
+
if profile==13:a['team']=3
|
| 73 |
+
if profile==14:a['entity']=0
|
| 74 |
+
if profile==15:a['client']=0
|
| 75 |
+
if profile==16:a['other_busy']=1
|
| 76 |
+
if profile==17:a['other_busy']=1;a['other_health']=0
|
| 77 |
+
if profile==18:a['other_busy']=1;a['other_follow']=1
|
| 78 |
+
if profile==19:a['other_busy']=1;a['other_connection']=1
|
| 79 |
+
if profile==20:a['other_busy']=1;a['other_team']=3
|
| 80 |
+
if profile==21:a['count']=0;a['other_busy']=1
|
| 81 |
+
if profile==22:a['count']=64;a['other_busy']=1;a['busy_slot']=63
|
| 82 |
+
if profile==23:a['bomb_first']=1
|
| 83 |
+
if profile==24:a['bomb_first']=2
|
| 84 |
+
if profile==25:a['bomb_first']=3
|
| 85 |
+
if profile==26:a['bomb_missing']=1
|
| 86 |
+
if profile==27:a['tick']=10;a['start']=0xfffff000;a['busy']=1;a['clock']=0xfffffff0;a['duration']=0
|
| 87 |
+
if profile==28:a['duration']=0xffffffff;a['busy']=1
|
| 88 |
+
if profile==29:a['duration']=0;a['busy']=0
|
| 89 |
+
if profile==30:a['flags']&=~32
|
| 90 |
+
if profile==31:a['busy']=0;a['flags']=0x80008040
|
| 91 |
+
rows.append(a)
|
| 92 |
+
return rows
|
| 93 |
+
|
| 94 |
+
def full_seed(m,b,a):
|
| 95 |
+
from qvm_move_callbacks_support import eligibility_seed
|
| 96 |
+
eligibility_seed(m,dict(a,own_busy=a['busy']));state_seed(m,a)
|
| 97 |
+
m[34992508]=6
|
| 98 |
+
for j in range(6):
|
| 99 |
+
e=POOL+880*j;m.update({e+532:1,e+536:1,e+540:0})
|
| 100 |
+
for j in [4,5]:
|
| 101 |
+
e=POOL+880*j;m[e+540]=HASH
|
| 102 |
+
for k in range(3):m[e+24+4*k]=word((a['distance'] if j==4 else 30.) if k==0 else 0.)
|
| 103 |
+
for k in range(3):m[ENTITY+488+4*k]=word(0.)
|
| 104 |
+
if a['bomb_first']==1:m[BOMB+532]=0
|
| 105 |
+
if a['bomb_first']==2:m[BOMB+536]=0
|
| 106 |
+
if a['bomb_first']==3:m[BOMB+540]=0
|
| 107 |
+
if a['bomb_missing']:m[BOMB+540]=0;m[BOMB+880+540]=0
|
| 108 |
+
|
| 109 |
+
def full_run(ins,m,b,a):
|
| 110 |
+
events=[];lookups=[];distances=[]
|
| 111 |
+
def lookup(i,m,args,bs):
|
| 112 |
+
assert args[8]==0 and (args[12]&0xffffffff)==HASH
|
| 113 |
+
m,value,p,b=find_class(i,m,args,dict(bs),base=ROOT+0xf0000)
|
| 114 |
+
lookups.append(None if not value else (value-POOL)//880);return m,value,{'actual_source_child':276433}
|
| 115 |
+
def distance(i,m,args,bs):
|
| 116 |
+
def sqrt(i,m,args,b):return m,word(math.sqrt(number(args[8]))),{'modeled_native_sqrt':True}
|
| 117 |
+
m,value,p,b=run(i,m,65655,65728,40,args,dict(bs),{-107:sqrt},base=ROOT+0x100000)
|
| 118 |
+
distances.append(value&0xffffffff);return m,value,{'actual_source_child':65655}
|
| 119 |
+
m,b=frame_args(m,b,{BASE+100:ENTITY if a['entity'] else 0})
|
| 120 |
+
m,p=resume(ins,153420,154088,m,BASE,boundaries=(153612,154087),handlers={**handlers(events),276433:lookup,65655:distance},byte_inputs=b,repeated_calls=True,sync_child_words=True,coherent_memory=True,byte_handlers=True,capture_byte_memory=True,limit=32768)
|
| 121 |
+
return m,dict(**view(m,a),events=events,lookups=lookups,distances=distances,missing=p['stop']==153612,execution={k:p[k] for k in ['stop','trace_length','trace_sha256']}),p['byte_memory']
|
| 122 |
+
def full(ins,m,b,a):full_seed(m,b,a);return full_run(ins,m,b,a)
|
scripts/test_qvm_defuse_complete.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from qvm_defuse_oracle import full
|
| 4 |
+
class OriginalTests(unittest.TestCase):
|
| 5 |
+
def test_original_contract(self):
|
| 6 |
+
rows=json.loads(Path('docs/research/qvm-defuse-complete.json').read_text())['probes'];self.assertEqual(len(rows),96)
|
| 7 |
+
for p in rows:
|
| 8 |
+
with self.subTest(input=p['input']):
|
| 9 |
+
for k,v in full(p['input']).items():self.assertEqual(p[k],v,k)
|
| 10 |
+
def test_fixture_identity_and_trace(self):
|
| 11 |
+
r=json.loads(Path('docs/research/qvm-defuse-complete.json').read_text());self.assertEqual(len(r['sha256']),64)
|
| 12 |
+
self.assertTrue(all(p['execution']['trace_length']>0 for p in r['probes']))
|
| 13 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -4242,3 +4242,7 @@ edge crates/urt-gameplay/src/move_callbacks.rs scripts/analyze_rust_defuse_finis
|
|
| 4242 |
edge crates/urt-gameplay/src/defuse.rs scripts/analyze_rust_defuse_finish.py
|
| 4243 |
edge crates/urt-gameplay/src/bin/urt-defuse.rs scripts/analyze_rust_defuse_finish.py
|
| 4244 |
edge crates/urt-gameplay/src/move_callbacks.rs scripts/analyze_rust_defuse_finish.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4242 |
edge crates/urt-gameplay/src/defuse.rs scripts/analyze_rust_defuse_finish.py
|
| 4243 |
edge crates/urt-gameplay/src/bin/urt-defuse.rs scripts/analyze_rust_defuse_finish.py
|
| 4244 |
edge crates/urt-gameplay/src/move_callbacks.rs scripts/analyze_rust_defuse_finish.py
|
| 4245 |
+
report scripts/analyze_qvm_defuse_complete.py docs/research/qvm-defuse-complete.json
|
| 4246 |
+
edge docs/research/qvm-defuse-complete.json scripts/test_qvm_defuse_complete.py
|
| 4247 |
+
group qvm-defuse-complete scripts/analyze_qvm_defuse_complete.py
|
| 4248 |
+
edge scripts/analyze_qvm_defuse_complete.py scripts/analyze_qvm_resumer_audit.py
|