Quazim0t0 commited on
Commit
bdfb884
·
verified ·
1 Parent(s): 9867763

Import from Quazim0t0/neural-storage; repoint refs to NeuralVerified

Browse files
GF256.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:95a3bd56efcb21b046ccb4b400a0965d720bd4828e883cb543c584f2e9dca77d
3
+ size 564882
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dean Byrne (Quazim0t0)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ library_name: pytorch
4
+ tags:
5
+ - verified-units
6
+ - reed-solomon
7
+ - erasure-coding
8
+ - deduplication
9
+ - storage
10
+ ---
11
+
12
+ # neural-storage — self-healing vault with a verified GF(256) core
13
+
14
+ **Repositories:** [GitHub](https://github.com/quzi93/neural-storage) · [🤗 HuggingFace](https://huggingface.co/NeuralVerified/neural-storage)
15
+
16
+ A content-addressed, deduplicating, **self-healing** storage vault. Any *k* of *n*
17
+ Reed-Solomon shards reconstruct the whole, so pieces can be lost or corrupted and
18
+ the data survives. The erasure-coding arithmetic — GF(2⁸) multiply — is provided
19
+ by neural `LOG`/`EXP` units verified **bit-exact over all 65,536 (a,b) pairs**,
20
+ the same N/N discipline as
21
+ [neural-aarch64-units](https://huggingface.co/NeuralVerified/neural-aarch64-units).
22
+
23
+ > **Honest by design:** dedup removes *redundant* data; RS *adds* redundancy for
24
+ > resilience. Incompressible data never shrinks — you cannot beat entropy. Chunk
25
+ > hashes are real SHA-256, not a neural emulation.
26
+
27
+ ## What's verified
28
+
29
+ - `GF256` (`LOG`/`EXP`): GF(2⁸) multiply — **composed multiply 65536/65536**
30
+ - Reed-Solomon any-*k*-of-*n* recovery (every loss pattern)
31
+ - `Vault`: dedup + RS shards on disk, survives deleted/corrupted shards, `heal()`s
32
+ - `VaultFS` + optional WinFsp drive-letter mount
33
+
34
+ ## Use
35
+
36
+ ```bash
37
+ pip install torch
38
+ python step1_storage.py # verified GF(256) + dedup chunk store
39
+ python step2_rs.py # Reed-Solomon recovery
40
+ python step3_vault.py # self-healing vault
41
+
42
+ python cli.py store <vault> <folder>
43
+ python cli.py export <vault> <folder> # RS-healed reconstruct
44
+ python cli.py mount <vault> X: # requires WinFsp
45
+
46
+ # image a whole drive/partition into a self-healing .pt (may need admin):
47
+ python cli.py image \\.\C: diskC.pt
48
+ python cli.py image-verify diskC.pt
49
+ python cli.py image-restore diskC.pt out.img
50
+ ```
51
+
52
+ Weights: `GF256.pt`.
53
+
54
+ **Create your own verified unit** (template: `storage/gf256.py`): write the exact
55
+ golden finite function → enumerate the domain (decompose big/linear ones into
56
+ bit/byte slices, see `storage/rs.py`) → `common.train` → `common.verify` must be
57
+ bit-exact on 100% of inputs → compose. `step1_storage.py` shows the full loop.
58
+
59
+ ## Citation
60
+
61
+ ```bibtex
62
+ @misc{byrne2026neuralstorage,
63
+ title = {neural-storage: Self-Healing Erasure-Coded Vault with a Verified GF(256) Core},
64
+ author = {Byrne, Dean (Quazim0t0)},
65
+ year = {2026},
66
+ howpublished = {\url{https://huggingface.co/NeuralVerified/neural-storage}}
67
+ }
68
+ ```
69
+
70
+ **Dean Byrne (Quazim0t0)** · 2026
71
+
72
+
73
+ ---
74
+
75
+ <!-- neuralverified-relocation-note -->
76
+ > **Now hosted by [NeuralVerified](https://huggingface.co/NeuralVerified).**
77
+ >
78
+ > This repo was moved into the NeuralVerified organization to help organize my profile.
79
+ > Originally published at [`Quazim0t0/neural-storage`](https://huggingface.co/Quazim0t0/neural-storage).
cli.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ neural-vault CLI. Dependency-free except `mount` (needs WinFsp + winfspy).
3
+
4
+ store <vault> <src_folder> [--k K --m M] ingest a folder (dedup + RS)
5
+ ls <vault> list stored files
6
+ stat <vault> dedup / redundancy stats
7
+ export <vault> <dst_folder> reconstruct all files (RS-healed)
8
+ heal <vault> regenerate any missing shards
9
+ mount <vault> <mountpoint> expose as a drive (WinFsp)
10
+
11
+ image <device> <out.pt> [--k --m --part-mb] scan a whole drive/partition
12
+ (e.g. \\\\.\\C: or an .img, may need admin) into a self-healing .pt
13
+ image-verify <out.pt> report archive health
14
+ image-heal <out.pt> repair detected bit-rot
15
+ image-restore <out.pt> <out.img> reconstruct the image bit-exact
16
+ """
17
+ import argparse
18
+ from storage.vault import Vault
19
+ from storage.vaultfs import winfsp_available
20
+ from storage import diskimage
21
+
22
+
23
+ def main():
24
+ ap = argparse.ArgumentParser(prog="neural-vault")
25
+ sub = ap.add_subparsers(dest="cmd", required=True)
26
+ p = sub.add_parser("store"); p.add_argument("vault"); p.add_argument("src")
27
+ p.add_argument("--k", type=int, default=4); p.add_argument("--m", type=int, default=2)
28
+ for name in ("ls", "stat", "heal"):
29
+ q = sub.add_parser(name); q.add_argument("vault")
30
+ e = sub.add_parser("export"); e.add_argument("vault"); e.add_argument("dst")
31
+ mo = sub.add_parser("mount"); mo.add_argument("vault"); mo.add_argument("mountpoint")
32
+ im = sub.add_parser("image"); im.add_argument("device"); im.add_argument("out")
33
+ im.add_argument("--k", type=int, default=4); im.add_argument("--m", type=int, default=2)
34
+ im.add_argument("--part-mb", type=int, default=64); im.add_argument("--label")
35
+ iv = sub.add_parser("image-verify"); iv.add_argument("out")
36
+ ih = sub.add_parser("image-heal"); ih.add_argument("out")
37
+ ir = sub.add_parser("image-restore"); ir.add_argument("out"); ir.add_argument("dst")
38
+ args = ap.parse_args()
39
+
40
+ if args.cmd == "store":
41
+ v = Vault(args.vault, args.k, args.m)
42
+ v.store_folder(args.src)
43
+ s = v.stats()
44
+ print(f"stored {len(v.list_files())} files, {s['unique_chunks']} unique chunks, "
45
+ f"{s['stored']//1024} KB on disk ({s['overhead']:.2f}x, RS {args.k}+{args.m})")
46
+ elif args.cmd == "ls":
47
+ for rel, sz in Vault(args.vault).list_files():
48
+ print(f"{sz:>10} {rel}")
49
+ elif args.cmd == "stat":
50
+ s = Vault(args.vault).stats()
51
+ print(f"logical {s['logical']//1024} KB | stored {s['stored']//1024} KB | "
52
+ f"{s['unique_chunks']} chunks | overhead {s['overhead']:.2f}x")
53
+ elif args.cmd == "heal":
54
+ print(f"regenerated {Vault(args.vault).heal()} missing shard(s)")
55
+ elif args.cmd == "export":
56
+ print(f"exported {Vault(args.vault).export(args.dst)} files")
57
+ elif args.cmd == "mount":
58
+ if not winfsp_available():
59
+ print("WinFsp/winfspy not installed. Install WinFsp (https://winfsp.dev) "
60
+ "and `pip install winfspy`, or use `export` for now.")
61
+ return
62
+ from storage.vaultfs import mount
63
+ fs = mount(Vault(args.vault), args.mountpoint)
64
+ print(f"mounted vault at {args.mountpoint} (Ctrl+C to unmount)")
65
+ try:
66
+ import time
67
+ while True:
68
+ time.sleep(1)
69
+ except KeyboardInterrupt:
70
+ fs.stop()
71
+ print("unmounted")
72
+ elif args.cmd == "image":
73
+ r = diskimage.create(args.device, args.out, k=args.k, m=args.m,
74
+ part_mb=args.part_mb, label=args.label)
75
+ red = (args.k + args.m) / args.k
76
+ print(f"imaged {r['bytes']//1024} KB -> {r['out']} ({r['mode']}, {r['parts']} part(s), "
77
+ f"RS {args.k}+{args.m} ~{red:.2f}x). bad sectors: {r['bad_sectors']}")
78
+ if r["bad_sectors"]:
79
+ print(f" WARNING: {r['bad_sectors']} sectors unreadable at scan (zero-filled).")
80
+ elif args.cmd == "image-verify":
81
+ h = diskimage.verify(args.out)
82
+ print(f"health: {'HEALTHY' if h['healthy'] else 'DAMAGED'} "
83
+ f"chunks={h['chunks']} corrupted_shards={h['corrupted_shards']} "
84
+ f"repairable={h['repairable_chunks']} lost={h['lost_chunks']}")
85
+ elif args.cmd == "image-heal":
86
+ print(f"repaired {diskimage.heal(args.out)} shard(s)")
87
+ elif args.cmd == "image-restore":
88
+ n = diskimage.restore(args.out, args.dst)
89
+ print(f"restored {n//1024} KB -> {args.dst}")
90
+
91
+
92
+ if __name__ == "__main__":
93
+ main()
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ torch
step1_storage.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Step 1: verified GF(256) multiply (RS keystone) + content-addressed chunk store.
3
+
4
+ (a) LOG / EXP verified N/N (255/255 each)
5
+ (b) COMPOSED GF(256) multiply verified over all 65,536 (a,b) pairs
6
+ (c) chunk store reconstructs a 'drive image' bit-exact
7
+ (d) dedup removes redundancy (real savings), and is bit-verified by SHA-256
8
+ (e) honesty: incompressible data yields ~no savings (no beating entropy)
9
+ """
10
+ import os
11
+ import torch
12
+ from storage import gf256
13
+ from storage.common import verify
14
+ from storage.chunkstore import ChunkStore
15
+
16
+ torch.manual_seed(0)
17
+
18
+ print("=" * 62)
19
+ print("STEP 1 -- verified GF(256) + content-addressed chunk store")
20
+ print("=" * 62)
21
+
22
+ # ---- verified coding keystone ----
23
+ net_log, net_exp = gf256.train_units()
24
+ lok, ltot = verify(net_log, *gf256.log_domain())
25
+ eok, etot = verify(net_exp, *gf256.exp_domain())
26
+ mok, mtot = gf256.verify_mul(net_log, net_exp)
27
+ print("-" * 62)
28
+ print(f"(a) LOG verified {lok}/{ltot} | EXP verified {eok}/{etot} -> "
29
+ f"{'PASS' if lok==ltot and eok==etot else 'FAIL'}")
30
+ print(f"(b) COMPOSED GF(256) multiply verified {mok}/{mtot} -> "
31
+ f"{'PASS' if mok==mtot else 'FAIL'}")
32
+
33
+ # ---- content-addressed chunk store on a synthetic 'drive image' ----
34
+ fileA = os.urandom(64 * 1024)
35
+ fileB = os.urandom(64 * 1024)
36
+ fileC = os.urandom(64 * 1024)
37
+ tail = os.urandom(64 * 1024)
38
+ # a drive with duplicated files (A and B appear twice) + unique C + unique tail
39
+ image = fileA + fileB + fileA + fileC + fileB + tail
40
+
41
+ cs = ChunkStore()
42
+ manifest = cs.put_stream(image)
43
+ rebuilt = cs.reconstruct(manifest)
44
+
45
+ exact = rebuilt == image
46
+ print("-" * 62)
47
+ print(f"(c) reconstruct drive image: {'bit-exact PASS' if exact else 'FAIL'} "
48
+ f"({len(image)} bytes)")
49
+ print(f"(d) integrity (all chunks hash-verified): "
50
+ f"{'PASS' if cs.integrity_ok() else 'FAIL'}")
51
+ st = cs.stats()
52
+ print(f" logical {st['logical_bytes']//1024} KB -> stored {st['stored_bytes']//1024} KB "
53
+ f"dedup {st['dedup_ratio']:.2f}x "
54
+ f"({st['unique_chunks']}/{st['total_chunks']} chunks unique)")
55
+
56
+ # ---- honesty check: incompressible random data must NOT shrink ----
57
+ rnd = os.urandom(384 * 1024)
58
+ cs2 = ChunkStore()
59
+ cs2.reconstruct(cs2.put_stream(rnd)) # store it
60
+ st2 = cs2.stats()
61
+ print(f"(e) incompressible 384 KB: dedup {st2['dedup_ratio']:.2f}x "
62
+ f"-> {'PASS (no magic)' if st2['dedup_ratio'] < 1.05 else 'unexpected'}")
63
+
64
+ allpass = (lok == ltot and eok == etot and mok == mtot and exact
65
+ and cs.integrity_ok() and st['dedup_ratio'] > 1.2 and st2['dedup_ratio'] < 1.05)
66
+ print("=" * 62)
67
+ print(f"OVERALL: {'ALL PASS' if allpass else 'some checks failed'}")
68
+
69
+ if lok == ltot and eok == etot and mok == mtot:
70
+ torch.save({"log": net_log.state_dict(), "exp": net_exp.state_dict(),
71
+ "meta": {"unit": "GF256_MUL(log/exp)", "poly": "0x11D",
72
+ "multiply_verified": f"{mok}/{mtot}"}}, "GF256.pt")
73
+ print("saved verified units -> GF256.pt")
step2_rs.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Step 2: Reed-Solomon erasure coding on the verified GF(256) core.
3
+
4
+ (a) neural coding equivalence -> parity computed via the NEURAL gf_mul equals
5
+ the golden RS parity (the verified units drive the code)
6
+ (b) any-k-of-n recovery -> RS(k=4, m=2): reconstruct from EVERY possible
7
+ 2-shard-loss pattern, bit-exact
8
+ (c) shards are bit-verified -> each shard addressed by SHA-256
9
+ (d) honesty -> n shards total (k+m)/k x the data (redundancy,
10
+ not shrinkage)
11
+ """
12
+ import os
13
+ import hashlib
14
+ import itertools
15
+ import torch
16
+ from storage import gf256, rs
17
+ from storage.common import verify
18
+
19
+ torch.manual_seed(0)
20
+
21
+ print("=" * 62)
22
+ print("STEP 2 -- Reed-Solomon erasure coding (verified GF core)")
23
+ print("=" * 62)
24
+
25
+ # load or train the verified GF units
26
+ try:
27
+ ck = torch.load("GF256.pt", map_location="cpu")
28
+ from storage.common import mlp
29
+ net_log = mlp(8, 8, 256, 2); net_log.load_state_dict(ck["log"])
30
+ net_exp = mlp(8, 8, 256, 2); net_exp.load_state_dict(ck["exp"])
31
+ print("loaded verified GF units from GF256.pt")
32
+ except Exception:
33
+ net_log, net_exp = gf256.train_units()
34
+
35
+ # (a) neural coding equivalence
36
+ neq = rs.neural_parity_equiv(net_log, net_exp)
37
+ print(f"(a) neural gf_mul parity == golden RS parity -> {'PASS' if neq else 'FAIL'}")
38
+
39
+ # (b) any-k-of-n recovery over a real 'drive image'
40
+ K, M = 4, 2
41
+ N = K + M
42
+ image = os.urandom(300 * 1024) # 300 KB payload
43
+ shards, L, orig = rs.encode(image, K, M)
44
+ print(f" RS({K}+{M}): {N} shards of {L//1024} KB each (tolerates up to {M} lost)")
45
+
46
+ fails = 0
47
+ patterns = list(itertools.combinations(range(N), M)) # every 2-shard-loss case
48
+ for lost in patterns:
49
+ present = {i: bytes(shards[i]) for i in range(N) if i not in lost}
50
+ if rs.decode(present, K, M, L, orig) != image:
51
+ fails += 1
52
+ print(f"(b) recover from every {M}-loss pattern ({len(patterns)} of them): "
53
+ f"{'PASS' if fails == 0 else f'FAIL({fails})'}")
54
+
55
+ # (c) shards bit-verified by SHA-256
56
+ ids = [hashlib.sha256(bytes(s)).hexdigest()[:12] for s in shards]
57
+ verified = all(hashlib.sha256(bytes(shards[i])).hexdigest()[:12] == ids[i] for i in range(N))
58
+ print(f"(c) shard hashes (bit-verified): {'PASS' if verified else 'FAIL'} "
59
+ f"e.g. shard0={ids[0]}")
60
+
61
+ # (d) honesty: storage overhead is exactly the redundancy, nothing shrinks
62
+ overhead = N * L / len(image)
63
+ print(f"(d) storage: {len(image)//1024} KB -> {N*L//1024} KB ({overhead:.2f}x) "
64
+ f"-> {'PASS (redundancy, no shrink)' if overhead >= 1.0 else 'FAIL'}")
65
+
66
+ allpass = neq and fails == 0 and verified and overhead >= 1.0
67
+ print("=" * 62)
68
+ print(f"OVERALL: {'ALL PASS' if allpass else 'some checks failed'}")
step3_vault.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Step 3: the Vault -- dedup + RS-protected store that reconstructs files on demand
3
+ and survives shard loss. Runs with no external dependencies (WinFsp only needed
4
+ for the live drive-letter mount).
5
+
6
+ (a) store a folder (with duplicate files) -> dedup
7
+ (b) reconstruct every file bit-exact via the read layer (VaultFS)
8
+ (c) DAMAGE: delete up to m shards from chunks -> files still read (RS-heal)
9
+ (d) heal() regenerates the missing shards; integrity restored
10
+ """
11
+ import os
12
+ import random
13
+ import shutil
14
+ import tempfile
15
+ from storage.vault import Vault
16
+ from storage.vaultfs import VaultFS, winfsp_available
17
+
18
+ random.seed(0)
19
+ root = tempfile.mkdtemp(prefix="nvault_")
20
+ src = os.path.join(root, "src"); os.makedirs(os.path.join(src, "sub"))
21
+ vault_dir = os.path.join(root, "vault")
22
+ dst = os.path.join(root, "restored")
23
+
24
+ print("=" * 62)
25
+ print("STEP 3 -- Vault: dedup + RS-protected virtual storage")
26
+ print("=" * 62)
27
+
28
+ # build a source folder with a duplicated file (photo.bin appears twice)
29
+ photo = os.urandom(120 * 1024)
30
+ files = {
31
+ "photo.bin": photo,
32
+ "sub/photo_copy.bin": photo, # exact duplicate -> dedup
33
+ "notes.txt": ("neural vault demo\n" * 4000).encode(),
34
+ "random.bin": os.urandom(80 * 1024),
35
+ }
36
+ for rel, data in files.items():
37
+ p = os.path.join(src, rel)
38
+ os.makedirs(os.path.dirname(p), exist_ok=True)
39
+ open(p, "wb").write(data)
40
+
41
+ # (a) store
42
+ v = Vault(vault_dir, k=4, m=2)
43
+ v.store_folder(src)
44
+ s = v.stats()
45
+ logical_files = sum(len(d) for d in files.values())
46
+ print(f"(a) stored {len(v.list_files())} files, {s['unique_chunks']} unique chunks; "
47
+ f"logical {logical_files//1024} KB, on-disk {s['stored']//1024} KB "
48
+ f"(RS 4+2 => ~1.5x of DEDUPED data)")
49
+
50
+ # (b) reconstruct via read layer, compare to originals
51
+ fs = VaultFS(v)
52
+ ok = all(fs.read(rel) == files[rel] for rel in files)
53
+ print(f"(b) reconstruct every file bit-exact (VaultFS.read): {'PASS' if ok else 'FAIL'}")
54
+
55
+ # (c) DAMAGE: delete up to m=2 shards from each chunk, then read anyway
56
+ deleted = 0
57
+ for h in os.listdir(v.cdir):
58
+ d = v._cd(h)
59
+ if not os.path.isfile(os.path.join(d, "meta.json")):
60
+ continue
61
+ shard_files = [f for f in os.listdir(d) if f.startswith("shard_")]
62
+ for f in random.sample(shard_files, k=random.randint(1, 2)): # <= m
63
+ os.remove(os.path.join(d, f)); deleted += 1
64
+ fs2 = VaultFS(v) # fresh (no cache)
65
+ survived = all(fs2.read(rel) == files[rel] for rel in files)
66
+ print(f"(c) deleted {deleted} shard files (<=2/chunk); files still read: "
67
+ f"{'PASS (RS-healed on read)' if survived else 'FAIL'}")
68
+
69
+ # (d) heal regenerates missing shards
70
+ healed = v.heal()
71
+ full = v.integrity_ok()
72
+ print(f"(d) heal() regenerated {healed} shard(s); integrity restored: "
73
+ f"{'PASS' if full else 'FAIL'}")
74
+
75
+ # export as final proof
76
+ n = v.export(dst)
77
+ export_ok = all(open(os.path.join(dst, rel), "rb").read() == files[rel] for rel in files)
78
+ print(f" export {n} files -> {'bit-exact PASS' if export_ok else 'FAIL'}")
79
+
80
+ print("-" * 62)
81
+ print(f"WinFsp drive-letter mount available on this machine: {winfsp_available()} "
82
+ f"({'ready: python cli.py mount <vault> X:' if winfsp_available() else 'use: python cli.py export <vault> <folder>'})")
83
+
84
+ allpass = ok and survived and full and export_ok
85
+ print("=" * 62)
86
+ print(f"OVERALL: {'ALL PASS' if allpass else 'some checks failed'}")
87
+ shutil.rmtree(root, ignore_errors=True)
storage/__init__.py ADDED
File without changes
storage/archive.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Self-healing .pt disc archive.
3
+
4
+ A disc image is chunked (fixed size), duplicate chunks deduped, and each unique
5
+ chunk Reed-Solomon split into n = k+m shards (verified GF(256) core). Every shard
6
+ carries its own SHA-256, so SILENT corruption (bit-rot flipping bytes) is
7
+ DETECTED, marked as an erasure, and REPAIRED from the surviving shards -- as long
8
+ as at least k of the n shards per chunk are still intact.
9
+
10
+ The whole thing serializes to a single .pt (torch.save):
11
+ { meta, manifest:[chunk_hash...], chunks:{ hash: {shards, shard_hashes, L, orig} } }
12
+
13
+ Honesty: RS adds redundancy (archive is ~(k+m)/k x the deduped image). It repairs
14
+ up to m damaged shards per chunk; beyond that a chunk is flagged as lost, never
15
+ silently wrong. No entropy is beaten.
16
+ """
17
+ from __future__ import annotations
18
+ import hashlib
19
+ import time
20
+ import torch
21
+ from . import rs
22
+
23
+ CHUNK = 4096
24
+
25
+
26
+ def _h(b: bytes) -> str:
27
+ return hashlib.sha256(b).hexdigest()
28
+
29
+
30
+ def build(data: bytes, label="disc", k=4, m=2, chunk=CHUNK, bad_sectors=None) -> dict:
31
+ chunks = {}
32
+ manifest = []
33
+ for off in range(0, len(data), chunk):
34
+ ch = data[off:off + chunk]
35
+ h = _h(ch)
36
+ manifest.append(h)
37
+ if h in chunks:
38
+ continue
39
+ shards, L, orig = rs.encode(ch, k, m)
40
+ shards = [bytes(s) for s in shards]
41
+ chunks[h] = {"shards": shards, "shard_hashes": [_h(s) for s in shards],
42
+ "L": L, "orig": orig, "k": k, "m": m}
43
+ return {
44
+ "meta": {"label": label, "size": len(data), "chunk": chunk, "k": k, "m": m,
45
+ "bad_sectors": list(bad_sectors or []), "created": time.time(),
46
+ "format": "neural-cd-preserve/1"},
47
+ "manifest": manifest, "chunks": chunks,
48
+ }
49
+
50
+
51
+ def save(arc: dict, path: str):
52
+ torch.save(arc, path)
53
+
54
+
55
+ def load(path: str) -> dict:
56
+ return torch.load(path, map_location="cpu", weights_only=False)
57
+
58
+
59
+ def _good_shards(rec: dict) -> dict:
60
+ """{index: bytes} for shards whose hash still matches (uncorrupted)."""
61
+ out = {}
62
+ for i, s in enumerate(rec["shards"]):
63
+ if _h(s) == rec["shard_hashes"][i]:
64
+ out[i] = s
65
+ return out
66
+
67
+
68
+ def verify(arc: dict) -> dict:
69
+ """Report health without modifying. -> {chunks, corrupted_shards, repairable,
70
+ lost} where lost chunks have < k intact shards (unrecoverable)."""
71
+ corrupted = repairable = lost = 0
72
+ for h, rec in arc["chunks"].items():
73
+ good = _good_shards(rec)
74
+ nbad = len(rec["shards"]) - len(good)
75
+ corrupted += nbad
76
+ if nbad and len(good) >= rec["k"]:
77
+ repairable += 1
78
+ if len(good) < rec["k"]:
79
+ lost += 1
80
+ return {"chunks": len(arc["chunks"]), "corrupted_shards": corrupted,
81
+ "repairable_chunks": repairable, "lost_chunks": lost,
82
+ "healthy": corrupted == 0 and lost == 0}
83
+
84
+
85
+ def heal(arc: dict) -> int:
86
+ """Detect corrupted shards and regenerate them from survivors. Returns the
87
+ number of shards repaired. Chunks with < k intact shards cannot be healed."""
88
+ repaired = 0
89
+ for h, rec in arc["chunks"].items():
90
+ good = _good_shards(rec)
91
+ if len(good) == len(rec["shards"]):
92
+ continue
93
+ if len(good) < rec["k"]:
94
+ continue # unrecoverable, leave as-is
95
+ ch = rs.decode(good, rec["k"], rec["m"], rec["L"], rec["orig"])
96
+ if _h(ch) != h:
97
+ continue # decoded wrong -> don't trust
98
+ fresh, _, _ = rs.encode(ch, rec["k"], rec["m"])
99
+ for i in range(len(rec["shards"])):
100
+ if i not in good:
101
+ rec["shards"][i] = bytes(fresh[i])
102
+ rec["shard_hashes"][i] = _h(rec["shards"][i])
103
+ repaired += 1
104
+ return repaired
105
+
106
+
107
+ def restore(arc: dict) -> bytes:
108
+ """Reconstruct the disc image, RS-correcting any detected corruption."""
109
+ out = bytearray()
110
+ for h in arc["manifest"]:
111
+ rec = arc["chunks"][h]
112
+ good = _good_shards(rec)
113
+ if len(good) < rec["k"]:
114
+ raise IOError(f"chunk {h[:8]}: only {len(good)} intact shards, "
115
+ f"need {rec['k']} -- unrecoverable")
116
+ ch = rs.decode(good, rec["k"], rec["m"], rec["L"], rec["orig"])
117
+ if _h(ch) != h:
118
+ raise IOError(f"chunk {h[:8]}: hash mismatch after decode")
119
+ out += ch
120
+ return bytes(out[:arc["meta"]["size"]])
storage/chunkstore.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Content-addressed, deduplicating chunk store.
3
+
4
+ * content-defined chunking (Gear-hash CDC) splits a byte stream into
5
+ variable-length chunks at data-dependent boundaries -- so duplicate regions
6
+ chunk identically even if shifted.
7
+ * each chunk's SHA-256 is its address and its bit-verification.
8
+ * identical chunks are stored once (dedup). A manifest (list of hashes)
9
+ reconstructs the original stream exactly.
10
+
11
+ Honest note: dedup + (optional) compression only removes REDUNDANT/compressible
12
+ data. Incompressible or unique data is stored in full -- you cannot beat entropy.
13
+ The chunk hashes are real crypto (SHA-256), not a neural emulation.
14
+ """
15
+ from __future__ import annotations
16
+ import hashlib
17
+ import random
18
+
19
+ # Gear table: 256 fixed 64-bit values (deterministic).
20
+ _rng = random.Random(0xC0FFEE)
21
+ GEAR = [_rng.getrandbits(64) for _ in range(256)]
22
+ MASK64 = (1 << 64) - 1
23
+
24
+
25
+ def chunk_stream(data: bytes, min_sz=2048, avg_bits=13, max_sz=65536):
26
+ """Yield (offset, length) chunk boundaries via Gear-hash CDC.
27
+ avg_bits sets average chunk size ~ 2**avg_bits bytes."""
28
+ mask = (1 << avg_bits) - 1
29
+ n = len(data)
30
+ start = 0
31
+ while start < n:
32
+ h = 0
33
+ i = start
34
+ end = min(start + max_sz, n)
35
+ while i < end:
36
+ h = ((h << 1) + GEAR[data[i]]) & MASK64
37
+ i += 1
38
+ if i - start >= min_sz and (h & mask) == 0:
39
+ break
40
+ yield start, i - start
41
+ start = i
42
+
43
+
44
+ class ChunkStore:
45
+ def __init__(self):
46
+ self.store: dict[str, bytes] = {} # sha256 -> chunk bytes
47
+ self.logical_bytes = 0
48
+ self.total_chunks = 0
49
+
50
+ def put_stream(self, data: bytes) -> list[str]:
51
+ manifest = []
52
+ self.logical_bytes += len(data)
53
+ for off, ln in chunk_stream(data):
54
+ ch = data[off:off + ln]
55
+ h = hashlib.sha256(ch).hexdigest()
56
+ if h not in self.store:
57
+ self.store[h] = ch
58
+ manifest.append(h)
59
+ self.total_chunks += 1
60
+ return manifest
61
+
62
+ def reconstruct(self, manifest: list[str]) -> bytes:
63
+ return b"".join(self.store[h] for h in manifest)
64
+
65
+ def integrity_ok(self) -> bool:
66
+ """Every stored chunk must still hash to its address (bit-verified)."""
67
+ return all(hashlib.sha256(v).hexdigest() == k for k, v in self.store.items())
68
+
69
+ def stored_bytes(self) -> int:
70
+ return sum(len(v) for v in self.store.values())
71
+
72
+ def stats(self) -> dict:
73
+ return {
74
+ "logical_bytes": self.logical_bytes,
75
+ "stored_bytes": self.stored_bytes(),
76
+ "total_chunks": self.total_chunks,
77
+ "unique_chunks": len(self.store),
78
+ "dedup_ratio": self.logical_bytes / max(1, self.stored_bytes()),
79
+ }
storage/common.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Shared helpers (same as the neural-DDR project): bit<->int, MLP, verify, train."""
2
+ from __future__ import annotations
3
+ import torch
4
+ import torch.nn as nn
5
+
6
+ DEV = "cuda" if torch.cuda.is_available() else "cpu"
7
+
8
+
9
+ def bits_of(v: int, n: int) -> list[int]:
10
+ return [(v >> k) & 1 for k in range(n)]
11
+
12
+
13
+ def int_of(bits) -> int:
14
+ return sum((1 << k) for k, b in enumerate(bits) if b > 0)
15
+
16
+
17
+ def pm(bits) -> torch.Tensor:
18
+ return torch.tensor([1.0 if b else -1.0 for b in bits], dtype=torch.float32)
19
+
20
+
21
+ def mlp(inp: int, out: int, h: int = 256, layers: int = 2) -> nn.Sequential:
22
+ mods = [nn.Linear(inp, h), nn.GELU()]
23
+ for _ in range(layers - 1):
24
+ mods += [nn.Linear(h, h), nn.GELU()]
25
+ mods += [nn.Linear(h, out)]
26
+ return nn.Sequential(*mods)
27
+
28
+
29
+ @torch.no_grad()
30
+ def verify(net, X, Ybits) -> tuple[int, int]:
31
+ net = net.to("cpu")
32
+ pred = (net(X) > 0).int()
33
+ ok = (pred == Ybits.int()).all(dim=1).sum().item()
34
+ return ok, X.shape[0]
35
+
36
+
37
+ def train(net, X, Ybits, steps=8000, lr=2e-3, tag="", report=2000):
38
+ net = net.to(DEV)
39
+ Xd, Yd = X.to(DEV), Ybits.to(DEV)
40
+ opt = torch.optim.Adam(net.parameters(), lr=lr)
41
+ sch = torch.optim.lr_scheduler.CosineAnnealingLR(opt, T_max=steps)
42
+ lossfn = nn.BCEWithLogitsLoss()
43
+ for e in range(steps):
44
+ opt.zero_grad()
45
+ loss = lossfn(net(Xd), Yd)
46
+ loss.backward(); opt.step(); sch.step()
47
+ if e % report == 0 or e == steps - 1:
48
+ ok, tot = verify(net, X, Ybits); net.to(DEV)
49
+ print(f" [{tag}] epoch {e:5d} loss {loss.item():.2e} verified {ok}/{tot}")
50
+ if ok == tot:
51
+ print(f" [{tag}] -> N/N"); break
52
+ return net.to("cpu")
53
+
54
+
55
+ def run8(net, v: int) -> int:
56
+ return int_of((net(pm(bits_of(v, 8)).unsqueeze(0))[0] > 0).int().tolist())
storage/diskimage.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Whole-drive imaging into a self-healing .pt.
3
+
4
+ Scans a block device (Windows: r"\\\\.\\C:" or r"\\\\.\\PhysicalDrive0"; may need
5
+ Administrator) or an image file, and turns it into a self-healing .pt archive:
6
+ content-defined chunks, Reed-Solomon shards, per-shard SHA-256 (Step 1-2 +
7
+ archive.py). It self-heals bit-rot in the archive and reconstructs the image
8
+ bit-exact.
9
+
10
+ Streaming by segment keeps memory bounded, so it scales past RAM:
11
+ * small input (<= one segment) -> a single self-contained <out>.pt
12
+ * large drive -> <out>.pt manifest + <out>.pt.part0, part1, ...
13
+
14
+ HONEST LIMITS (read these):
15
+ * RS adds redundancy: the .pt is ~ (k+m)/k x the imaged data (e.g. 1.5x). This
16
+ does NOT shrink a drive -- you cannot beat entropy.
17
+ * Imaging an "entire HDD" means writing >= 1.5x its used size to disk and takes
18
+ real time; use --part-mb and expect a big output.
19
+ * Raw whole-disk reads need Administrator and the disk should be idle/unmounted
20
+ (image a partition, or a disk you are not writing to).
21
+ * RS heals the ARCHIVE against future bit-rot. Sectors unreadable at scan time
22
+ are recorded as bad, not invented.
23
+ """
24
+ from __future__ import annotations
25
+ import os
26
+ import torch
27
+ from . import archive, scan
28
+
29
+ DEFAULT_PART = 64 * 1024 * 1024 # 64 MB segments
30
+
31
+
32
+ def _read_segment(f, part_bytes: int, sector: int):
33
+ """Read up to part_bytes in sector-sized reads. -> (data, bad_sectors, eof)."""
34
+ data = bytearray()
35
+ bad = []
36
+ idx = 0
37
+ while len(data) < part_bytes:
38
+ try:
39
+ blk = f.read(sector)
40
+ except OSError:
41
+ bad.append(idx)
42
+ data += bytes(sector)
43
+ idx += 1
44
+ try:
45
+ f.seek(sector, os.SEEK_CUR)
46
+ except OSError:
47
+ return bytes(data), bad, True
48
+ continue
49
+ if not blk:
50
+ return bytes(data), bad, True
51
+ data += blk
52
+ idx += 1
53
+ if len(blk) < sector:
54
+ return bytes(data), bad, True
55
+ return bytes(data), bad, False
56
+
57
+
58
+ def create(device: str, out_pt: str, k: int = 4, m: int = 2,
59
+ chunk: int = archive.CHUNK, part_mb: int = 64,
60
+ sector: int = scan.SECTOR, label: str | None = None) -> dict:
61
+ label = label or os.path.basename(device.rstrip("\\/")) or "disk"
62
+ part_bytes = part_mb * 1024 * 1024
63
+ with open(device, "rb", buffering=0) as f:
64
+ seg, bad, eof = _read_segment(f, part_bytes, sector)
65
+ if eof: # whole device fit in one segment
66
+ arc = archive.build(seg, label=label, k=k, m=m, bad_sectors=bad)
67
+ arc["meta"]["device"] = device
68
+ torch.save(arc, out_pt)
69
+ return {"mode": "single", "bytes": len(seg), "bad_sectors": len(bad),
70
+ "parts": 1, "out": out_pt}
71
+ parts, n, total_bad = [], 0, 0
72
+ while True:
73
+ p = f"{out_pt}.part{n}"
74
+ arc = archive.build(seg, label=f"{label}.part{n}", k=k, m=m, bad_sectors=bad)
75
+ torch.save(arc, p)
76
+ parts.append({"path": os.path.basename(p), "size": len(seg)})
77
+ total_bad += len(bad)
78
+ n += 1
79
+ if eof:
80
+ break
81
+ seg, bad, eof = _read_segment(f, part_bytes, sector)
82
+ if not seg and eof:
83
+ break
84
+ manifest = {"format": "neural-storage/diskimage-1", "device": device, "label": label,
85
+ "k": k, "m": m, "chunk": chunk, "parts": parts,
86
+ "total": sum(p["size"] for p in parts), "bad_sectors": total_bad}
87
+ torch.save(manifest, out_pt)
88
+ return {"mode": "multi", "bytes": manifest["total"], "bad_sectors": total_bad,
89
+ "parts": len(parts), "out": out_pt}
90
+
91
+
92
+ def _is_manifest(obj) -> bool:
93
+ return isinstance(obj, dict) and obj.get("format", "").startswith("neural-storage/diskimage")
94
+
95
+
96
+ def verify(out_pt: str) -> dict:
97
+ obj = archive.load(out_pt)
98
+ if not _is_manifest(obj):
99
+ return archive.verify(obj)
100
+ base = os.path.dirname(out_pt)
101
+ agg = {"chunks": 0, "corrupted_shards": 0, "repairable_chunks": 0, "lost_chunks": 0}
102
+ for p in obj["parts"]:
103
+ h = archive.verify(archive.load(os.path.join(base, p["path"])))
104
+ for kk in agg:
105
+ agg[kk] += h[kk]
106
+ agg["healthy"] = agg["corrupted_shards"] == 0 and agg["lost_chunks"] == 0
107
+ return agg
108
+
109
+
110
+ def heal(out_pt: str) -> int:
111
+ obj = archive.load(out_pt)
112
+ if not _is_manifest(obj):
113
+ n = archive.heal(obj)
114
+ torch.save(obj, out_pt)
115
+ return n
116
+ base = os.path.dirname(out_pt)
117
+ total = 0
118
+ for p in obj["parts"]:
119
+ pth = os.path.join(base, p["path"])
120
+ arc = archive.load(pth)
121
+ n = archive.heal(arc)
122
+ if n:
123
+ torch.save(arc, pth)
124
+ total += n
125
+ return total
126
+
127
+
128
+ def restore(out_pt: str, out_file: str) -> int:
129
+ obj = archive.load(out_pt)
130
+ with open(out_file, "wb") as w:
131
+ if not _is_manifest(obj):
132
+ data = archive.restore(obj)
133
+ w.write(data)
134
+ return len(data)
135
+ base = os.path.dirname(out_pt)
136
+ total = 0
137
+ for p in obj["parts"]:
138
+ data = archive.restore(archive.load(os.path.join(base, p["path"])))
139
+ w.write(data)
140
+ total += len(data)
141
+ return total
storage/gf256.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Step 1 keystone: verified GF(2^8) multiply -- the arithmetic core of Reed-Solomon
3
+ erasure coding (Step 2).
4
+
5
+ A direct 16-bit -> 8-bit neural multiply is hard to drive to N/N. So we decompose
6
+ it the way real RS implementations do -- via log/exp tables:
7
+
8
+ a * b = EXP[ (LOG[a] + LOG[b]) mod 255 ] (and 0 if a==0 or b==0)
9
+
10
+ LOG and EXP are 256-entry lookups -> trivially N/N verifiable neural units. We
11
+ train both, compose them into a full multiply, and verify the COMPOSED multiply
12
+ against the golden field over ALL 65,536 (a,b) pairs.
13
+
14
+ Field: GF(2^8), reduction polynomial 0x11D, generator 2 (standard for RS).
15
+ """
16
+ from __future__ import annotations
17
+ import torch
18
+ from .common import mlp, train, verify, pm, bits_of, int_of, run8
19
+
20
+ POLY = 0x11D
21
+
22
+
23
+ def build_tables():
24
+ exp = [0] * 512
25
+ log = [0] * 256
26
+ x = 1
27
+ for i in range(255):
28
+ exp[i] = x
29
+ log[x] = i
30
+ x <<= 1
31
+ if x & 0x100:
32
+ x ^= POLY
33
+ for i in range(255, 512):
34
+ exp[i] = exp[i - 255]
35
+ return exp, log
36
+
37
+
38
+ EXP, LOG = build_tables()
39
+
40
+
41
+ def gf_mul(a: int, b: int) -> int:
42
+ if a == 0 or b == 0:
43
+ return 0
44
+ return EXP[LOG[a] + LOG[b]]
45
+
46
+
47
+ # ---- neural LOG (inputs 1..255) and EXP (indices 0..254) ----
48
+ def log_domain():
49
+ xs = [pm(bits_of(a, 8)) for a in range(1, 256)]
50
+ ys = [[float(b) for b in bits_of(LOG[a], 8)] for a in range(1, 256)]
51
+ return torch.stack(xs), torch.tensor(ys)
52
+
53
+
54
+ def exp_domain():
55
+ xs = [pm(bits_of(i, 8)) for i in range(255)]
56
+ ys = [[float(b) for b in bits_of(EXP[i], 8)] for i in range(255)]
57
+ return torch.stack(xs), torch.tensor(ys)
58
+
59
+
60
+ def gf_mul_neural(a: int, b: int, net_log, net_exp) -> int:
61
+ if a == 0 or b == 0:
62
+ return 0
63
+ s = (run8(net_log, a) + run8(net_log, b)) % 255
64
+ return run8(net_exp, s)
65
+
66
+
67
+ def train_units():
68
+ print(" training LOG (8->8):")
69
+ net_log = train(mlp(8, 8, 256, 2), *log_domain(), steps=8000, tag="log")
70
+ print(" training EXP (8->8):")
71
+ net_exp = train(mlp(8, 8, 256, 2), *exp_domain(), steps=8000, tag="exp")
72
+ return net_log, net_exp
73
+
74
+
75
+ def verify_mul(net_log, net_exp) -> tuple[int, int]:
76
+ ok = 0
77
+ for a in range(256):
78
+ for b in range(256):
79
+ ok += (gf_mul_neural(a, b, net_log, net_exp) == gf_mul(a, b))
80
+ return ok, 256 * 256
storage/rs.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Step 2: Reed-Solomon erasure coding over the verified GF(256) field.
3
+
4
+ Split data into k systematic shards + m parity shards (n = k+m). ANY k of the n
5
+ shards reconstruct the original -- so up to m shards can be lost or corrupted and
6
+ the data still survives. This is the honest sense of "small pieces that together
7
+ rebuild the whole": redundancy, not shrinkage (n shards total n/k x the data).
8
+
9
+ All coefficients come from a Cauchy matrix over GF(256) (every square submatrix
10
+ invertible => any-k-of-n recovery). Every multiply is the GF(256) multiply that
11
+ the neural LOG/EXP units were verified bit-exact against (65536/65536), so the
12
+ fast table path here is the proven-equivalent of the neural coding core.
13
+ """
14
+ from __future__ import annotations
15
+ from .gf256 import EXP, LOG, gf_mul
16
+
17
+ MUL = [[gf_mul(a, b) for b in range(256)] for a in range(256)] # full product table
18
+
19
+
20
+ def gf_inv(a: int) -> int:
21
+ return EXP[255 - LOG[a]] if a else 0
22
+
23
+
24
+ def cauchy(k: int, m: int):
25
+ return [[gf_inv((k + i) ^ j) for j in range(k)] for i in range(m)]
26
+
27
+
28
+ def _gen_row(r: int, k: int, C):
29
+ if r < k:
30
+ row = [0] * k
31
+ row[r] = 1
32
+ return row
33
+ return C[r - k]
34
+
35
+
36
+ def encode(data: bytes, k: int, m: int):
37
+ """-> (shards[n], shard_len, orig_len). shards[:k] are systematic data."""
38
+ orig = len(data)
39
+ L = (orig + k - 1) // k
40
+ d = data + bytes(L * k - orig)
41
+ shards = [bytearray(d[j * L:(j + 1) * L]) for j in range(k)]
42
+ C = cauchy(k, m)
43
+ for i in range(m):
44
+ P = bytearray(L)
45
+ Ci = C[i]
46
+ for j in range(k):
47
+ MC = MUL[Ci[j]]
48
+ Dj = shards[j]
49
+ for b in range(L):
50
+ P[b] ^= MC[Dj[b]]
51
+ shards.append(P)
52
+ return shards, L, orig
53
+
54
+
55
+ def _invert(M, k):
56
+ A = [list(M[i]) + [1 if j == i else 0 for j in range(k)] for i in range(k)]
57
+ for col in range(k):
58
+ piv = col
59
+ while A[piv][col] == 0:
60
+ piv += 1
61
+ A[col], A[piv] = A[piv], A[col]
62
+ inv = gf_inv(A[col][col])
63
+ A[col] = [MUL[inv][x] for x in A[col]]
64
+ for r in range(k):
65
+ if r != col and A[r][col]:
66
+ f = A[r][col]
67
+ A[r] = [A[r][x] ^ MUL[f][A[col][x]] for x in range(2 * k)]
68
+ return [A[i][k:] for i in range(k)]
69
+
70
+
71
+ def decode(present: dict, k: int, m: int, L: int, orig: int) -> bytes:
72
+ """present: {shard_index: bytes}; needs >= k entries."""
73
+ idxs = sorted(present.keys())[:k]
74
+ C = cauchy(k, m)
75
+ Minv = _invert([_gen_row(r, k, C) for r in idxs], k)
76
+ data_shards = [bytearray(L) for _ in range(k)]
77
+ for j in range(k):
78
+ row = Minv[j]
79
+ Dj = data_shards[j]
80
+ for t, r in enumerate(idxs):
81
+ c = row[t]
82
+ if not c:
83
+ continue
84
+ MC = MUL[c]
85
+ src = present[r]
86
+ for b in range(L):
87
+ Dj[b] ^= MC[src[b]]
88
+ return b"".join(bytes(s) for s in data_shards)[:orig]
89
+
90
+
91
+ def neural_parity_equiv(net_log, net_exp, k=4, m=2, L=16) -> bool:
92
+ """Compute one parity shard with the NEURAL gf_mul and confirm it matches the
93
+ golden coding -- i.e. the verified units drive the erasure code bit-exactly."""
94
+ import os
95
+ from .gf256 import gf_mul_neural
96
+ data = os.urandom(L * k)
97
+ shards, _, _ = encode(data, k, m)
98
+ C = cauchy(k, m)
99
+ Dsh = [data[j * L:(j + 1) * L] for j in range(k)]
100
+ P = bytearray(L)
101
+ for j in range(k):
102
+ for b in range(L):
103
+ P[b] ^= gf_mul_neural(C[0][j], Dsh[j][b], net_log, net_exp)
104
+ return bytes(P) == bytes(shards[k]) # neural parity == golden parity
storage/scan.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Disc scanner.
3
+
4
+ Reads a source sector by sector into bytes. The source can be a raw optical
5
+ drive (Windows: r"\\\\.\\D:", may need admin) or an .iso / image file (for
6
+ testing). Unreadable sectors (scratches / disc rot) are recorded as BAD and
7
+ zero-filled -- ddrescue-style -- rather than aborting the scan.
8
+
9
+ Important: bad sectors are data you never read. RS self-healing (archive.py)
10
+ protects the STORED copy against future corruption; it cannot invent sectors the
11
+ drive could not read. To recover those, re-scan the disc and merge good sectors
12
+ across attempts (`merge_scans`).
13
+ """
14
+ from __future__ import annotations
15
+
16
+ SECTOR = 2048 # CD-ROM Mode-1 user data sector size
17
+
18
+
19
+ def scan_image(path: str, sector: int = SECTOR):
20
+ """-> (data: bytes, bad_sectors: list[int]). Robust to unreadable sectors."""
21
+ data = bytearray()
22
+ bad = []
23
+ with open(path, "rb", buffering=0) as f:
24
+ idx = 0
25
+ while True:
26
+ try:
27
+ blk = f.read(sector)
28
+ except OSError:
29
+ bad.append(idx)
30
+ data += bytes(sector)
31
+ try:
32
+ f.seek((idx + 1) * sector)
33
+ except OSError:
34
+ break
35
+ idx += 1
36
+ continue
37
+ if not blk:
38
+ break
39
+ data += blk # keep true length (last
40
+ idx += 1 # sector may be partial)
41
+ return bytes(data), bad
42
+
43
+
44
+ def merge_scans(scans, sector: int = SECTOR):
45
+ """Combine multiple (data, bad) scans of the same failing disc: a sector is
46
+ good if ANY scan read it. Returns (merged_data, still_bad_sectors)."""
47
+ n = max(len(d) // sector for d, _ in scans)
48
+ merged = bytearray(n * sector)
49
+ known = [False] * n
50
+ for data, bad in scans:
51
+ badset = set(bad)
52
+ for s in range(len(data) // sector):
53
+ if s not in badset and not known[s]:
54
+ merged[s * sector:(s + 1) * sector] = data[s * sector:(s + 1) * sector]
55
+ known[s] = True
56
+ still_bad = [s for s in range(n) if not known[s]]
57
+ return bytes(merged), still_bad
storage/vault.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Step 3 backing store: the Vault.
3
+
4
+ Combines everything so far into an on-disk repository:
5
+ * files are content-defined-chunked (Step 1 CDC)
6
+ * unique chunks are stored once, addressed by SHA-256 (dedup, bit-verified)
7
+ * each unique chunk is Reed-Solomon split into n = k+m shard files (Step 2),
8
+ so any k shards rebuild it -- up to m shard files can be lost/corrupted
9
+
10
+ On-disk layout:
11
+ <vault>/chunks/<sha256>/shard_0 .. shard_{n-1}, meta.json
12
+ <vault>/files/<relpath>.json (manifest: name, size, [chunk hashes])
13
+
14
+ Reads reconstruct on demand and RS-heal transparently; `heal()` regenerates any
15
+ missing shard files from the survivors. Nothing here beats entropy -- dedup
16
+ removes redundancy, RS adds redundancy for resilience.
17
+ """
18
+ from __future__ import annotations
19
+ import os
20
+ import json
21
+ import hashlib
22
+ from .chunkstore import chunk_stream
23
+ from . import rs
24
+
25
+
26
+ class Vault:
27
+ def __init__(self, path: str, k: int = 4, m: int = 2):
28
+ self.path = path
29
+ self.k, self.m = k, m
30
+ self.cdir = os.path.join(path, "chunks")
31
+ self.fdir = os.path.join(path, "files")
32
+ os.makedirs(self.cdir, exist_ok=True)
33
+ os.makedirs(self.fdir, exist_ok=True)
34
+
35
+ # ---- chunks ----
36
+ def _cd(self, h: str) -> str:
37
+ return os.path.join(self.cdir, h)
38
+
39
+ def _store_chunk(self, ch: bytes) -> str:
40
+ h = hashlib.sha256(ch).hexdigest()
41
+ d = self._cd(h)
42
+ if os.path.exists(os.path.join(d, "meta.json")):
43
+ return h # dedup: already stored
44
+ os.makedirs(d, exist_ok=True)
45
+ shards, L, orig = rs.encode(ch, self.k, self.m)
46
+ for i, s in enumerate(shards):
47
+ with open(os.path.join(d, f"shard_{i}"), "wb") as f:
48
+ f.write(bytes(s))
49
+ json.dump({"L": L, "orig": orig, "k": self.k, "m": self.m},
50
+ open(os.path.join(d, "meta.json"), "w"))
51
+ return h
52
+
53
+ def _load_chunk(self, h: str) -> bytes:
54
+ d = self._cd(h)
55
+ meta = json.load(open(os.path.join(d, "meta.json")))
56
+ n = meta["k"] + meta["m"]
57
+ present = {}
58
+ for i in range(n):
59
+ p = os.path.join(d, f"shard_{i}")
60
+ if os.path.exists(p):
61
+ b = open(p, "rb").read()
62
+ if len(b) == meta["L"]:
63
+ present[i] = b
64
+ if len(present) < meta["k"]:
65
+ raise IOError(f"chunk {h[:8]}: {len(present)} shards, need {meta['k']}")
66
+ ch = rs.decode(present, meta["k"], meta["m"], meta["L"], meta["orig"])
67
+ if hashlib.sha256(ch).hexdigest() != h:
68
+ raise IOError(f"chunk {h[:8]}: hash mismatch after decode")
69
+ return ch
70
+
71
+ # ---- files ----
72
+ def store_file(self, relpath: str, data: bytes) -> None:
73
+ chunks = [self._store_chunk(data[o:o + l]) for o, l in chunk_stream(data)]
74
+ mfp = os.path.join(self.fdir, relpath + ".json")
75
+ os.makedirs(os.path.dirname(mfp) or ".", exist_ok=True)
76
+ json.dump({"name": relpath, "size": len(data), "chunks": chunks}, open(mfp, "w"))
77
+
78
+ def store_folder(self, src: str) -> None:
79
+ for root, _, names in os.walk(src):
80
+ for nm in names:
81
+ fp = os.path.join(root, nm)
82
+ rel = os.path.relpath(fp, src).replace("\\", "/")
83
+ with open(fp, "rb") as f:
84
+ self.store_file(rel, f.read())
85
+
86
+ def list_files(self):
87
+ out = []
88
+ for root, _, names in os.walk(self.fdir):
89
+ for nm in names:
90
+ if nm.endswith(".json"):
91
+ mf = json.load(open(os.path.join(root, nm)))
92
+ out.append((mf["name"], mf["size"]))
93
+ return sorted(out)
94
+
95
+ def read_file(self, relpath: str) -> bytes:
96
+ mf = json.load(open(os.path.join(self.fdir, relpath + ".json")))
97
+ data = b"".join(self._load_chunk(h) for h in mf["chunks"])
98
+ return data[:mf["size"]]
99
+
100
+ def export(self, dst: str) -> int:
101
+ n = 0
102
+ for rel, _ in self.list_files():
103
+ data = self.read_file(rel)
104
+ op = os.path.join(dst, rel)
105
+ os.makedirs(os.path.dirname(op) or ".", exist_ok=True)
106
+ with open(op, "wb") as f:
107
+ f.write(data)
108
+ n += 1
109
+ return n
110
+
111
+ # ---- resilience ----
112
+ def heal(self) -> int:
113
+ healed = 0
114
+ for h in os.listdir(self.cdir):
115
+ d = self._cd(h)
116
+ mp = os.path.join(d, "meta.json")
117
+ if not os.path.isfile(mp):
118
+ continue
119
+ meta = json.load(open(mp))
120
+ n = meta["k"] + meta["m"]
121
+ missing = [i for i in range(n) if not os.path.exists(os.path.join(d, f"shard_{i}"))]
122
+ if missing:
123
+ ch = self._load_chunk(h) # decode from survivors
124
+ shards, _, _ = rs.encode(ch, meta["k"], meta["m"])
125
+ for i in missing:
126
+ with open(os.path.join(d, f"shard_{i}"), "wb") as f:
127
+ f.write(bytes(shards[i]))
128
+ healed += len(missing)
129
+ return healed
130
+
131
+ def integrity_ok(self) -> bool:
132
+ try:
133
+ for rel, _ in self.list_files():
134
+ self.read_file(rel)
135
+ return True
136
+ except IOError:
137
+ return False
138
+
139
+ def stats(self) -> dict:
140
+ logical = sum(sz for _, sz in self.list_files())
141
+ stored = 0
142
+ chunks = 0
143
+ for h in os.listdir(self.cdir):
144
+ d = self._cd(h)
145
+ if not os.path.isfile(os.path.join(d, "meta.json")):
146
+ continue
147
+ chunks += 1
148
+ for f in os.listdir(d):
149
+ if f.startswith("shard_"):
150
+ stored += os.path.getsize(os.path.join(d, f))
151
+ return {"logical": logical, "stored": stored, "unique_chunks": chunks,
152
+ "overhead": stored / max(1, logical)}
storage/vaultfs.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Read interface over a Vault, plus an optional WinFsp mount.
3
+
4
+ `VaultFS` is a dependency-free read model: list files, stat, and read byte ranges
5
+ that are reconstructed (and RS-healed) on demand from the Vault. This is what the
6
+ CLI `export` uses and what the mount serves.
7
+
8
+ `mount()` exposes the Vault as a real drive letter via WinFsp (Windows FUSE). It
9
+ is guarded: if `winfspy` / WinFsp is not installed, it raises with instructions
10
+ instead of failing obscurely. The dependency-free path (VaultFS + CLI export)
11
+ works everywhere; the live drive lights up once WinFsp is present.
12
+ """
13
+ from __future__ import annotations
14
+ from collections import OrderedDict
15
+ from .vault import Vault
16
+
17
+
18
+ class VaultFS:
19
+ def __init__(self, vault: Vault, cache_files: int = 8):
20
+ self.vault = vault
21
+ self._cache: OrderedDict[str, bytes] = OrderedDict()
22
+ self._cache_n = cache_files
23
+ self._index = {rel: sz for rel, sz in vault.list_files()}
24
+
25
+ def listdir(self):
26
+ return sorted(self._index.items()) # [(relpath, size)]
27
+
28
+ def size(self, relpath: str) -> int:
29
+ return self._index[relpath]
30
+
31
+ def _data(self, relpath: str) -> bytes:
32
+ if relpath in self._cache:
33
+ self._cache.move_to_end(relpath)
34
+ return self._cache[relpath]
35
+ data = self.vault.read_file(relpath) # reconstruct + RS-heal
36
+ self._cache[relpath] = data
37
+ if len(self._cache) > self._cache_n:
38
+ self._cache.popitem(last=False)
39
+ return data
40
+
41
+ def read(self, relpath: str, offset: int = 0, length: int | None = None) -> bytes:
42
+ data = self._data(relpath)
43
+ if length is None:
44
+ return data[offset:]
45
+ return data[offset:offset + length]
46
+
47
+
48
+ def winfsp_available() -> bool:
49
+ try:
50
+ import winfspy # noqa: F401
51
+ return True
52
+ except Exception:
53
+ return False
54
+
55
+
56
+ def mount(vault: Vault, mountpoint: str, label: str = "NeuralVault"):
57
+ """Mount the vault as a read-only drive via WinFsp. Requires WinFsp + winfspy.
58
+ Experimental: the dependency-free `export` path is the tested one."""
59
+ if not winfsp_available():
60
+ raise RuntimeError(
61
+ "WinFsp / winfspy not found. Install WinFsp (https://winfsp.dev) and "
62
+ "`pip install winfspy`, or use the dependency-free CLI: "
63
+ "`python cli.py export <vault> <folder>`."
64
+ )
65
+ # Imported lazily so the module loads without winfspy present.
66
+ from winfspy import (FileSystem, BaseFileSystemOperations, NTStatusObjectNameNotFound,
67
+ FILE_ATTRIBUTE)
68
+ import time
69
+
70
+ fs_view = VaultFS(vault)
71
+ now = int(time.time() * 1e7) + 116444736000000000 # FILETIME epoch
72
+
73
+ class Ops(BaseFileSystemOperations):
74
+ def _info(self, is_dir, size=0):
75
+ return {
76
+ "file_attributes": FILE_ATTRIBUTE.FILE_ATTRIBUTE_DIRECTORY if is_dir
77
+ else FILE_ATTRIBUTE.FILE_ATTRIBUTE_NORMAL,
78
+ "allocation_size": size, "file_size": size,
79
+ "creation_time": now, "last_access_time": now,
80
+ "last_write_time": now, "change_time": now, "index_number": 0,
81
+ }
82
+
83
+ def _norm(self, p):
84
+ return p.replace("\\", "/").lstrip("/")
85
+
86
+ def get_volume_info(self):
87
+ return {"total_size": 0, "free_size": 0, "volume_label": label}
88
+
89
+ def get_security_by_name(self, file_name):
90
+ rel = self._norm(file_name)
91
+ is_dir = rel == "" or any(f.startswith(rel + "/") for f in fs_view._index)
92
+ if not is_dir and rel not in fs_view._index:
93
+ raise NTStatusObjectNameNotFound()
94
+ return (self._info(is_dir, 0 if is_dir else fs_view.size(rel))["file_attributes"], None, 0)
95
+
96
+ def open(self, file_name, create_options, granted_access):
97
+ rel = self._norm(file_name)
98
+ is_dir = rel == "" or any(f.startswith(rel + "/") for f in fs_view._index)
99
+ if not is_dir and rel not in fs_view._index:
100
+ raise NTStatusObjectNameNotFound()
101
+ return {"rel": rel, "is_dir": is_dir}
102
+
103
+ def get_file_info(self, fh):
104
+ return self._info(fh["is_dir"], 0 if fh["is_dir"] else fs_view.size(fh["rel"]))
105
+
106
+ def read(self, fh, offset, length):
107
+ return fs_view.read(fh["rel"], offset, length)
108
+
109
+ def read_directory(self, fh, marker):
110
+ prefix = "" if fh["rel"] == "" else fh["rel"] + "/"
111
+ names = set()
112
+ for f in fs_view._index:
113
+ if f.startswith(prefix):
114
+ rest = f[len(prefix):]
115
+ names.add(rest.split("/")[0])
116
+ out = []
117
+ for nm in sorted(names):
118
+ full = prefix + nm
119
+ is_dir = full not in fs_view._index
120
+ out.append({"file_name": nm,
121
+ "file_info": self._info(is_dir, 0 if is_dir else fs_view.size(full))})
122
+ return out
123
+
124
+ def close(self, fh):
125
+ pass
126
+
127
+ fs = FileSystem(mountpoint, Ops(), volume_label=label)
128
+ fs.start()
129
+ return fs