Table of Contents

Class ZeroizingBuffer

Namespace
PostQuantum.SecretSharing
Assembly
PostQuantum.SecretSharing.dll

A fixed-size byte buffer for secret material that is zeroed on disposal and is allocated on the pinned object heap so the garbage collector can never relocate (and thus silently copy) the secret elsewhere in memory.

public sealed class ZeroizingBuffer : IDisposable
Inheritance
ZeroizingBuffer
Implements
Inherited Members

Remarks

Why pinned allocation. A normal managed array can be moved by a compacting GC, leaving a stale copy of the secret in the old location that ZeroMemory(Span<byte>) on the live array will never reach. AllocateArray<T>(int, bool) with pinned: true places the backing array on the pinned object heap, which is never compacted, so the bytes we zero are the only copy the GC ever made.

Best-effort page-locking. On construction the buffer is locked into RAM (VirtualLock on Windows, mlock on Linux/macOS) to resist being paged to swap, and unlocked on disposal. This is best-effort: IsMemoryLocked reports whether it succeeded — it can fail without privileges or when the per-process locked-memory limit is reached, in which case the buffer still works, just unlocked.

Still out of scope. Locking resists swap but does not defend against a process memory dump. The secret necessarily exists in cleartext in process memory while it is in use. See KNOWN-GAPS.md.

Constructors

ZeroizingBuffer(int)

Allocates a pinned, zero-initialized buffer of the given length and attempts to lock it into RAM (best-effort; see IsMemoryLocked).

public ZeroizingBuffer(int length)

Parameters

length int

Buffer length in bytes; must be non-negative.

Exceptions

ArgumentOutOfRangeException

If length is negative.

Properties

IsMemoryLocked

Whether the backing pages were successfully locked into RAM. False is not an error — the buffer is fully functional, just not protected from swap.

public bool IsMemoryLocked { get; }

Property Value

bool

Length

The buffer length in bytes. Remains valid after disposal.

public int Length { get; }

Property Value

int

Span

A writable view over the secret bytes.

public Span<byte> Span { get; }

Property Value

Span<byte>

Exceptions

ObjectDisposedException

If the buffer has been disposed.

Methods

Dispose()

Zeroes the buffer and marks it disposed. Idempotent: calling more than once is safe and does nothing after the first call.

public void Dispose()

~ZeroizingBuffer()

Best-effort finalizer backstop: if a caller forgets to dispose, zero and unlock the buffer when the object is collected. This is not a substitute for explicit disposal (the window between last use and collection is unbounded) and is documented as best-effort in KNOWN-GAPS.md.

protected ~ZeroizingBuffer()