Zion Boggan
repos/Oversight/oversight-rust/tests/conformance_cross_lang.sh
zionboggan.com ↗
173 lines · bash
History for this file →
1
 
2
set -e
3
export PATH="$HOME/.cargo/bin:$PATH"
4
 
5
WORKDIR=/tmp/oversight-conformance
6
REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)}"
7
RUST_CARGO="$REPO_ROOT/oversight-rust/Cargo.toml"
8
PYTHON_ROOT="$REPO_ROOT"
9
 
10
rm -rf $WORKDIR
11
mkdir -p $WORKDIR
12
cd $WORKDIR
13
 
14
echo "=== Setup: generate identities in Rust ==="
15
cargo run --manifest-path $RUST_CARGO --release -q -- keygen --out alice.json 2>&1 | tail -4
16
cargo run --manifest-path $RUST_CARGO --release -q -- keygen --out issuer.json 2>&1 | tail -4
17
 
18
ALICE_X_PUB=$(python3 -c "import json; print(json.load(open('alice.json'))['x25519_pub'])")
19
ALICE_X_PRIV=$(python3 -c "import json; print(json.load(open('alice.json'))['x25519_priv'])")
20
ISSUER_ED_PRIV=$(python3 -c "import json; print(json.load(open('issuer.json'))['ed25519_priv'])")
21
ISSUER_ED_PUB=$(python3 -c "import json; print(json.load(open('issuer.json'))['ed25519_pub'])")
22
 
23
echo "This is a cross-language conformance test." > plaintext.txt
24
EXPECTED_HASH=$(python3 -c "
25
import hashlib
26
data = open('plaintext.txt', 'rb').read()
27
print(hashlib.sha256(data).hexdigest())
28
")
29
echo "Expected hash: $EXPECTED_HASH"
30
 
31
echo ""
32
echo "=== 1. Seal in RUST, open in PYTHON ==="
33
cargo run --manifest-path $RUST_CARGO --release -q -- seal \
34
  --input plaintext.txt --output rust-sealed.bin \
35
  --issuer issuer.json --recipient-pub "$ALICE_X_PUB" \
36
  --recipient-id "alice@test" --registry "https://reg.test" 2>&1 | tail -3
37
 
38
python3 <<PYEOF
39
import sys
40
sys.path.insert(0, '$PYTHON_ROOT')
41
from oversight_core.container import open_sealed
42
blob = open('rust-sealed.bin', 'rb').read()
43
priv = bytes.fromhex('$ALICE_X_PRIV')
44
plaintext, manifest = open_sealed(blob, priv)
45
expected = open('plaintext.txt', 'rb').read()
46
assert plaintext == expected, f"PLAINTEXT MISMATCH: got {plaintext!r}, expected {expected!r}"
47
assert manifest.content_hash == '$EXPECTED_HASH', f"HASH MISMATCH: {manifest.content_hash}"
48
print(f"  ✓ Python read Rust-sealed file ({len(plaintext)} bytes)")
49
print(f"  ✓ content_hash matches: {manifest.content_hash[:16]}...")
50
print(f"  ✓ file_id from Rust manifest: {manifest.file_id}")
51
print(f"  ✓ signature verified: {manifest.verify()}")
52
PYEOF
53
 
54
echo ""
55
echo "=== 2. Seal in PYTHON, open in RUST ==="
56
python3 <<PYEOF
57
import sys
58
sys.path.insert(0, '$PYTHON_ROOT')
59
from oversight_core import ClassicIdentity, content_hash
60
from oversight_core.manifest import Manifest, Recipient
61
from oversight_core.container import seal
62
 
63
alice_pub = bytes.fromhex('$ALICE_X_PUB')
64
issuer_priv = bytes.fromhex('$ISSUER_ED_PRIV')
65
issuer_pub = bytes.fromhex('$ISSUER_ED_PUB')
66
 
67
plaintext = open('plaintext.txt', 'rb').read()
68
m = Manifest.new(
69
    original_filename='plaintext.txt',
70
    content_hash=content_hash(plaintext),
71
    size_bytes=len(plaintext),
72
    issuer_id='cross-test',
73
    issuer_ed25519_pub_hex=issuer_pub.hex(),
74
    recipient=Recipient(recipient_id='alice@test', x25519_pub=alice_pub.hex()),
75
    registry_url='https://reg.test',
76
    content_type='text/plain',
77
)
78
blob = seal(plaintext, m, issuer_priv, alice_pub)
79
open('python-sealed.bin', 'wb').write(blob)
80
print(f"  ✓ Python sealed ({len(blob)} bytes)")
81
PYEOF
82
 
83
cargo run --manifest-path $RUST_CARGO --release -q -- open \
84
  --input python-sealed.bin --output rust-recovered.txt --recipient alice.json 2>&1 | tail -3
85
 
86
diff plaintext.txt rust-recovered.txt && echo "  ✓ Rust read Python-sealed file, plaintext matches"
87
 
88
echo ""
89
echo "=== 3. Inspect cross-format: Python can inspect Rust-sealed, Rust can inspect Python-sealed ==="
90
python3 <<PYEOF
91
import sys
92
sys.path.insert(0, '$PYTHON_ROOT')
93
from oversight_core.container import SealedFile
94
blob = open('rust-sealed.bin', 'rb').read()
95
sf = SealedFile.from_bytes(blob)
96
assert sf.manifest.verify(), "Python couldn't verify Rust signature!"
97
print(f"  ✓ Python Manifest.verify() of Rust-sealed: True (suite={sf.manifest.suite})")
98
PYEOF
99
 
100
cargo run --manifest-path $RUST_CARGO --release -q -- inspect \
101
  --input python-sealed.bin 2>&1 | grep -E "(signature valid|suite|OVERSIGHT)" | head -5
102
 
103
echo ""
104
echo "=== 4. Non-ASCII recipient_id round trip (the JCS divergence case) ==="
105
UNICODE_RECIPIENT='Zión@org'
106
 
107
cargo run --manifest-path $RUST_CARGO --release -q -- seal \
108
  --input plaintext.txt --output rust-unicode-sealed.bin \
109
  --issuer issuer.json --recipient-pub "$ALICE_X_PUB" \
110
  --recipient-id "$UNICODE_RECIPIENT" --registry "https://reg.test" 2>&1 | tail -3
111
 
112
python3 <<PYEOF
113
import sys
114
sys.path.insert(0, '$PYTHON_ROOT')
115
from oversight_core.container import open_sealed, SealedFile
116
blob = open('rust-unicode-sealed.bin', 'rb').read()
117
priv = bytes.fromhex('$ALICE_X_PRIV')
118
plaintext, manifest = open_sealed(blob, priv)
119
assert manifest.verify(), (
120
    "Python Manifest.verify() of Rust-sealed file with non-ASCII recipient_id "
121
    "FAILED. This is the JCS divergence: Python and Rust are computing "
122
    "different canonical bytes for the same manifest."
123
)
124
assert manifest.recipient.recipient_id == '$UNICODE_RECIPIENT', (
125
    f"recipient_id mismatch: got {manifest.recipient.recipient_id!r}"
126
)
127
print(f"  ✓ Python verifies Rust-sealed manifest with recipient_id={manifest.recipient.recipient_id!r}")
128
PYEOF
129
 
130
python3 <<PYEOF
131
import sys
132
sys.path.insert(0, '$PYTHON_ROOT')
133
from oversight_core import ClassicIdentity, content_hash
134
from oversight_core.manifest import Manifest, Recipient
135
from oversight_core.container import seal
136
 
137
alice_pub = bytes.fromhex('$ALICE_X_PUB')
138
issuer_priv = bytes.fromhex('$ISSUER_ED_PRIV')
139
issuer_pub = bytes.fromhex('$ISSUER_ED_PUB')
140
 
141
plaintext = open('plaintext.txt', 'rb').read()
142
m = Manifest.new(
143
    original_filename='plaintext.txt',
144
    content_hash=content_hash(plaintext),
145
    size_bytes=len(plaintext),
146
    issuer_id='cross-test',
147
    issuer_ed25519_pub_hex=issuer_pub.hex(),
148
    recipient=Recipient(recipient_id='$UNICODE_RECIPIENT', x25519_pub=alice_pub.hex()),
149
    registry_url='https://reg.test',
150
    content_type='text/plain',
151
)
152
blob = seal(plaintext, m, issuer_priv, alice_pub)
153
open('python-unicode-sealed.bin', 'wb').write(blob)
154
assert m.verify(), "Python cannot verify its own signature on a non-ASCII manifest"
155
print(f"  ✓ Python signed manifest with non-ASCII recipient_id, self-verify OK")
156
PYEOF
157
 
158
cargo run --manifest-path $RUST_CARGO --release -q -- open \
159
  --input python-unicode-sealed.bin --output rust-unicode-recovered.txt --recipient alice.json 2>&1 | tail -3
160
 
161
diff plaintext.txt rust-unicode-recovered.txt && echo "  ✓ Rust opens Python-sealed non-ASCII manifest, plaintext matches"
162
 
163
cargo run --manifest-path $RUST_CARGO --release -q -- inspect \
164
  --input python-unicode-sealed.bin 2>&1 | grep -E "signature valid" | head -1
165
 
166
echo ""
167
echo "=== 5. Hybrid (OSGT-HYBRID-v1) ML-KEM-768 KEM, Python <-> Rust ==="
168
PYTHONPATH="$REPO_ROOT:$PYTHONPATH" python3 "$REPO_ROOT/oversight-rust/tests/conformance_hybrid_kem.py"
169
 
170
echo ""
171
echo "=========================================="
172
echo "  CROSS-LANGUAGE CONFORMANCE: ALL PASS"
173
echo "=========================================="