[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-93265":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":15,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":36,"readmeContent":37,"aiSummary":38,"trendingCount":14,"starSnapshotCount":14,"syncStatus":12,"lastSyncTime":39,"discoverSource":40},93265,"memguard-rs","m-novotny\u002Fmemguard-rs","m-novotny","Secure memory handling primitives for Rust — zeroization on drop, mlock-protected regions, constant-time comparison, and compile-time enforced memory safety boundaries",null,"Rust",130,2,122,0,1,42.03,"Apache License 2.0",false,"main",true,[22,23,24,25,26,27,28,29,30,31,32,33,34,35],"constant-time","crypto","cryptography","embedded","memory-management","memory-safety","mlock","no-std","rust","secret","secure-memory","security","side-channel","zeroize","2026-07-22 04:02:08","# memguard-rs\n\n[![CI](https:\u002F\u002Fgithub.com\u002Fm-novotny\u002Fmemguard-rs\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fm-novotny\u002Fmemguard-rs\u002Factions\u002Fworkflows\u002Fci.yml)\n[![Crates.io](https:\u002F\u002Fimg.shields.io\u002Fcrates\u002Fv\u002Fmemguard-rs.svg?style=flat-square)](https:\u002F\u002Fcrates.io\u002Fcrates\u002Fmemguard-rs)\n[![Documentation](https:\u002F\u002Fdocs.rs\u002Fmemguard-rs\u002Fbadge.svg?style=flat-square)](https:\u002F\u002Fdocs.rs\u002Fmemguard-rs\u002F)\n[![License](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT%20OR%20Apache--2.0-blue.svg?style=flat-square)](#license)\n[![MSRV](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Frustc-1.65+-orange.svg?style=flat-square)](https:\u002F\u002Fblog.rust-lang.org\u002F2022\u002F11\u002F03\u002FRust-1.65.0.html)\n[![no_std](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fno__std-compatible-purple.svg?style=flat-square)](#features)\n\nSecure memory handling primitives for Rust.\n\n- **Zeroization on drop** — volatile-write memory clearing the compiler cannot optimize away\n- **Memory locking** — `mlock`\u002F`VirtualLock` to prevent secrets from being written to swap\n- **Constant-time comparison** — timing side-channel resistant equality checks for secrets\n- **Compile-time guarded regions** — const-generic memory regions with type-level size enforcement\n- **`no_std` compatible** — core primitives work without an allocator\n- **Zero dependencies** — no transitive dependency surface to audit\n\n## Quick start\n\nAdd to your `Cargo.toml`:\n\n```toml\n[dependencies]\nmemguard-rs = \"0.1\"\n```\n\n### Wrapping a secret\n\n```rust\nuse memguard_rs::Secret;\n\nlet mut key = Secret::new([0u8; 32]);\n\n\u002F\u002F Access the secret only within a closure\nkey.expose(|k| {\n    println!(\"Key length: {}\", k.len());\n});\n\n\u002F\u002F Modify in place\nkey.expose_mut(|k| {\n    k[0] = 0xFF;\n});\n\n\u002F\u002F When `key` goes out of scope, its memory is zeroized via volatile writes\n```\n\n### Locking memory with mlock\n\n```rust\nuse memguard_rs::Secret;\n\n\u002F\u002F Lock the secret's memory to prevent it from being written to swap\nlet key = Secret::new([0xAB; 32]).lock().unwrap();\nassert!(key.is_locked());\n\n\u002F\u002F Memory is unlocked and zeroized when `key` is dropped\n```\n\n### Guarded memory regions\n\n```rust\nuse memguard_rs::GuardedRegion;\n\n\u002F\u002F Create a 64-byte locked, zeroized-on-drop region\nlet mut region = GuardedRegion::\u003C64>::new().unwrap();\n\n\u002F\u002F Write sensitive data\nregion.as_mut_slice().copy_from_slice(&[0xEF; 64]);\n\n\u002F\u002F Read it back\nassert_eq!(region.as_slice()[0], 0xEF);\n\n\u002F\u002F When `region` drops, memory is zeroized and unlocked\n```\n\n### Constant-time comparison\n\n```rust\nuse memguard_rs::ct_eq;\n\nlet stored_mac = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];\nlet received_mac = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];\n\n\u002F\u002F Compare without leaking timing information\nif ct_eq(&stored_mac, &received_mac) {\n    println!(\"MAC verified\");\n}\n```\n\n## Features\n\n| Feature | Default | Description |\n|---------|---------|-------------|\n| `std`   | ✓ | Enables `std` support (implies `alloc`) |\n| `alloc` | (via `std`) | Enables heap-allocated types (`SecretBox`) |\n| `lock`  | ✓ | Enables `mlock`\u002F`VirtualLock` memory locking |\n\n### `no_std` usage\n\n```rust\n#![no_std]\n\nuse memguard_rs::{Secret, Zeroize};\n\nfn verify_token(stored: &[u8; 16], received: &[u8; 16]) -> bool {\n    let mut secret = Secret::new(*stored);\n    let mut result = false;\n    secret.expose(|s| {\n        \u002F\u002F constant-time comparison works in no_std\n        result = memguard_rs::ct_eq(s, received);\n    });\n    result\n}\n```\n\n## Safety\n\nThis crate uses `unsafe` in the following places:\n\n- **Volatile writes** in `zeroize` — `core::ptr::write_volatile` is used to zero memory. The pointers are always valid, aligned, and within bounds.\n- **FFI calls** in `mlock` — direct `extern \"C\"` \u002F `extern \"system\"` declarations for `mlock`\u002F`munlock` (Unix) and `VirtualLock`\u002F`VirtualUnlock` (Windows). These are standard system calls with well-defined semantics.\n- **ManuallyDrop** in `secret` — used to control the drop order: zeroize first, then drop the value. This prevents double-drops if zeroization panics.\n\nNo `unsafe` is exposed in the public API. All unsafe code is internal and encapsulated behind safe abstractions.\n\n## MSRV\n\nMinimum Supported Rust Version: **1.65**\n\nThe MSRV may be bumped in minor version releases. Pin a specific version in your `Cargo.toml` if you need a stable MSRV.\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or http:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n\nat your option.\n\n## Contributing\n\nContributions are welcome. Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n### Help wanted\n\nWe have several issues tagged [`good first issue`](https:\u002F\u002Fgithub.com\u002Fm-novotny\u002Fmemguard-rs\u002Fissues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) suitable for new contributors:\n\n- [#2 — Implement `Zeroize` for wider slice types](https:\u002F\u002Fgithub.com\u002Fm-novotny\u002Fmemguard-rs\u002Fissues\u002F2)\n- [#8 — Document drop order guarantee in `Secret\u003CT>`](https:\u002F\u002Fgithub.com\u002Fm-novotny\u002Fmemguard-rs\u002Fissues\u002F8)\n\nAll contributions are dual-licensed under the MIT and Apache 2.0 licenses.\n","memguard-rs 是一个面向安全敏感场景的 Rust 内存保护库，提供零化销毁、内存锁定（mlock）、恒定时间比较及编译期大小约束的受保护内存区域等核心能力。它通过 volatile 写入确保秘密数据在 drop 时不可恢复清除，利用 mlock\u002FVirtualLock 防止交换泄露，并通过类型系统与 const generics 强制内存边界安全。支持 no_std 环境，无外部依赖，适用于密码学实现、嵌入式密钥管理、金融终端等对侧信道防护和内存安全有严格要求的场景。","2026-07-15 02:30:03","CREATED_QUERY"]