OpenPay (1 crate, ~2287 LOC, 15 tests)
op-dispute-evidence Chargeback lifecycle + evidence packaging across Visa
VCR (10.x/11.x/12.x/13.x), Mastercard Mastercom
(4837/4853/1240/1442), Amex SafeKey + DRR, Discover DRR,
PayPal. CE3.0 compelling-evidence qualifier (120-365d
window, ≥2 qualifiers, ≥2 linking matches, 10.4-only).
Phase state machine + ReasonCodeCatalog + sealed
EvidencePackageBuilder + win-rate scoring.
Smart Byte (1 crate, ~2479 LOC, 44 tests)
smart-byte-edv Encrypted Data Vaults (DIF v0.10).
JWE ECDH-ES P-256 + HKDF-SHA256-Concat-KDF + AES-256-GCM,
multi-recipient; HMAC-SHA-256 encrypted index with
AND-equality queries; full ZCAP-LD chain validation;
chunked AES-256-GCM streaming with per-chunk AAD;
Vault trait + InMemoryVault + one-way pull replication.
EOC (1 crate, ~2065 LOC, 29 tests)
eoc-agent Agentic loops with per-step joule accounting.
ReAct, Reflexion (PASS/FAIL judge + episodic memory),
Tree of Thoughts (BFS/DFS + self-scoring), LATS
(MCTS-UCT select/expand/simulate/backprop),
Plan-and-Execute, CodeAct (fenced-block + pluggable
runtime). Budget enforcement (tokens/joules/tool-calls),
trace spans, JouleCounter integration.
Three other batch-5 deferrals (op-ewallets-asia, smart-byte-zk, eoc-rag)
will land in wave A3.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
136 lines
4.2 KiB
Rust
136 lines
4.2 KiB
Rust
//! Insert documents into an in-memory vault and prove that equality
|
|
//! queries over HMAC-blinded index tags return the expected matches —
|
|
//! without the vault ever seeing plaintext attribute values.
|
|
|
|
use smart_byte_edv::index::{IndexKey, Query};
|
|
use smart_byte_edv::jwe::{KeyPair, Recipient, wrap};
|
|
use smart_byte_edv::spec::{Config, EncryptedDocument, KeyDescriptor};
|
|
use smart_byte_edv::vault::{InMemoryVault, Vault};
|
|
|
|
fn cfg() -> Config {
|
|
let kex = KeyDescriptor {
|
|
id: "did:example:alice#kex-1".into(),
|
|
key_type: "JsonWebKey2020".into(),
|
|
controller: None,
|
|
};
|
|
let hmac = KeyDescriptor {
|
|
id: "did:example:alice#hmac-1".into(),
|
|
key_type: "Sha256HmacKey2019".into(),
|
|
controller: None,
|
|
};
|
|
Config::new("urn:uuid:vault", "did:example:alice", kex, hmac)
|
|
}
|
|
|
|
fn encrypted_doc(
|
|
id: &str,
|
|
plaintext: &[u8],
|
|
recipient: &Recipient,
|
|
index: &IndexKey,
|
|
attrs: &[(&str, &str)],
|
|
) -> EncryptedDocument {
|
|
let jwe = wrap(plaintext, std::slice::from_ref(recipient)).expect("wrap");
|
|
let entry = index.entry(attrs).expect("entry");
|
|
EncryptedDocument {
|
|
id: id.into(),
|
|
sequence: 0,
|
|
jwe: serde_json::to_value(&jwe).expect("jwe"),
|
|
indexed: vec![entry],
|
|
stream: None,
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn equality_query_returns_only_matching_docs() {
|
|
let vault = InMemoryVault::new(cfg());
|
|
|
|
let bob = KeyPair::generate().expect("bob");
|
|
let recipient = Recipient {
|
|
kid: "did:example:bob#kex-1".into(),
|
|
public: bob.public.clone(),
|
|
};
|
|
let index_key = IndexKey {
|
|
kid: "did:example:alice#hmac-1".into(),
|
|
key: [42u8; 32],
|
|
};
|
|
|
|
let a = encrypted_doc(
|
|
"urn:doc:a",
|
|
b"note one",
|
|
&recipient,
|
|
&index_key,
|
|
&[("type", "Note"), ("folder", "inbox")],
|
|
);
|
|
let b = encrypted_doc(
|
|
"urn:doc:b",
|
|
b"note two",
|
|
&recipient,
|
|
&index_key,
|
|
&[("type", "Note"), ("folder", "archive")],
|
|
);
|
|
let c = encrypted_doc(
|
|
"urn:doc:c",
|
|
b"photo",
|
|
&recipient,
|
|
&index_key,
|
|
&[("type", "Photo"), ("folder", "inbox")],
|
|
);
|
|
|
|
vault.insert(a).await.expect("insert a");
|
|
vault.insert(b).await.expect("insert b");
|
|
vault.insert(c).await.expect("insert c");
|
|
|
|
let q = Query::new()
|
|
.equal(&index_key, "type", "Note")
|
|
.expect("q1");
|
|
let hits = vault.query(&q).await.expect("query");
|
|
let ids: Vec<&str> = hits.iter().map(|d| d.id.as_str()).collect();
|
|
assert_eq!(ids, vec!["urn:doc:a", "urn:doc:b"]);
|
|
|
|
let q2 = Query::new()
|
|
.equal(&index_key, "folder", "inbox")
|
|
.expect("q2");
|
|
let hits2 = vault.query(&q2).await.expect("query");
|
|
let ids2: Vec<&str> = hits2.iter().map(|d| d.id.as_str()).collect();
|
|
assert_eq!(ids2, vec!["urn:doc:a", "urn:doc:c"]);
|
|
|
|
let q3 = Query::new()
|
|
.equal(&index_key, "type", "Note")
|
|
.expect("q3a")
|
|
.equal(&index_key, "folder", "archive")
|
|
.expect("q3b");
|
|
let hits3 = vault.query(&q3).await.expect("query");
|
|
let ids3: Vec<&str> = hits3.iter().map(|d| d.id.as_str()).collect();
|
|
assert_eq!(ids3, vec!["urn:doc:b"]);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn vault_sees_only_hmac_tags() {
|
|
// Sanity-check that the literal plaintext attribute names and values
|
|
// never appear in the serialised on-disk form.
|
|
let vault = InMemoryVault::new(cfg());
|
|
let bob = KeyPair::generate().expect("bob");
|
|
let recipient = Recipient {
|
|
kid: "did:example:bob#kex-1".into(),
|
|
public: bob.public.clone(),
|
|
};
|
|
let index_key = IndexKey {
|
|
kid: "did:example:alice#hmac-1".into(),
|
|
key: [42u8; 32],
|
|
};
|
|
let doc = encrypted_doc(
|
|
"urn:doc:secret",
|
|
b"top secret",
|
|
&recipient,
|
|
&index_key,
|
|
&[("classification", "TopSecret")],
|
|
);
|
|
vault.insert(doc).await.expect("insert");
|
|
|
|
let listed = vault.list().await.expect("list");
|
|
assert_eq!(listed.len(), 1);
|
|
let stored = vault.get("urn:doc:secret").await.expect("get");
|
|
let wire = serde_json::to_string(&stored).expect("serialize");
|
|
assert!(!wire.contains("TopSecret"));
|
|
assert!(!wire.contains("classification"));
|
|
assert!(!wire.contains("top secret"));
|
|
}
|