Skip to content

Obfuscated 2.0.0

Choose a tag to compare

@tomisacat tomisacat released this 14 Jun 07:37
· 2 commits to main since this release

Obfuscated 2.0.0

Obfuscated 2.0.0 adds user-defined obfuscation steps, extracts shared macro infrastructure into ObfuscatedMacroSupport, and publishes ObfuscatedCore as a standalone product. Built-in #Obfuscated usage is unchanged for typical apps; this is a major release because public enums and CryptoMaterial gained new cases and fields.

Requirements

  • macOS 15+, iOS 14+, tvOS 14+, watchOS 7+, macCatalyst 14+
  • Swift 6.2+
  • Xcode 16+ (macro plugin support)

Installation

Add Obfuscated via Swift Package Manager:

dependencies: [
    .package(url: "https://github.com/tomisacat/Obfuscated.git", from: "2.0.0"),
],
targets: [
    .target(
        name: "<YourAppTarget>",
        dependencies: ["Obfuscated"]
    ),
]

For an Xcode app target, use File → Add Package Dependencies and enter https://github.com/tomisacat/Obfuscated.git.

Products

Product Use when
Obfuscated Default — built-in methods only; #Obfuscated via ObfuscatedMacros
ObfuscatedCore Direct pipeline access, tests, or custom step libraries
ObfuscatedMacroSupport Building a user-owned macro plugin with custom ObfuscationStep types

Highlights

Custom obfuscation steps

Define your own transforms with the ObfuscationStep protocol and use them in #Obfuscated via .custom(id:parameters:):

let secret = #Obfuscated(
    "Custom protected secret",
    methods: [.custom(id: "rot13", parameters: ObfuscationParameters(bytes: [13]))]
)

Custom steps require a user-owned macro plugin target that links ObfuscatedMacroSupport and registers step types before expansion. Macro expansion runs in a plugin process that cannot import your app module.

Full setup guide: docs/CUSTOM_OBFUSCATION_STEPS.md

Working example in this repo: Demo/ObfuscatedDemoSupport (ObfuscatedDemoKit + ObfuscatedDemoMacros + DemoRot13Step).

ObfuscatedMacroSupport extraction

Macro parsing, expansion building, and ObfuscatedMacro now live in the ObfuscatedMacroSupport library. ObfuscatedMacros is a thin default compiler plugin (built-in methods only). Advanced users link ObfuscatedMacroSupport when building custom plugins.

New public types

Type Role
ObfuscationStep Protocol for user-defined encode/decode transforms
ObfuscationParameters Literal byte parameters embedded in macro expansions
ObfuscationStepRegistry Registers custom steps for pipeline + macro encode
CustomMaterialEntry Per-step persisted state in CryptoMaterial
ObfuscationMacroConfiguration Plugin init hook to run step registration

Re-exported from Obfuscated alongside existing ObfuscationMethod, ObfuscatedKey, etc.

Demo package

The demo app's custom-step wiring moved out of the root package into a local SPM package at Demo/ObfuscatedDemoSupport/. The Xcode demo imports ObfuscatedDemoKit from that package instead of depending on the root Obfuscated product directly.

Breaking changes (from 1.0.0)

ObfuscationMethod — new case

case custom(id: String, parameters: ObfuscationParameters)

Impact: Exhaustive switch statements over ObfuscationMethod must handle .custom or add @unknown default.

No impact for typical usage: #Obfuscated("...", methods: [.xor(key: 0x5A), .base64]) with built-in method literals.

ObfuscationError — new cases

  • unknownCustomStep(String)
  • missingCustomMaterial

Impact: Exhaustive switch statements over ObfuscationError must handle the new cases.

No impact for typical #Obfuscated callers — ObfuscatedRuntime._decode catches errors internally.

CryptoMaterial — new field

public var customEntries: [CustomMaterialEntry]
public init(entries: [CryptoEntry] = [], customEntries: [CustomMaterialEntry] = [])

Impact: Code that pattern-matches CryptoMaterial exhaustively or assumes a fixed shape may need updates.

No impact for CryptoMaterial(entries: [...]) call sites — customEntries defaults to [].

Macro module layout

Macro implementation code moved from ObfuscatedMacros to ObfuscatedMacroSupport. The default #Obfuscated declaration still points at ObfuscatedMacros.ObfuscatedMacro.

Impact: Projects that imported or @testable imported ObfuscatedMacros internals directly must migrate to ObfuscatedMacroSupport.

No impact for import Obfuscated consumers.

Migration from 1.0.0

  1. Typical app (built-in methods only) — bump the dependency and rebuild:

    .package(url: "https://github.com/tomisacat/Obfuscated.git", from: "2.0.0")

    No source changes expected.

  2. Exhaustive enum switches — add cases for .custom, unknownCustomStep, and missingCustomMaterial, or use @unknown default.

  3. Custom steps (new in 2.0) — follow CUSTOM_OBFUSCATION_STEPS.md:

    • Implement ObfuscationStep
    • Add a .macro target with ObfuscatedMacroSupport
    • Register steps in the plugin init and at app launch for runtime decode
    • Point #Obfuscated at your plugin with #externalMacro
  4. Pin to 1.0.0 if you are not ready to upgrade:

    .package(url: "https://github.com/tomisacat/Obfuscated.git", exact: "1.0.0")

Unchanged from 1.0.0

  • #Obfuscated macro signature and default plugin module (ObfuscatedMacros)
  • All built-in obfuscation methods (XOR, bit shift, bit OR, Base64, AES-GCM, ChaCha, HMAC, HKDF, ECIES)
  • Static string interpolation (\("...") literals folded at compile time)
  • ObfuscatedRuntime._decode(bytes:methods:material:) entry point
  • Platform and Swift version requirements

Documentation

Testing

48 unit tests cover encode/decode round-trips, built-in and custom step pipelines, macro parsing, and expansion. CI runs swift test and demo app builds on every push and pull request to main.

License

MIT License — see LICENSE.


Tag: 2.0.0