FEP-0001: Progressive Secure Package Format (PSPF/2025) - Core Specification¶
Status: Standards Track
Type: Core Protocol
Created: 2025-01-08
Version: v0.1
Category: Informational → Standards Track
Abstract¶
This document specifies the Progressive Secure Package Format (PSPF/2025), a binary package format designed for cross-platform software distribution with embedded cryptographic verification, composable operation chains, and runtime extraction capabilities. PSPF/2025 combines a native launcher binary with structured metadata and data slots using a space-efficient trailer-based index design.
The format supports deterministic builds, Ed25519 digital signatures, composable archive and compression operations, and memory-mapped access patterns suitable for resource-constrained environments.
Table of Contents¶
- Introduction
- Conventions and Terminology
- Protocol Overview
- Binary Format Specification
- Operation Chain System
- Processing Algorithms
- Security Model
- Error Handling
- Implementation Requirements
- Security Considerations
- IANA Considerations
- Examples and Test Vectors
- References
1. Introduction¶
1.1 Motivation¶
Modern software distribution faces several challenges: - Portability: Applications must run across diverse operating systems and architectures - Security: Packages require cryptographic verification and tamper detection - Efficiency: Large applications need selective extraction and memory-mapped access - Reliability: Deterministic builds and reproducible archives are essential - Complexity: Traditional package managers introduce dependency conflicts and environment coupling
PSPF/2025 addresses these challenges by embedding a native launcher directly into each package, eliminating external runtime dependencies while providing cryptographic security and efficient data access.
1.2 Scope and Applicability¶
This specification defines: - Binary layout and parsing requirements for PSPF/2025 packages - Operation chain system for composable archive and compression operations - Cryptographic security model using Ed25519 signatures - Cross-language implementation requirements for Python, Go, and Rust - Compatibility and extensibility mechanisms
This specification does NOT define:
- Higher-level packaging workflows or build systems
- Network distribution protocols or package repositories
- Application runtime environments or execution models
- Operating system integration or installation procedures
1.3 Requirements Language¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here.
1.4 Related Documents¶
This document is part of a series:
- FEP-0001 (this document): Core binary format and operation chains
- FEP-0002: JSON Metadata Format Specification
- FEP-0003: Operation Registry and Allocation Policy
2. Conventions and Terminology¶
2.1 Definitions¶
Package: A single binary file containing a launcher, metadata, and data slots Launcher: Platform-specific native executable embedded at the start of the package Slot: A numbered data container with associated metadata and operations Operation Chain: A sequence of up to 8 operations (archive, compress, encrypt, etc.) Index Block: 8192-byte structure containing package metadata and offsets Magic Trailer: The index block plus surrounding 4-byte emoji markers Workenv: Temporary directory where package contents are extracted during execution
2.2 Notation Conventions¶
Binary layouts use C-style struct notation with explicit sizes:
struct Example {
uint32_t field1; // 4 bytes, little-endian
uint64_t field2; // 8 bytes, little-endian
uint8_t data[16]; // 16-byte array
};
Operation chains use pipe notation: TAR|GZIP means "apply TAR, then GZIP"
Hexadecimal values use 0x prefix: 0x20250001
Sizes use standard units: 1KB = 1024 bytes, 1MB = 1024KB
2.3 Architectural Constants¶
PSPF_VERSION = 0x20250001 // Format version identifier
INDEX_BLOCK_SIZE = 8192 // Exactly 8KB
SLOT_DESCRIPTOR_SIZE = 64 // Exactly 64 bytes
MAGIC_TRAILER_SIZE = 8200 // Index + 2 emoji markers
MAX_SLOTS = 65535 // 16-bit slot count limit
MAX_OPERATION_CHAIN = 8 // Operations per chain
MAX_PACKAGE_SIZE = 2^63-1 // 64-bit size limit
3. Protocol Overview¶
3.1 Design Principles¶
Self-Contained Execution: Each package includes its own launcher, eliminating external dependencies
Cryptographic Integrity: Ed25519 signatures provide tamper detection and authenticity verification
Composable Operations: Standardized operation chains enable flexible archive and compression strategies
Memory Efficiency: Trailer-based design enables memory-mapped access without loading entire package
Cross-Language Compatibility: Identical binary layout across Python, Go, and Rust implementations
Progressive Enhancement: v0 defines minimal requirements; future versions add capabilities
3.2 Package Structure Overview¶
┌─────────────────────────────┐ ← Offset 0
│ Native Launcher │ Platform-specific executable
│ (Variable Size) │ Contains extraction logic
├─────────────────────────────┤ ← launcher_size
│ │
│ Metadata Block │ Compressed JSON metadata
│ (Variable Size) │ Package info, slot definitions
│ │
├─────────────────────────────┤ ← metadata_offset + metadata_size
│ │
│ Slot Table │ Array of 64-byte descriptors
│ (slot_count × 64 bytes) │ One per slot
│ │
├─────────────────────────────┤ ← slot_table_offset + slot_table_size
│ │
│ Slot Data │ Actual slot contents
│ (Variable Size) │ May be compressed/encrypted
│ │
├─────────────────────────────┤ ← EOF - 8200
│ 📦 (Start Magic, 4 bytes) │ UTF-8 emoji: 0xF0 0x9F 0x93 0xA6
├─────────────────────────────┤ ← EOF - 8196
│ │
│ Index Block │ Package metadata and pointers
│ (8192 bytes) │ Checksum, signatures, offsets
│ │
├─────────────────────────────┤ ← EOF - 4
│ 🪄 (End Magic, 4 bytes) │ UTF-8 emoji: 0xF0 0x9F 0xAA 0x84
└─────────────────────────────┘ ← EOF
3.3 Processing Model¶
Package Creation: 1. Prepare launcher binary for target platform 2. Process input files through operation chains (e.g., TAR → GZIP) 3. Generate slot descriptors with checksums 4. Create JSON metadata 5. Assemble binary package with index block 6. Sign package with Ed25519 private key
Package Execution: 1. Launcher validates magic trailer and signature 2. Index block provides metadata and slot table offsets 3. Required slots are extracted to workenv on demand 4. Application executes from workenv with proper environment
4. Binary Format Specification¶
4.1 Overall Package Layout¶
A PSPF/2025 package MUST be structured as a single binary file with components laid out sequentially. Multi-byte integers MUST use little-endian byte order.
The package size MUST be at least 8200 bytes (minimum for magic trailer) and MUST NOT exceed 2^63-1 bytes.
4.2 Magic Trailer Format¶
The magic trailer is exactly 8200 bytes located at the end of the package file. Its presence and integrity indicate a valid PSPF/2025 package.
struct MagicTrailer {
uint8_t start_magic[4]; // 0xF0 0x9F 0x93 0xA6 (📦 emoji)
uint8_t index_block[8192]; // See Section 4.3
uint8_t end_magic[4]; // 0xF0 0x9F 0xAA 0x84 (🪄 emoji)
};
Field Descriptions:
- start_magic: UTF-8 encoded 📦 emoji marking trailer start
- index_block: Fixed-size metadata block (see Section 4.3)
- end_magic: UTF-8 encoded 🪄 emoji marking trailer end
Validation Requirements:
1. Both magic sequences MUST be present and correct
2. Index block MUST pass checksum validation
3. Package size MUST match package_size field in index
4.3 Index Block Structure¶
The index block is exactly 8192 bytes containing package metadata, file offsets, cryptographic signatures, and performance hints.
struct IndexBlock {
// === Core Identification (8 bytes) ===
uint32_t format_version; // MUST be 0x20250001 for v0
uint32_t index_checksum; // Adler-32 of index block (with this field set to 0)
// === File Structure (48 bytes) ===
uint64_t package_size; // Total package file size in bytes
uint64_t launcher_size; // Size of embedded launcher binary
uint64_t metadata_offset; // Offset to JSON metadata
uint64_t metadata_size; // Size of JSON metadata (compressed)
uint64_t slot_table_offset; // Offset to slot descriptor array
uint64_t slot_table_size; // Size of slot table in bytes
// === Slot Information (8 bytes) ===
uint32_t slot_count; // Number of slots (0-65535)
uint32_t flags; // Package flags (see PackageFlags)
// === Security (576 bytes) ===
uint8_t public_key[32]; // Ed25519 public key
uint8_t metadata_checksum[32]; // SHA-256 of compressed metadata (full 32 bytes)
uint8_t integrity_signature[512]; // Ed25519 signature (first 64 bytes used)
// === Performance Hints (64 bytes) ===
uint8_t access_mode; // Access pattern hint (0=auto, 1=sequential, 2=random)
uint8_t cache_strategy; // Cache behavior hint (0=normal, 1=aggressive, 2=minimal)
uint8_t reserved_hint1; // Reserved for future use
uint8_t reserved_hint2; // Reserved for future use
uint32_t page_size; // Preferred memory page size (typically 4096)
uint64_t max_memory; // Maximum memory usage hint in bytes
uint64_t min_memory; // Minimum memory required in bytes
uint64_t cpu_features; // Required CPU feature flags
uint64_t gpu_requirements; // GPU capability requirements
uint64_t numa_hints; // NUMA topology hints
uint32_t stream_chunk_size; // Streaming I/O chunk size hint
uint8_t padding[12]; // Padding to maintain alignment
// === Extended Metadata (128 bytes) ===
uint64_t build_timestamp; // Unix timestamp of package creation
uint8_t build_machine[32]; // Build machine identifier
uint8_t source_hash[32]; // SHA-256 of source code tree
uint8_t dependency_hash[32]; // SHA-256 of dependency manifest
uint8_t license_id[16]; // License identifier or hash
uint8_t provenance_uri[8]; // Short provenance URI or reference
// === Capabilities (32 bytes) ===
uint64_t capabilities; // Supported feature flags
uint64_t requirements; // Required system capabilities
uint64_t extensions; // Extension mechanism flags
uint32_t compatibility; // Compatibility version identifier
uint32_t protocol_version; // Protocol version (1 for v0)
// === Future Cryptography (512 bytes) ===
uint8_t future_crypto[512]; // Reserved for future cryptographic algorithms
// === Reserved Space (6816 bytes) ===
uint8_t reserved[6816]; // Reserved for future expansion
};
Field Validation Requirements:
All offset fields MUST point to valid locations within the package file:
- 0 ≤ metadata_offset ≤ package_size - metadata_size
- 0 ≤ slot_table_offset ≤ package_size - slot_table_size
- launcher_size ≤ package_size - 8200
The slot_table_size MUST equal slot_count × 64.
Reserved fields MUST be zero-filled in v0 packages.
4.4 Package Flags¶
The flags field uses bit positions to indicate package capabilities:
enum PackageFlags {
FLAG_MEMORY_MAPPED = 1 << 0, // Package supports memory mapping
FLAG_SIGNED = 1 << 1, // Package is cryptographically signed
FLAG_COMPRESSED = 1 << 2, // Package uses compression
FLAG_ENCRYPTED = 1 << 3, // Package contains encrypted slots
FLAG_REPRODUCIBLE = 1 << 4, // Package was built reproducibly
FLAG_STREAMING = 1 << 5, // Package supports streaming access
// Bits 6-31 reserved for future use
};
4.5 Slot Descriptor Format¶
Each slot in the package is described by a 64-byte descriptor with the following binary layout:
struct SlotDescriptor {
// === Core Fields (56 bytes - 7 × uint64) ===
uint64_t id; // Unique slot identifier
uint64_t name_hash; // SHA-256 of slot name (first 8 bytes, little-endian)
uint64_t offset; // File offset to slot data
uint64_t size; // Size of stored data (compressed)
uint64_t original_size; // Uncompressed size
uint64_t operations; // Packed operation chain (up to 8 ops)
uint64_t checksum; // SHA-256 of stored data (first 8 bytes, little-endian)
// === Metadata Fields (8 bytes - 8 × uint8) ===
uint8_t purpose; // Purpose type (0=data, 1=code, 2=config, 3=media)
uint8_t lifecycle; // Lifecycle management hint
uint8_t priority; // Cache priority hint (0-255)
uint8_t platform; // Platform requirements
uint8_t reserved1; // Reserved for future use
uint8_t reserved2; // Reserved for future use
uint8_t permissions; // Unix-style permissions (low byte)
uint8_t permissions_high; // Unix-style permissions (high byte)
};
Field Descriptions:
- id: 64-bit unique identifier for the slot
- name_hash: SHA-256 hash of slot name (first 8 bytes, little-endian) for fast lookup
- offset: Byte offset from the beginning of the package file to the slot data
- size: Size of the slot data as stored (after compression)
- original_size: Original uncompressed size of the slot data
- operations: Packed operation chain (up to 8 operations, each 8 bits)
- checksum: SHA-256 hash of stored data (first 8 bytes, little-endian)
- purpose: Classification of slot contents (0=code, 1=data, 2=config, 3=media)
- lifecycle: When the slot should be extracted/loaded
- priority: Cache priority hint (0-255, higher = keep in memory longer)
- platform: Platform hint for optimization (0=any, 1=linux, 2=darwin, 3=windows)
- permissions + permissions_high: Unix-style file permissions (16-bit value)
- reserved1-2: Reserved for future expansion
Total size: 64 bytes exactly
5. Operation Chain System¶
Implementation Note: In the current v0 implementation, operation codes are defined directly in language-specific constants files (
constants.py,constants.go,constants.rs) rather than generated from Protocol Buffer definitions. The protobuf-based operation registry described in FEP-0003 is planned for future versions to provide cross-language schema validation.
5.1 Operation Categories¶
Operations are 8-bit values organized into functional categories. Each category occupies a fixed range of the 256-value operation space:
| Range | Category | v0 Status | Description |
|---|---|---|---|
| 0x00 | NONE | REQUIRED | No operation (pass-through) |
| 0x01-0x0F | BUNDLE | PARTIAL | Archive formats (TAR required) |
| 0x10-0x2F | COMPRESS | PARTIAL | Compression algorithms |
| 0x30-0x4F | ENCRYPT | FUTURE | Encryption and key management |
| 0x50-0x6F | ENCODE | FUTURE | Encoding transformations |
| 0x70-0x8F | HASH | FUTURE | Cryptographic hash functions |
| 0x90-0xAF | SIGNATURE | FUTURE | Digital signature algorithms |
| 0xB0-0xCF | TRANSFORM | FUTURE | Data transformation operations |
| 0xD0-0xEF | CUSTOM | FUTURE | Implementation-specific ops |
| 0xF0-0xFF | RESERVED | FUTURE | Reserved for specification use |
5.2 v0 Required Operations¶
All v0-compliant implementations MUST support these operations:
Core Operations¶
Bundle Operations¶
Compression Operations¶
0x10 OP_GZIP GZIP compression (RFC 1952)
0x13 OP_BZIP2 BZIP2 compression
0x16 OP_XZ XZ/LZMA2 compression
0x1B OP_ZSTD Zstandard compression
5.3 Operation Chain Encoding¶
Operation chains are encoded as 64-bit little-endian integers with each operation occupying one byte. Operations are applied in sequence during package creation and reversed during extraction.
Encoding Format:
Bytes: 7 6 5 4 3 2 1 0
┌────┬────┬────┬────┬────┬────┬────┬────┐
│Op8 │Op7 │Op6 │Op5 │Op4 │Op3 │Op2 │Op1 │
└────┴────┴────┴────┴────┴────┴────┴────┘
MSB LSB
Processing Order: - Creation: Input → Op1 → Op2 → ... → Op8 → Stored Data - Extraction: Stored Data → Op8⁻¹ → ... → Op2⁻¹ → Op1⁻¹ → Output
Encoding Rules:
1. Operations MUST be stored in application order (LSB first)
2. Unused positions MUST be filled with OP_NONE (0x00)
3. The first OP_NONE encountered terminates the chain
4. Maximum chain length is 8 operations
5. Empty chains (all zeros) represent raw data
Examples:
TAR only: 0x0000000000000001
GZIP only: 0x0000000000000010
TAR→GZIP: 0x0000000000001001
TAR→BZIP2: 0x0000000000001301
TAR→XZ: 0x0000000000001601
TAR→ZSTD: 0x0000000000001B01
5.4 Operation Chain Validation¶
Implementations MUST validate operation chains before processing:
- Supported Operations: All operations in chain MUST be supported by implementation
- Chain Length: Chain MUST NOT exceed 8 operations
- Termination: First
OP_NONEterminates chain; subsequent bytes ignored - Compatibility: Operation combinations MUST be compatible (e.g., compression after archive)
Invalid chains MUST cause package rejection with appropriate error codes.
5.5 Standard Operation Chains¶
v0 implementations MUST support these common operation chains:
"raw" [] // No operations
"gzip" [OP_GZIP] // GZIP only
"bzip2" [OP_BZIP2] // BZIP2 only
"xz" [OP_XZ] // XZ only
"zstd" [OP_ZSTD] // Zstandard only
"tar" [OP_TAR] // TAR only
"tar.gz" [OP_TAR, OP_GZIP] // TAR then GZIP
"tar.bz2" [OP_TAR, OP_BZIP2] // TAR then BZIP2
"tar.xz" [OP_TAR, OP_XZ] // TAR then XZ
"tar.zst" [OP_TAR, OP_ZSTD] // TAR then Zstandard
6. Processing Algorithms¶
6.1 Package Validation Algorithm¶
function validatePackage(packageData):
// 1. Check minimum size
if packageData.length < 8200:
return ERROR_INVALID_SIZE
// 2. Extract and validate magic trailer
trailerOffset = packageData.length - 8200
startMagic = packageData[trailerOffset:trailerOffset+4]
endMagic = packageData[packageData.length-4:packageData.length]
if startMagic != [0xF0, 0x9F, 0x93, 0xA6]:
return ERROR_INVALID_START_MAGIC
if endMagic != [0xF0, 0x9F, 0xAA, 0x84]:
return ERROR_INVALID_END_MAGIC
// 3. Parse and validate index block
indexData = packageData[trailerOffset+4:trailerOffset+4+8192]
index = parseIndexBlock(indexData)
if index.format_version != 0x20250001:
return ERROR_INVALID_VERSION
// 4. Verify index checksum
checksumData = indexData.copy()
checksumData[4:8] = [0, 0, 0, 0] // Zero checksum field
computedChecksum = adler32(checksumData)
if computedChecksum != index.index_checksum:
return ERROR_INVALID_CHECKSUM
// 5. Validate structure
if index.package_size != packageData.length:
return ERROR_SIZE_MISMATCH
if index.slot_table_size != index.slot_count * 64:
return ERROR_INVALID_SLOT_TABLE_SIZE
return SUCCESS
6.2 Slot Extraction Algorithm¶
function extractSlot(packageData, slotDescriptor):
// 1. Read slot data from package
slotData = packageData[slotDescriptor.offset:slotDescriptor.offset+slotDescriptor.size]
// 2. Verify stored data checksum
computedChecksum = sha256(slotData)[0:8] // First 8 bytes as uint64
if computedChecksum != slotDescriptor.checksum:
return ERROR_CORRUPTED_SLOT
// 3. Apply reverse operation chain
operations = unpackOperations(slotDescriptor.operations)
currentData = slotData
for operation in reverse(operations):
currentData = applyReverseOperation(operation, currentData)
if currentData == ERROR:
return ERROR_OPERATION_FAILED
// 4. Verify final size
if currentData.length != slotDescriptor.original_size:
return ERROR_SIZE_MISMATCH
return currentData
6.3 Operation Chain Processing¶
function applyOperationChain(inputData, operations):
currentData = inputData
for operation in operations:
switch operation:
case OP_NONE:
break // No-op, terminate chain
case OP_TAR:
currentData = createTarArchive(currentData)
case OP_GZIP:
currentData = gzipCompress(currentData)
case OP_BZIP2:
currentData = bzip2Compress(currentData)
case OP_XZ:
currentData = xzCompress(currentData)
case OP_ZSTD:
currentData = zstdCompress(currentData)
default:
return ERROR_UNSUPPORTED_OPERATION
if currentData == ERROR:
return ERROR_OPERATION_FAILED
return currentData
function applyReverseOperation(operation, data):
switch operation:
case OP_NONE:
return data // No-op
case OP_TAR:
return extractTarArchive(data)
case OP_GZIP:
return gzipDecompress(data)
case OP_BZIP2:
return bzip2Decompress(data)
case OP_XZ:
return xzDecompress(data)
case OP_ZSTD:
return zstdDecompress(data)
default:
return ERROR_UNSUPPORTED_OPERATION
7. Security Model¶
7.1 Cryptographic Primitives¶
PSPF/2025 uses modern cryptographic algorithms for integrity and authenticity:
Digital Signatures: Ed25519 (RFC 8032) - Public key: 32 bytes - Signature: 64 bytes (stored in first 64 bytes of 512-byte field) - Provides non-repudiation and tamper detection
Hash Functions: - SHA-256 for metadata integrity (32 bytes full hash) - SHA-256 for slot data integrity (first 8 bytes) - Adler-32 for index block checksums (4 bytes, fast validation)
Random Number Generation: Implementations MUST use cryptographically secure random number generators for key generation.
7.2 Signature Verification¶
Package signatures cover all package content except the signature field itself:
function verifyPackageSignature(packageData, publicKey):
// 1. Extract signature from index block
indexOffset = packageData.length - 8196
signatureOffset = indexOffset + 80 // Offset to integrity_signature field
signature = packageData[signatureOffset:signatureOffset+64]
// 2. Create signed data by zeroing signature field
signedData = packageData.copy()
signedData[signatureOffset:signatureOffset+512] = zeros(512)
// 3. Verify Ed25519 signature
return ed25519Verify(publicKey, signature, signedData)
7.3 Trust Model¶
PSPF/2025 implements a explicit trust model:
- Package Integrity: Signatures prevent modification after creation
- Publisher Authentication: Public keys identify package creators
- Content Isolation: Each slot has independent checksums
- Replay Protection: Build timestamps prevent rollback attacks
Trust Establishment: Out of band through: - Secure distribution channels (HTTPS) - Public key infrastructure (PKI) - Web of trust systems - Hardware security modules (HSMs)
7.4 Threat Mitigation¶
| Threat | Mitigation |
|---|---|
| Package tampering | Ed25519 signatures |
| Content corruption | Per-slot SHA-256 checksums (8 bytes) |
| Rollback attacks | Build timestamps |
| Directory traversal | Path validation during extraction |
| Resource exhaustion | Size limits and memory bounds |
| Malicious operations | Operation whitelist validation |
8. Error Handling¶
8.1 Error Code Classification¶
Error codes are organized by category:
// Format Errors (1-99)
#define ERROR_INVALID_MAGIC 1
#define ERROR_INVALID_VERSION 2
#define ERROR_INVALID_CHECKSUM 3
#define ERROR_INVALID_SIZE 4
#define ERROR_TRUNCATED_PACKAGE 5
// Structure Errors (100-199)
#define ERROR_INVALID_OFFSET 100
#define ERROR_INVALID_SLOT_COUNT 101
#define ERROR_MISSING_METADATA 102
#define ERROR_MISSING_SLOT_TABLE 103
// Cryptographic Errors (200-299)
#define ERROR_INVALID_SIGNATURE 200
#define ERROR_MISSING_PUBLIC_KEY 201
#define ERROR_CORRUPTED_METADATA 202
#define ERROR_CORRUPTED_SLOT 203
// Operation Errors (300-399)
#define ERROR_UNSUPPORTED_OPERATION 300
#define ERROR_OPERATION_FAILED 301
#define ERROR_INVALID_CHAIN 302
#define ERROR_CHAIN_TOO_LONG 303
// Resource Errors (400-499)
#define ERROR_INSUFFICIENT_MEMORY 400
#define ERROR_DISK_FULL 401
#define ERROR_PERMISSION_DENIED 402
#define ERROR_TIMEOUT 403
8.2 Error Recovery Strategies¶
Implementations SHOULD attempt recovery when possible:
- Checksum Failures: Retry with different compression levels
- Partial Extraction: Continue with available slots
- Memory Pressure: Fall back to streaming extraction
- Network Issues: Implement exponential backoff
8.3 Diagnostic Information¶
Error responses MUST include sufficient diagnostic information:
struct ErrorInfo {
uint32_t error_code; // Error classification code
uint32_t offset; // File offset where error occurred
uint32_t size; // Expected vs actual size
char message[256]; // Human-readable description
uint8_t context[64]; // Additional debugging data
};
9. Implementation Requirements¶
9.1 Conformance Levels¶
Level 1 - Basic Reader: - MUST validate package format and signatures - MUST extract slots with required operations - MUST handle standard operation chains
Level 2 - Full Implementation:
- MUST support package creation
- MUST implement all required operations
- MUST generate valid signatures
Level 3 - Extended Implementation: - MAY support future operations - MAY implement streaming extraction - MAY support memory-mapped access
9.2 Cross-Language Compatibility¶
Implementations in different languages MUST:
- Produce Identical Output: Same input MUST generate byte-identical packages
- Interoperate Completely: Packages created by one implementation MUST be readable by all others
- Handle Edge Cases: Consistent behavior for boundary conditions
- Use Standard Libraries: Cryptographic operations MUST use well-tested libraries
9.3 Performance Requirements¶
Implementations SHOULD meet these performance targets:
- Validation: < 10ms for packages under 100MB
- Signature Verification: < 5ms using standard hardware
- Metadata Parsing: < 1ms for typical metadata sizes
- Memory Usage: < 64MB for packages under 1GB
9.4 Testing Requirements¶
Implementations MUST pass a standardized test suite including:
- Format Validation: Valid and invalid package structures
- Cryptographic Tests: Signature generation and verification
- Operation Tests: All required operation combinations
- Cross-Language Tests: Interoperability between implementations
- Security Tests: Malformed input and attack vectors
10. Security Considerations¶
10.1 Input Validation¶
Implementations MUST validate all input data to prevent:
- Buffer Overflows: Bounds checking on all array accesses
- Integer Overflows: Validation of size calculations
- Path Traversal: Sanitization of extraction paths
- Resource Exhaustion: Limits on memory and disk usage
10.2 Cryptographic Implementation¶
Security-critical operations require careful implementation:
- Constant-Time Operations: Signature verification MUST be constant-time
- Secure Key Handling: Private keys MUST be zeroized after use
- Random Number Quality: Use cryptographically secure PRNGs
- Side-Channel Resistance: Consider timing and power analysis attacks
10.3 Execution Environment¶
Package launchers execute in potentially hostile environments:
- Privilege Isolation: Run with minimal required privileges
- Temporary File Security: Secure workenv creation and cleanup
- Signal Handling: Graceful cleanup on interruption
- Resource Limits: Prevent unbounded resource consumption
10.4 Supply Chain Security¶
PSPF/2025 supports supply chain security through:
- Reproducible Builds: Deterministic package generation
- Build Attestation: Signed build metadata and provenance
- Dependency Tracking: Cryptographic dependency manifests
- Source Code Integrity: Source tree hash verification
11. IANA Considerations¶
11.1 Operation Code Registry¶
This document establishes the PSPF Operation Code Registry managed by IANA. The registry contains 256 8-bit operation codes organized into categories.
Registry Structure:
- Operation Code: 8-bit value (0x00-0xFF)
- Category: Functional grouping
- Name: Human-readable identifier
- Specification: Reference to defining document
- Status: Required, Optional, or Reserved
Allocation Policy: - Standards Action: Required operations (0x00-0x7F) - Specification Required: Optional operations (0x80-0xEF) - Private Use: Implementation-specific (0xF0-0xFE) - Reserved: Future specification use (0xFF)
11.2 Media Type Registration¶
Type name: application Subtype name: pspf Required parameters: version Optional parameters: charset (for metadata) Encoding considerations: binary Security considerations: See Section 10 Interoperability considerations: Cross-language compatibility required Published specification: This document Applications: Software packaging and distribution Fragment identifier considerations: Not applicable Additional information: - Magic number: 0xF0 0x9F 0x93 0xA6 (📦 emoji) - File extension: .psp - Person/organization: [Contact Information]
11.3 Port Number Registration¶
PSPF/2025 does not require dedicated port numbers as it operates on files rather than network protocols.
12. Examples and Test Vectors¶
12.1 Minimal Package Example¶
This section provides a complete minimal package for testing implementations:
Input Files:
Package Configuration: - Launcher: Generic x86_64 Linux launcher (8192 bytes) - Operations: Raw (no compression) - Signature: Ed25519 with test key pair
Test Key Pair (for testing only):
Private Key (hex):
9d61b19deffd5e56c2d6b61b1fb2c6c5b7e7e1e5a2a9b5e0e9f5e5f5a5a5a5a5
Public Key (hex):
d75a9801426b7e3e80f2a9f4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4
Expected Package Structure (hex dump):
Offset Content Description
0000 7f 45 4c 46 02 01 01 00 ... Launcher binary (8192 bytes)
2000 7b 22 66 6f 72 6d 61 74 ... JSON metadata (compressed)
2100 00 00 00 00 48 65 6c 6c ... Slot 0: "Hello, PSPF!\n"
210e f0 9f 93 a6 ... Start magic + index block
4000 f0 9f aa 84 End magic
12.2 Complex Package Example¶
Multi-slot package with compression:
Input Structure:
app/
├── bin/myapp (executable, 1MB)
├── lib/runtime.so (library, 2MB)
└── config/app.yaml (config, 1KB)
Slot Configuration:
Slot 0: bin/myapp → TAR+GZIP → 300KB
Slot 1: lib/runtime.so → TAR+ZSTD → 400KB
Slot 2: config/app.yaml → GZIP → 500B
Expected Operation Chains:
Slot 0: 0x0000000000001001 (TAR|GZIP)
Slot 1: 0x0000000000001B01 (TAR|ZSTD)
Slot 2: 0x0000000000000010 (GZIP)
12.3 Cryptographic Test Vectors¶
Signature Test Case:
Input package (without signature):
Package data: [complete package with signature field zeroed]
Private key: 9d61b19deffd5e56c2d6b61b1fb2c6c5b7e7e1e5a2a9b5e0e9f5e5f5a5a5a5a5
Expected Ed25519 signature:
Signature: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
Checksum Test Cases:
Adler-32 checksums for common data:
Input: "" → Checksum: 0x00000001
Input: "a" → Checksum: 0x00620062
Input: "Hello, PSPF!\n" → Checksum: 0x1a0b039e
Input: [1024 zero bytes] → Checksum: 0x04000001
13. References¶
13.1 Normative References¶
RFC2119 Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
RFC8174 Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, May 2017.
[RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, January 2017.
[RFC1952] Deutsch, P., "GZIP file format specification version 4.3", RFC 1952, May 1996.
[FIPS180-4] National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, August 2015.
13.2 Informative References¶
[TAR] POSIX.1-2008, "pax - portable archive interchange", IEEE Std 1003.1-2008, 2008.
[BZIP2] Seward, J., "bzip2 and libbzip2", https://sourceware.org/bzip2/
[XZ] Collin, L., "XZ Utils", https://tukaani.org/xz/
[ZSTD] Collet, Y., "Zstandard Compression Algorithm", RFC 8878, February 2021.
[FEP-0002] "PSPF/2025 JSON Metadata Format Specification", FEP-0002, January 2025.
[FEP-0003] "PSPF/2025 Operation Registry and Allocation Policy", FEP-0003, January 2025.
Authors' Addresses
[Author contact information would go here]
Copyright Notice
Copyright © 2025 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents in effect on the date of publication of this document.