Private/Crypto/Protect-SecretSharingMasterSecret.ps1

function Protect-SecretSharingMasterSecret {
    <#
    .SYNOPSIS
        Encrypts a master secret using the SLIP-0039 4-round Feistel cipher.
    .DESCRIPTION
        Splits MasterSecret into equal left/right halves and runs 4 forward Feistel
        rounds keyed by Passphrase, Identifier, and IterationExponent, per SLIP-0039.
        An empty Passphrase is a valid input - per spec, there is deliberately no way to
        verify a passphrase was "correct," which enables plausible deniability.
    #>

    [CmdletBinding()]
    [OutputType([byte[]], [System.Object[]])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory computation; no external state is changed.')]
    param(
        [Parameter(Mandatory)]
        [byte[]]$MasterSecret,

        [byte[]]$Passphrase = @(),

        [Parameter(Mandatory)]
        [ValidateRange(0, 32767)]
        [int]$Identifier,

        [Parameter(Mandatory)]
        [ValidateRange(0, 15)]
        [int]$IterationExponent,

        [switch]$Extendable
    )

    $constant = Get-SecretSharingCipherConstant
    if ($MasterSecret.Length -lt $constant.MinimumSecretLength -or ($MasterSecret.Length % 2) -ne 0) {
        throw "MasterSecret must be an even number of bytes, at least $($constant.MinimumSecretLength)."
    }

    $saltPrefix = Get-SecretSharingCipherSaltPrefix -Identifier $Identifier -Extendable:$Extendable

    $half = [int]($MasterSecret.Length / 2)
    $l = [byte[]]$MasterSecret[0..($half - 1)]
    $r = [byte[]]$MasterSecret[$half..($MasterSecret.Length - 1)]

    for ($i = 0; $i -lt $constant.RoundCount; $i++) {
        $f = Invoke-SecretSharingCipherRoundFunction -RoundIndex ([byte]$i) -Passphrase $Passphrase -SaltPrefix $saltPrefix -R $r -IterationExponent $IterationExponent

        $newR = [byte[]]::new($half)
        for ($b = 0; $b -lt $half; $b++) {
            $newR[$b] = $l[$b] -bxor $f[$b]
        }

        $l = $r
        $r = $newR
    }

    return , ([byte[]]($r + $l))
}