Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

CAST-128 Encryption for 3.0/7.0

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • CAST-128 Encryption for 3.0/7.0

    Code:
    #IF 0 
    =====================================================================
                            CAST-128 Encryption
    =====================================================================
       
    The CAST-128 encryption algorithm (also known as CAST5) is patented by 
    Entrust Technologies, which makes it freely available for both 
    commercial and non-commercial use.  Information about the algorithm is 
    available from Entrust at: 
     http://www.ietf.org/rfc/rfc2144.txt 
       
    The PowerBASIC implementation appearing here is based on RFC2144 and 
    is hereby placed in the public domain.  Use it as you wish.  My hope 
    is discourage reliance on home-grown encryption schemes in favor of 
    well-examined, strong, freely available algorithms. 
       
    In this posting, test-bed code appears below the CAST-128.BAS file 
    contents.  All code requires compiler releases 3.0/7.0 or later.
       
       
    <U>Implementation Notes</U>
    -- The algorithm operates on plaintext blocks of 8 bytes.  Encryption 
    of shorter blocks is possible only by padding the plaintext (usually 
    with zero bytes), which can be accomplished through several methods.  
    The simplest of them assumes that the final byte of plaintext always 
    identifies the number of bytes of padding added, including the final 
    byte itself. 
       
    Examples: 
       total plaintext bytes         = 30
       plaintext blocks encrypted:   = 4
       final block                   = chr$(x1 to x6) + chr$(0,2)
       
       total plaintext bytes         = 40
       plaintext blocks encrypted:   = 6
       final block                   = chr$(0,0,0,0,0,0,0,8)
       
    -- Encryption key lengths can range from 5 to 16 bytes.  Keys shorter 
    than 16 bytes are padded to 16 by appending zero bytes.  For original 
    key lengths shorter than 11 bytes (88 bits), the number of rounds of 
    encryption is shortened from 16 to 12.  This procedure follows the 
    specifications of RFC2144. 
       
    -- Implementation here is handled through an #INCLUDE file.  No global 
    data is employed.  
       
    -- As presented, the code does not supply a ready-to-use encryption 
    application.  It offers necessary pieces only, as well as an 
    illustration of their use.  Always keep in mind that most encryption 
    is broken because of implementation flaws and weaknesses.
       
    -- Like most encryption algorithms, CAST-128 was designed on big-endian
    systems.  For this reason, little-endian systems return correct test 
    vector results only through considerable byte-swapping, with efficiency 
    suffering as a result.  Because it adds nothing to the encryption 
    security, an efficient implementation should avoid the byte-swapping.
    (My own preference: #IF def%(%VERIFY_IMPLEMENTATION)...)
       
    -- Because of its internal methods of data handling, PowerBASIC's 
    DWORDs cannot be used efficiently with most encryption and hashing 
    algorithms.  Long integers should be used instead, as they are here.  
    Use of longs& assures correct bit-level results (as well as additional 
    speed). 
       
    -- The large group of s-box constants which appears at the end of the 
    #INCLUDE file is required and must not be altered. 
       
    -- Greg Turgeon 06/2002
       
    =====================================================================
    #ENDIF
       
    '=====================================================================
    '                           CAST-128.BAS
    '=====================================================================
       
    %BLOCKSIZE      = 8
    %KEY_SIZE       = 16
    %SUBKEY_SIZE    = 16*2
    %MIN_KEY_SIZE   = 5
    %MAX_KEY_SIZE   = 16
    %DEFAULT_ROUNDS = 16
    %SHORT_ROUNDS   = 12
       
    '-- Note: Strings (UserKey, etc) are processed as 
    '   four-byte sequences, so LONG PTRs required
    TYPE ENCRYPTION_CONTEXT
    Rounds         AS LONG
    S_Box          AS LONG PTR
    UserKeyLength  AS LONG
    UserKey        AS LONG PTR
    InBlock        AS LONG PTR
    OutBlock       AS LONG PTR
    K              AS LONG PTR                  '<-- pointer to subkey buffer
    K_Buffer       AS STRING * (%SUBKEY_SIZE*4) '<-- subkey buffer itself
    END TYPE
       
    DECLARE SUB CAST128_Init(Ctx AS ENCRYPTION_CONTEXT)
    DECLARE FUNCTION Set_Key&(Ctx AS ENCRYPTION_CONTEXT)
    DECLARE FUNCTION EncryptBlock&(Ctx AS ENCRYPTION_CONTEXT)
    DECLARE FUNCTION DecryptBlock&(Ctx AS ENCRYPTION_CONTEXT)
       
    '--------------------
    MACRO zbs(x) = string$(x,0)
       
    '--------------------
    MACRO FUNCTION byte_reverse(x)
    !  mov   eax, x
    !  bswap eax
    !  mov   x, eax
    END MACRO = x
       
       
    '--------------------
    MACRO get_keyblock(mem_ptr,kdata)
    !  mov   edx, mem_ptr
    !  mov   eax, [edx]
    !  bswap eax
    !  mov   kdata, eax
    !  add   edx, 4
    !  mov   mem_ptr, edx
    END MACRO
       
    '--------------------
    MACRO FUNCTION getbyte(x,idx)
    retval = x
    !  shr   retval, idx*8
    END MACRO = (retval AND &HFF)
       
    '--------------------
    MACRO unpack_bytes(value,byte1,byte2,byte3,byte4)
    byte1=getbyte(value,3)
    byte2=getbyte(value,2)
    byte3=getbyte(value,1)
    byte4=getbyte(value,0)
    END MACRO
       
       
    '====================
    FUNCTION Set_Key&(Ctx AS ENCRYPTION_CONTEXT)
    LOCAL x0x1x2x3&, x4x5x6x7&, x8x9xAxB&, xCxDxExF&
    LOCAL z0z1z2z3&, z4z5z6z7&, z8z9zAzB&, zCzDzEzF&
    LOCAL x0&, x1&, x2&, x3&, x4&, x5&, x6&, x7&, x8&, x9&, xA&, xB&, xC&, xD&, xE&, xF&
    LOCAL z0&, z1&, z2&, z3&, z4&, z5&, z6&, z7&, z8&, z9&, zA&, zB&, zC&, zD&, zE&, zF&
    LOCAL s5 AS LONG PTR, s6 AS LONG PTR, s7 AS LONG PTR, s8 AS LONG PTR
    LOCAL k AS LONG PTR  ' temp copy
    LOCAL retval&        ' for macro use
       
    '-- Verify key length & abort if out of range
    if (Ctx.UserkeyLength < %MIN_KEY_SIZE) OR (Ctx.UserkeyLength > %MAX_KEY_SIZE) then
       function = 0 : exit function
    end if
       
    '-- Verify that CAST128_Init has been called
    if Ctx.S_BOX = 0 then
       function = 0 : exit function
    end if
       
    Ctx.Rounds = %DEFAULT_ROUNDS
    if (Ctx.UserKeyLength) < %KEY_SIZE then
       '-- Pad to default %KEY_SIZE:
       '   Make copy of original UserKey & add padding
       LOCAL keybuff$
       keybuff$ = peek$(Ctx.UserKey, Ctx.UserKeyLength) + zbs(%KEY_SIZE - Ctx.UserKeyLength)
       '  Burn original UserKey
       poke$ Ctx.UserKey, zbs(Ctx.UserKeyLength)
       '  Point to new UserKey 
       Ctx.UserKey = strptr(keybuff$)
       '  Adjust rounds if necessary
       if Ctx.UserKeyLength < 11 then Ctx.Rounds = %SHORT_ROUNDS
       Ctx.UserKeyLength = %KEY_SIZE
    end if
       
    '-- Load pointers to keygen s-boxes
    s5 = Ctx.S_BOX+(256*4*4) : s6 = s5+(256*4) : s7 = s6+(256*4) : s8 = s7+(256*4)
       
    k = Ctx.UserKey   'local copy for macro use & to reduce overhead
       
    get_keyblock(k,x0x1x2x3) : unpack_bytes(x0x1x2x3,x0,x1,x2,x3)
    get_keyblock(k,x4x5x6x7) : unpack_bytes(x4x5x6x7,x4,x5,x6,x7)
    get_keyblock(k,x8x9xAxB) : unpack_bytes(x8x9xAxB,x8,x9,xA,xB)
    get_keyblock(k,xCxDxExF) : unpack_bytes(xCxDxExF,xC,xD,xE,xF)
       
    k = Ctx.K         'point now to subkey buffer
    poke$ k, zbs(sizeof(Ctx.K_Buffer)) 'and clear any previous key data
       
    z0z1z2z3 = x0x1x2x3 XOR @s5[xD] XOR @s6[xF] XOR @s7[xC] XOR @s8[xE] XOR @s7[x8]
    unpack_bytes(z0z1z2z3,z0,z1,z2,z3)
    z4z5z6z7 = x8x9xAxB XOR @s5[z0] XOR @s6[z2] XOR @s7[z1] XOR @s8[z3] XOR @s8[xA]
    unpack_bytes(z4z5z6z7,z4,z5,z6,z7)
    z8z9zAzB = xCxDxExF XOR @s5[z7] XOR @s6[z6] XOR @s7[z5] XOR @s8[z4] XOR @s5[x9]
    unpack_bytes(z8z9zAzB,z8,z9,zA,zB)
    zCzDzEzF = x4x5x6x7 XOR @s5[zA] XOR @s6[z9] XOR @s7[zB] XOR @s8[z8] XOR @s6[xB]
    unpack_bytes(zCzDzEzF,zC,zD,zE,zF)
    @k[0]  = @s5[z8] XOR @s6[z9] XOR @s7[z7] XOR @s8[z6] XOR @s5[z2]
    @k[1]  = @s5[zA] XOR @s6[zB] XOR @s7[z5] XOR @s8[z4] XOR @s6[z6]
    @k[2]  = @s5[zC] XOR @s6[zD] XOR @s7[z3] XOR @s8[z2] XOR @s7[z9]
    @k[3]  = @s5[zE] XOR @s6[zF] XOR @s7[z1] XOR @s8[z0] XOR @s8[zC]
       
    x0x1x2x3 = z8z9zAzB XOR @s5[z5] XOR @s6[z7] XOR @s7[z4] XOR @s8[z6] XOR @s7[z0]
    unpack_bytes(x0x1x2x3,x0,x1,x2,x3)
    x4x5x6x7 = z0z1z2z3 XOR @s5[x0] XOR @s6[x2] XOR @s7[x1] XOR @s8[x3] XOR @s8[z2]
    unpack_bytes(x4x5x6x7,x4,x5,x6,x7)
    x8x9xAxB = z4z5z6z7 XOR @s5[x7] XOR @s6[x6] XOR @s7[x5] XOR @s8[x4] XOR @s5[z1]
    unpack_bytes(x8x9xAxB,x8,x9,xA,xB)
    xCxDxExF = zCzDzEzF XOR @s5[xA] XOR @s6[x9] XOR @s7[xB] XOR @s8[x8] XOR @s6[z3]
    unpack_bytes(xCxDxExF,xC,xD,xE,xF)
    @k[4]  = @s5[x3] XOR @s6[x2] XOR @s7[xC] XOR @s8[xD] XOR @s5[x8]
    @k[5]  = @s5[x1] XOR @s6[x0] XOR @s7[xE] XOR @s8[xF] XOR @s6[xD]
    @k[6]  = @s5[x7] XOR @s6[x6] XOR @s7[x8] XOR @s8[x9] XOR @s7[x3]
    @k[7]  = @s5[x5] XOR @s6[x4] XOR @s7[xA] XOR @s8[xB] XOR @s8[x7]
       
    z0z1z2z3 = x0x1x2x3 XOR @s5[xD] XOR @s6[xF] XOR @s7[xC] XOR @s8[xE] XOR @s7[x8]
    unpack_bytes(z0z1z2z3,z0,z1,z2,z3)
    z4z5z6z7 = x8x9xAxB XOR @s5[z0] XOR @s6[z2] XOR @s7[z1] XOR @s8[z3] XOR @s8[xA]
    unpack_bytes(z4z5z6z7,z4,z5,z6,z7)
    z8z9zAzB = xCxDxExF XOR @s5[z7] XOR @s6[z6] XOR @s7[z5] XOR @s8[z4] XOR @s5[x9]
    unpack_bytes(z8z9zAzB,z8,z9,zA,zB)
    zCzDzEzF = x4x5x6x7 XOR @s5[zA] XOR @s6[z9] XOR @s7[zB] XOR @s8[z8] XOR @s6[xB]
    unpack_bytes(zCzDzEzF,zC,zD,zE,zF)
    @k[8]  = @s5[z3] XOR @s6[z2] XOR @s7[zC] XOR @s8[zD] XOR @s5[z9]
    @k[9]  = @s5[z1] XOR @s6[z0] XOR @s7[zE] XOR @s8[zF] XOR @s6[zC]
    @k[10] = @s5[z7] XOR @s6[z6] XOR @s7[z8] XOR @s8[z9] XOR @s7[z2]
    @k[11] = @s5[z5] XOR @s6[z4] XOR @s7[zA] XOR @s8[zB] XOR @s8[z6]
       
    x0x1x2x3 = z8z9zAzB XOR @s5[z5] XOR @s6[z7] XOR @s7[z4] XOR @s8[z6] XOR @s7[z0]
    unpack_bytes(x0x1x2x3,x0,x1,x2,x3)
    x4x5x6x7 = z0z1z2z3 XOR @s5[x0] XOR @s6[x2] XOR @s7[x1] XOR @s8[x3] XOR @s8[z2]
    unpack_bytes(x4x5x6x7,x4,x5,x6,x7)
    x8x9xAxB = z4z5z6z7 XOR @s5[x7] XOR @s6[x6] XOR @s7[x5] XOR @s8[x4] XOR @s5[z1]
    unpack_bytes(x8x9xAxB,x8,x9,xA,xB)
    xCxDxExF = zCzDzEzF XOR @s5[xA] XOR @s6[x9] XOR @s7[xB] XOR @s8[x8] XOR @s6[z3]
    unpack_bytes(xCxDxExF,xC,xD,xE,xF)
    @k[12] = @s5[x8] XOR @s6[x9] XOR @s7[x7] XOR @s8[x6] XOR @s5[x3]
    @k[13] = @s5[xA] XOR @s6[xB] XOR @s7[x5] XOR @s8[x4] XOR @s6[x7]
    @k[14] = @s5[xC] XOR @s6[xD] XOR @s7[x3] XOR @s8[x2] XOR @s7[x8]
    @k[15] = @s5[xE] XOR @s6[xF] XOR @s7[x1] XOR @s8[x0] XOR @s8[xD]
       
    z0z1z2z3 = x0x1x2x3 XOR @s5[xD] XOR @s6[xF] XOR @s7[xC] XOR @s8[xE] XOR @s7[x8]
    unpack_bytes(z0z1z2z3,z0,z1,z2,z3)
    z4z5z6z7 = x8x9xAxB XOR @s5[z0] XOR @s6[z2] XOR @s7[z1] XOR @s8[z3] XOR @s8[xA]
    unpack_bytes(z4z5z6z7,z4,z5,z6,z7)
    z8z9zAzB = xCxDxExF XOR @s5[z7] XOR @s6[z6] XOR @s7[z5] XOR @s8[z4] XOR @s5[x9]
    unpack_bytes(z8z9zAzB,z8,z9,zA,zB)
    zCzDzEzF = x4x5x6x7 XOR @s5[zA] XOR @s6[z9] XOR @s7[zB] XOR @s8[z8] XOR @s6[xB]
    unpack_bytes(zCzDzEzF,zC,zD,zE,zF)
    @k[16] = (@s5[z8] XOR @s6[z9] XOR @s7[z7] XOR @s8[z6] XOR @s5[z2]) AND &h1f
    @k[17] = (@s5[zA] XOR @s6[zB] XOR @s7[z5] XOR @s8[z4] XOR @s6[z6]) AND &h1f
    @k[18] = (@s5[zC] XOR @s6[zD] XOR @s7[z3] XOR @s8[z2] XOR @s7[z9]) AND &h1f
    @k[19] = (@s5[zE] XOR @s6[zF] XOR @s7[z1] XOR @s8[z0] XOR @s8[zC]) AND &h1f
       
    x0x1x2x3 = z8z9zAzB XOR @s5[z5] XOR @s6[z7] XOR @s7[z4] XOR @s8[z6] XOR @s7[z0]
    unpack_bytes(x0x1x2x3,x0,x1,x2,x3)
    x4x5x6x7 = z0z1z2z3 XOR @s5[x0] XOR @s6[x2] XOR @s7[x1] XOR @s8[x3] XOR @s8[z2]
    unpack_bytes(x4x5x6x7,x4,x5,x6,x7)
    x8x9xAxB = z4z5z6z7 XOR @s5[x7] XOR @s6[x6] XOR @s7[x5] XOR @s8[x4] XOR @s5[z1]
    unpack_bytes(x8x9xAxB,x8,x9,xA,xB)
    xCxDxExF = zCzDzEzF XOR @s5[xA] XOR @s6[x9] XOR @s7[xB] XOR @s8[x8] XOR @s6[z3]
    unpack_bytes(xCxDxExF,xC,xD,xE,xF)
    @k[20] = (@s5[x3] XOR @s6[x2] XOR @s7[xC] XOR @s8[xD] XOR @s5[x8]) AND &h1f
    @k[21] = (@s5[x1] XOR @s6[x0] XOR @s7[xE] XOR @s8[xF] XOR @s6[xD]) AND &h1f
    @k[22] = (@s5[x7] XOR @s6[x6] XOR @s7[x8] XOR @s8[x9] XOR @s7[x3]) AND &h1f
    @k[23] = (@s5[x5] XOR @s6[x4] XOR @s7[xA] XOR @s8[xB] XOR @s8[x7]) AND &h1f
       
    z0z1z2z3 = x0x1x2x3 XOR @s5[xD] XOR @s6[xF] XOR @s7[xC] XOR @s8[xE] XOR @s7[x8]
    unpack_bytes(z0z1z2z3,z0,z1,z2,z3)
    z4z5z6z7 = x8x9xAxB XOR @s5[z0] XOR @s6[z2] XOR @s7[z1] XOR @s8[z3] XOR @s8[xA]
    unpack_bytes(z4z5z6z7,z4,z5,z6,z7)
    z8z9zAzB = xCxDxExF XOR @s5[z7] XOR @s6[z6] XOR @s7[z5] XOR @s8[z4] XOR @s5[x9]
    unpack_bytes(z8z9zAzB,z8,z9,zA,zB)
    zCzDzEzF = x4x5x6x7 XOR @s5[zA] XOR @s6[z9] XOR @s7[zB] XOR @s8[z8] XOR @s6[xB]
    unpack_bytes(zCzDzEzF,zC,zD,zE,zF)
    @k[24] = (@s5[z3] XOR @s6[z2] XOR @s7[zC] XOR @s8[zD] XOR @s5[z9]) AND &h1f
    @k[25] = (@s5[z1] XOR @s6[z0] XOR @s7[zE] XOR @s8[zF] XOR @s6[zC]) AND &h1f
    @k[26] = (@s5[z7] XOR @s6[z6] XOR @s7[z8] XOR @s8[z9] XOR @s7[z2]) AND &h1f
    @k[27] = (@s5[z5] XOR @s6[z4] XOR @s7[zA] XOR @s8[zB] XOR @s8[z6]) AND &h1f
       
    x0x1x2x3 = z8z9zAzB XOR @s5[z5] XOR @s6[z7] XOR @s7[z4] XOR @s8[z6] XOR @s7[z0]
    unpack_bytes(x0x1x2x3,x0,x1,x2,x3)
    x4x5x6x7 = z0z1z2z3 XOR @s5[x0] XOR @s6[x2] XOR @s7[x1] XOR @s8[x3] XOR @s8[z2]
    unpack_bytes(x4x5x6x7,x4,x5,x6,x7)
    x8x9xAxB = z4z5z6z7 XOR @s5[x7] XOR @s6[x6] XOR @s7[x5] XOR @s8[x4] XOR @s5[z1]
    unpack_bytes(x8x9xAxB,x8,x9,xA,xB)
    xCxDxExF = zCzDzEzF XOR @s5[xA] XOR @s6[x9] XOR @s7[xB] XOR @s8[x8] XOR @s6[z3]
    unpack_bytes(xCxDxExF,xC,xD,xE,xF)
    @k[28] = (@s5[x8] XOR @s6[x9] XOR @s7[x7] XOR @s8[x6] XOR @s5[x3]) AND &h1f
    @k[29] = (@s5[xA] XOR @s6[xB] XOR @s7[x5] XOR @s8[x4] XOR @s6[x7]) AND &h1f
    @k[30] = (@s5[xC] XOR @s6[xD] XOR @s7[x3] XOR @s8[x2] XOR @s7[x8]) AND &h1f
    @k[31] = (@s5[xE] XOR @s6[xF] XOR @s7[x1] XOR @s8[x0] XOR @s8[xD]) AND &h1f
       
    '-- Burn the UserKey
    poke$ Ctx.UserKey, zbs(Ctx.UserKeyLength)
    function = -1  ' True on success
    END FUNCTION
       
       
    '--------------------
    MACRO f1(out_put,in_put,i)
    t =       (@k[i] + in_put)
    u =        @k[i+16]
    ! mov      ecx, u
    ! rol      t, cl
    u =        @s_box[(0*256)+getbyte(t,3)]
    u = (u XOR @s_box[(1*256)+getbyte(t,2)])
    u = (u  -  @s_box[(2*256)+getbyte(t,1)])
    u = (u  +  @s_box[(3*256)+getbyte(t,0)])
    out_put = (out_put XOR u)
    END MACRO
       
    '--------------------
    MACRO f2(out_put,in_put,i)
    t =       (@k[i] XOR in_put)
    u =        @k[i+16]
    ! mov      ecx, u
    ! rol      t, cl
    u =        @s_box[(0*256)+getbyte(t,3)]
    u = (u  -  @s_box[(1*256)+getbyte(t,2)])
    u = (u  +  @s_box[(2*256)+getbyte(t,1)])
    u = (u XOR @s_box[(3*256)+getbyte(t,0)])
    out_put = (out_put XOR u)
    END MACRO
       
    '--------------------
    MACRO f3(out_put,in_put,i)
    t =       (@k[i] - in_put)
    u =        @k[i+16]
    ! mov      ecx, u
    ! rol      t, cl
    u =        @s_box[(0*256)+getbyte(t,3)]
    u = (u  +  @s_box[(1*256)+getbyte(t,2)])
    u = (u XOR @s_box[(2*256)+getbyte(t,1)])
    u = (u  -  @s_box[(3*256)+getbyte(t,0)])
    out_put = (out_put XOR u)
    END MACRO
       
       
    '====================
    FUNCTION EncryptBlock&(Ctx AS ENCRYPTION_CONTEXT)
    LOCAL t&, u&, l&, r&, k AS LONG PTR, s_box AS LONG PTR
    LOCAL retval&  ' for macro use
    t = Ctx.@InBlock[0] : l = byte_reverse(t)
    t = Ctx.@InBlock[1] : r = byte_reverse(t)
       
    '-- Local copies
    k = Ctx.K : s_box = Ctx.S_Box
       
    f1(l,r,0)  : f2(r,l,1)  : f3(l,r,2)
    f1(r,l,3)  : f2(l,r,4)  : f3(r,l,5)
    f1(l,r,6)  : f2(r,l,7)  : f3(l,r,8)
    f1(r,l,9)  : f2(l,r,10) : f3(r,l,11)
    if Ctx.Rounds = %DEFAULT_ROUNDS then
       '-- Only if key length > 80 bits
       f1(l,r,12) : f2(r,l,13) : f3(l,r,14) : f1(r,l,15)
    end if
       
    Ctx.@OutBlock[0] = byte_reverse(r)
    Ctx.@OutBlock[1] = byte_reverse(l)
    END FUNCTION
       
    '====================
    FUNCTION DecryptBlock&(Ctx AS ENCRYPTION_CONTEXT)
    LOCAL t&, u&, l&, r&, k AS LONG PTR, s_box AS LONG PTR
    LOCAL retval&  ' for macro use
       
    t = Ctx.@InBlock[0] : l = byte_reverse(t)
    t = Ctx.@InBlock[1] : r = byte_reverse(t)
       
    '-- Local copies
    k = Ctx.K : s_box = Ctx.S_Box
       
    if Ctx.Rounds = %DEFAULT_ROUNDS then
       '-- Only if key length > 80 bits
       f1(l,r,15) : f3(r,l,14) : f2(l,r,13) : f1(r,l,12)
    end if
    f3(l,r,11) : f2(r,l,10) : f1(l,r,9)
    f3(r,l,8)  : f2(l,r,7)  : f1(r,l,6)
    f3(l,r,5)  : f2(r,l,4)  : f1(l,r,3)
    f3(r,l,2)  : f2(l,r,1)  : f1(r,l,0)
       
    Ctx.@OutBlock[0] = byte_reverse(r)
    Ctx.@OutBlock[1] = byte_reverse(l)
    END FUNCTION
       
       
    '====================
    SUB CAST128_Init(Ctx AS ENCRYPTION_CONTEXT)
    Ctx.K_Buffer = zbs(%SUBKEY_SIZE*4)
    Ctx.K        = varptr(Ctx.K_Buffer)
    Ctx.S_Box    = codeptr(S_BOX1)
    exit sub
       
    '-- CAST s-boxes
    S_BOX1:
    ! DD  &h30FB40D4, &h9FA0FF0B, &h6BECCD2F, &h3F258C7A, &h1E213F2F, &h9C004DD3, &h6003E540, &hCF9FC949
    ! DD  &hBFD4AF27, &h88BBBDB5, &hE2034090, &h98D09675, &h6E63A0E0, &h15C361D2, &hC2E7661D, &h22D4FF8E
    ! DD  &h28683B6F, &hC07FD059, &hFF2379C8, &h775F50E2, &h43C340D3, &hDF2F8656, &h887CA41A, &hA2D2BD2D
    ! DD  &hA1C9E0D6, &h346C4819, &h61B76D87, &h22540F2F, &h2ABE32E1, &hAA54166B, &h22568E3A, &hA2D341D0
    ! DD  &h66DB40C8, &hA784392F, &h004DFF2F, &h2DB9D2DE, &h97943FAC, &h4A97C1D8, &h527644B7, &hB5F437A7
    ! DD  &hB82CBAEF, &hD751D159, &h6FF7F0ED, &h5A097A1F, &h827B68D0, &h90ECF52E, &h22B0C054, &hBC8E5935
    ! DD  &h4B6D2F7F, &h50BB64A2, &hD2664910, &hBEE5812D, &hB7332290, &hE93B159F, &hB48EE411, &h4BFF345D
    ! DD  &hFD45C240, &hAD31973F, &hC4F6D02E, &h55FC8165, &hD5B1CAAD, &hA1AC2DAE, &hA2D4B76D, &hC19B0C50
    ! DD  &h882240F2, &h0C6E4F38, &hA4E4BFD7, &h4F5BA272, &h564C1D2F, &hC59C5319, &hB949E354, &hB04669FE
    ! DD  &hB1B6AB8A, &hC71358DD, &h6385C545, &h110F935D, &h57538AD5, &h6A390493, &hE63D37E0, &h2A54F6B3
    ! DD  &h3A787D5F, &h6276A0B5, &h19A6FCDF, &h7A42206A, &h29F9D4D5, &hF61B1891, &hBB72275E, &hAA508167
    ! DD  &h38901091, &hC6B505EB, &h84C7CB8C, &h2AD75A0F, &h874A1427, &hA2D1936B, &h2AD286AF, &hAA56D291
    ! DD  &hD7894360, &h425C750D, &h93B39E26, &h187184C9, &h6C00B32D, &h73E2BB14, &hA0BEBC3C, &h54623779
    ! DD  &h64459EAB, &h3F328B82, &h7718CF82, &h59A2CEA6, &h04EE002E, &h89FE78E6, &h3FAB0950, &h325FF6C2
    ! DD  &h81383F05, &h6963C5C8, &h76CB5AD6, &hD49974C9, &hCA180DCF, &h380782D5, &hC7FA5CF6, &h8AC31511
    ! DD  &h35E79E13, &h47DA91D0, &hF40F9086, &hA7E2419E, &h31366241, &h051EF495, &hAA573B04, &h4A805D8D
    ! DD  &h548300D0, &h00322A3C, &hBF64CDDF, &hBA57A68E, &h75C6372B, &h50AFD341, &hA7C13275, &h915A0BF5
    ! DD  &h6B54BFAB, &h2B0B1426, &hAB4CC9D7, &h449CCD82, &hF7FBF265, &hAB85C5F3, &h1B55DB94, &hAAD4E324
    ! DD  &hCFA4BD3F, &h2DEAA3E2, &h9E204D02, &hC8BD25AC, &hEADF55B3, &hD5BD9E98, &hE31231B2, &h2AD5AD6C
    ! DD  &h954329DE, &hADBE4528, &hD8710F69, &hAA51C90F, &hAA786BF6, &h22513F1E, &hAA51A79B, &h2AD344CC
    ! DD  &h7B5A41F0, &hD37CFBAD, &h1B069505, &h41ECE491, &hB4C332E6, &h032268D4, &hC9600ACC, &hCE387E6D
    ! DD  &hBF6BB16C, &h6A70FB78, &h0D03D9C9, &hD4DF39DE, &hE01063DA, &h4736F464, &h5AD328D8, &hB347CC96
    ! DD  &h75BB0FC3, &h98511BFB, &h4FFBCC35, &hB58BCF6A, &hE11F0ABC, &hBFC5FE4A, &hA70AEC10, &hAC39570A
    ! DD  &h3F04442F, &h6188B153, &hE0397A2E, &h5727CB79, &h9CEB418F, &h1CACD68D, &h2AD37C96, &h0175CB9D
    ! DD  &hC69DFF09, &hC75B65F0, &hD9DB40D8, &hEC0E7779, &h4744EAD4, &hB11C3274, &hDD24CB9E, &h7E1C54BD
    ! DD  &hF01144F9, &hD2240EB1, &h9675B3FD, &hA3AC3755, &hD47C27AF, &h51C85F4D, &h56907596, &hA5BB15E6
    ! DD  &h580304F0, &hCA042CF1, &h011A37EA, &h8DBFAADB, &h35BA3E4A, &h3526FFA0, &hC37B4D09, &hBC306ED9
    ! DD  &h98A52666, &h5648F725, &hFF5E569D, &h0CED63D0, &h7C63B2CF, &h700B45E1, &hD5EA50F1, &h85A92872
    ! DD  &hAF1FBDA7, &hD4234870, &hA7870BF3, &h2D3B4D79, &h42E04198, &h0CD0EDE7, &h26470DB8, &hF881814C
    ! DD  &h474D6AD7, &h7C0C5E5C, &hD1231959, &h381B7298, &hF5D2F4DB, &hAB838653, &h6E2F1E23, &h83719C9E
    ! DD  &hBD91E046, &h9A56456E, &hDC39200C, &h20C8C571, &h962BDA1C, &hE1E696FF, &hB141AB08, &h7CCA89B9
    ! DD  &h1A69E783, &h02CC4843, &hA2F7C579, &h429EF47D, &h427B169C, &h5AC9F049, &hDD8F0F00, &h5C8165BF
       
    S_BOX2:
    ! DD  &h1F201094, &hEF0BA75B, &h69E3CF7E, &h393F4380, &hFE61CF7A, &hEEC5207A, &h55889C94, &h72FC0651
    ! DD  &hADA7EF79, &h4E1D7235, &hD55A63CE, &hDE0436BA, &h99C430EF, &h5F0C0794, &h18DCDB7D, &hA1D6EFF3
    ! DD  &hA0B52F7B, &h59E83605, &hEE15B094, &hE9FFD909, &hDC440086, &hEF944459, &hBA83CCB3, &hE0C3CDFB
    ! DD  &hD1DA4181, &h3B092AB1, &hF997F1C1, &hA5E6CF7B, &h01420DDB, &hE4E7EF5B, &h25A1FF41, &hE180F806
    ! DD  &h1FC41080, &h179BEE7A, &hD37AC6A9, &hFE5830A4, &h98DE8B7F, &h77E83F4E, &h79929269, &h24FA9F7B
    ! DD  &hE113C85B, &hACC40083, &hD7503525, &hF7EA615F, &h62143154, &h0D554B63, &h5D681121, &hC866C359
    ! DD  &h3D63CF73, &hCEE234C0, &hD4D87E87, &h5C672B21, &h071F6181, &h39F7627F, &h361E3084, &hE4EB573B
    ! DD  &h602F64A4, &hD63ACD9C, &h1BBC4635, &h9E81032D, &h2701F50C, &h99847AB4, &hA0E3DF79, &hBA6CF38C
    ! DD  &h10843094, &h2537A95E, &hF46F6FFE, &hA1FF3B1F, &h208CFB6A, &h8F458C74, &hD9E0A227, &h4EC73A34
    ! DD  &hFC884F69, &h3E4DE8DF, &hEF0E0088, &h3559648D, &h8A45388C, &h1D804366, &h721D9BFD, &hA58684BB
    ! DD  &hE8256333, &h844E8212, &h128D8098, &hFED33FB4, &hCE280AE1, &h27E19BA5, &hD5A6C252, &hE49754BD
    ! DD  &hC5D655DD, &hEB667064, &h77840B4D, &hA1B6A801, &h84DB26A9, &hE0B56714, &h21F043B7, &hE5D05860
    ! DD  &h54F03084, &h066FF472, &hA31AA153, &hDADC4755, &hB5625DBF, &h68561BE6, &h83CA6B94, &h2D6ED23B
    ! DD  &hECCF01DB, &hA6D3D0BA, &hB6803D5C, &hAF77A709, &h33B4A34C, &h397BC8D6, &h5EE22B95, &h5F0E5304
    ! DD  &h81ED6F61, &h20E74364, &hB45E1378, &hDE18639B, &h881CA122, &hB96726D1, &h8049A7E8, &h22B7DA7B
    ! DD  &h5E552D25, &h5272D237, &h79D2951C, &hC60D894C, &h488CB402, &h1BA4FE5B, &hA4B09F6B, &h1CA815CF
    ! DD  &hA20C3005, &h8871DF63, &hB9DE2FCB, &h0CC6C9E9, &h0BEEFF53, &hE3214517, &hB4542835, &h9F63293C
    ! DD  &hEE41E729, &h6E1D2D7C, &h50045286, &h1E6685F3, &hF33401C6, &h30A22C95, &h31A70850, &h60930F13
    ! DD  &h73F98417, &hA1269859, &hEC645C44, &h52C877A9, &hCDFF33A6, &hA02B1741, &h7CBAD9A2, &h2180036F
    ! DD  &h50D99C08, &hCB3F4861, &hC26BD765, &h64A3F6AB, &h80342676, &h25A75E7B, &hE4E6D1FC, &h20C710E6
    ! DD  &hCDF0B680, &h17844D3B, &h31EEF84D, &h7E0824E4, &h2CCB49EB, &h846A3BAE, &h8FF77888, &hEE5D60F6
    ! DD  &h7AF75673, &h2FDD5CDB, &hA11631C1, &h30F66F43, &hB3FAEC54, &h157FD7FA, &hEF8579CC, &hD152DE58
    ! DD  &hDB2FFD5E, &h8F32CE19, &h306AF97A, &h02F03EF8, &h99319AD5, &hC242FA0F, &hA7E3EBB0, &hC68E4906
    ! DD  &hB8DA230C, &h80823028, &hDCDEF3C8, &hD35FB171, &h088A1BC8, &hBEC0C560, &h61A3C9E8, &hBCA8F54D
    ! DD  &hC72FEFFA, &h22822E99, &h82C570B4, &hD8D94E89, &h8B1C34BC, &h301E16E6, &h273BE979, &hB0FFEAA6
    ! DD  &h61D9B8C6, &h00B24869, &hB7FFCE3F, &h08DC283B, &h43DAF65A, &hF7E19798, &h7619B72F, &h8F1C9BA4
    ! DD  &hDC8637A0, &h16A7D3B1, &h9FC393B7, &hA7136EEB, &hC6BCC63E, &h1A513742, &hEF6828BC, &h520365D6
    ! DD  &h2D6A77AB, &h3527ED4B, &h821FD216, &h095C6E2E, &hDB92F2FB, &h5EEA29CB, &h145892F5, &h91584F7F
    ! DD  &h5483697B, &h2667A8CC, &h85196048, &h8C4BACEA, &h833860D4, &h0D23E0F9, &h6C387E8A, &h0AE6D249
    ! DD  &hB284600C, &hD835731D, &hDCB1C647, &hAC4C56EA, &h3EBD81B3, &h230EABB0, &h6438BC87, &hF0B5B1FA
    ! DD  &h8F5EA2B3, &hFC184642, &h0A036B7A, &h4FB089BD, &h649DA589, &hA345415E, &h5C038323, &h3E5D3BB9
    ! DD  &h43D79572, &h7E6DD07C, &h06DFDF1E, &h6C6CC4EF, &h7160A539, &h73BFBE70, &h83877605, &h4523ECF1
       
    S_BOX3:
    ! DD  &h8DEFC240, &h25FA5D9F, &hEB903DBF, &hE810C907, &h47607FFF, &h369FE44B, &h8C1FC644, &hAECECA90
    ! DD  &hBEB1F9BF, &hEEFBCAEA, &hE8CF1950, &h51DF07AE, &h920E8806, &hF0AD0548, &hE13C8D83, &h927010D5
    ! DD  &h11107D9F, &h07647DB9, &hB2E3E4D4, &h3D4F285E, &hB9AFA820, &hFADE82E0, &hA067268B, &h8272792E
    ! DD  &h553FB2C0, &h489AE22B, &hD4EF9794, &h125E3FBC, &h21FFFCEE, &h825B1BFD, &h9255C5ED, &h1257A240
    ! DD  &h4E1A8302, &hBAE07FFF, &h528246E7, &h8E57140E, &h3373F7BF, &h8C9F8188, &hA6FC4EE8, &hC982B5A5
    ! DD  &hA8C01DB7, &h579FC264, &h67094F31, &hF2BD3F5F, &h40FFF7C1, &h1FB78DFC, &h8E6BD2C1, &h437BE59B
    ! DD  &h99B03DBF, &hB5DBC64B, &h638DC0E6, &h55819D99, &hA197C81C, &h4A012D6E, &hC5884A28, &hCCC36F71
    ! DD  &hB843C213, &h6C0743F1, &h8309893C, &h0FEDDD5F, &h2F7FE850, &hD7C07F7E, &h02507FBF, &h5AFB9A04
    ! DD  &hA747D2D0, &h1651192E, &hAF70BF3E, &h58C31380, &h5F98302E, &h727CC3C4, &h0A0FB402, &h0F7FEF82
    ! DD  &h8C96FDAD, &h5D2C2AAE, &h8EE99A49, &h50DA88B8, &h8427F4A0, &h1EAC5790, &h796FB449, &h8252DC15
    ! DD  &hEFBD7D9B, &hA672597D, &hADA840D8, &h45F54504, &hFA5D7403, &hE83EC305, &h4F91751A, &h925669C2
    ! DD  &h23EFE941, &hA903F12E, &h60270DF2, &h0276E4B6, &h94FD6574, &h927985B2, &h8276DBCB, &h02778176
    ! DD  &hF8AF918D, &h4E48F79E, &h8F616DDF, &hE29D840E, &h842F7D83, &h340CE5C8, &h96BBB682, &h93B4B148
    ! DD  &hEF303CAB, &h984FAF28, &h779FAF9B, &h92DC560D, &h224D1E20, &h8437AA88, &h7D29DC96, &h2756D3DC
    ! DD  &h8B907CEE, &hB51FD240, &hE7C07CE3, &hE566B4A1, &hC3E9615E, &h3CF8209D, &h6094D1E3, &hCD9CA341
    ! DD  &h5C76460E, &h00EA983B, &hD4D67881, &hFD47572C, &hF76CEDD9, &hBDA8229C, &h127DADAA, &h438A074E
    ! DD  &h1F97C090, &h081BDB8A, &h93A07EBE, &hB938CA15, &h97B03CFF, &h3DC2C0F8, &h8D1AB2EC, &h64380E51
    ! DD  &h68CC7BFB, &hD90F2788, &h12490181, &h5DE5FFD4, &hDD7EF86A, &h76A2E214, &hB9A40368, &h925D958F
    ! DD  &h4B39FFFA, &hBA39AEE9, &hA4FFD30B, &hFAF7933B, &h6D498623, &h193CBCFA, &h27627545, &h825CF47A
    ! DD  &h61BD8BA0, &hD11E42D1, &hCEAD04F4, &h127EA392, &h10428DB7, &h8272A972, &h9270C4A8, &h127DE50B
    ! DD  &h285BA1C8, &h3C62F44F, &h35C0EAA5, &hE805D231, &h428929FB, &hB4FCDF82, &h4FB66A53, &h0E7DC15B
    ! DD  &h1F081FAB, &h108618AE, &hFCFD086D, &hF9FF2889, &h694BCC11, &h236A5CAE, &h12DECA4D, &h2C3F8CC5
    ! DD  &hD2D02DFE, &hF8EF5896, &hE4CF52DA, &h95155B67, &h494A488C, &hB9B6A80C, &h5C8F82BC, &h89D36B45
    ! DD  &h3A609437, &hEC00C9A9, &h44715253, &h0A874B49, &hD773BC40, &h7C34671C, &h02717EF6, &h4FEB5536
    ! DD  &hA2D02FFF, &hD2BF60C4, &hD43F03C0, &h50B4EF6D, &h07478CD1, &h006E1888, &hA2E53F55, &hB9E6D4BC
    ! DD  &hA2048016, &h97573833, &hD7207D67, &hDE0F8F3D, &h72F87B33, &hABCC4F33, &h7688C55D, &h7B00A6B0
    ! DD  &h947B0001, &h570075D2, &hF9BB88F8, &h8942019E, &h4264A5FF, &h856302E0, &h72DBD92B, &hEE971B69
    ! DD  &h6EA22FDE, &h5F08AE2B, &hAF7A616D, &hE5C98767, &hCF1FEBD2, &h61EFC8C2, &hF1AC2571, &hCC8239C2
    ! DD  &h67214CB8, &hB1E583D1, &hB7DC3E62, &h7F10BDCE, &hF90A5C38, &h0FF0443D, &h606E6DC6, &h60543A49
    ! DD  &h5727C148, &h2BE98A1D, &h8AB41738, &h20E1BE24, &hAF96DA0F, &h68458425, &h99833BE5, &h600D457D
    ! DD  &h282F9350, &h8334B362, &hD91D1120, &h2B6D8DA0, &h642B1E31, &h9C305A00, &h52BCE688, &h1B03588A
    ! DD  &hF7BAEFD5, &h4142ED9C, &hA4315C11, &h83323EC5, &hDFEF4636, &hA133C501, &hE9D3531C, &hEE353783
       
    S_BOX4:
    ! DD  &h9DB30420, &h1FB6E9DE, &hA7BE7BEF, &hD273A298, &h4A4F7BDB, &h64AD8C57, &h85510443, &hFA020ED1
    ! DD  &h7E287AFF, &hE60FB663, &h095F35A1, &h79EBF120, &hFD059D43, &h6497B7B1, &hF3641F63, &h241E4ADF
    ! DD  &h28147F5F, &h4FA2B8CD, &hC9430040, &h0CC32220, &hFDD30B30, &hC0A5374F, &h1D2D00D9, &h24147B15
    ! DD  &hEE4D111A, &h0FCA5167, &h71FF904C, &h2D195FFE, &h1A05645F, &h0C13FEFE, &h081B08CA, &h05170121
    ! DD  &h80530100, &hE83E5EFE, &hAC9AF4F8, &h7FE72701, &hD2B8EE5F, &h06DF4261, &hBB9E9B8A, &h7293EA25
    ! DD  &hCE84FFDF, &hF5718801, &h3DD64B04, &hA26F263B, &h7ED48400, &h547EEBE6, &h446D4CA0, &h6CF3D6F5
    ! DD  &h2649ABDF, &hAEA0C7F5, &h36338CC1, &h503F7E93, &hD3772061, &h11B638E1, &h72500E03, &hF80EB2BB
    ! DD  &hABE0502E, &hEC8D77DE, &h57971E81, &hE14F6746, &hC9335400, &h6920318F, &h081DBB99, &hFFC304A5
    ! DD  &h4D351805, &h7F3D5CE3, &hA6C866C6, &h5D5BCCA9, &hDAEC6FEA, &h9F926F91, &h9F46222F, &h3991467D
    ! DD  &hA5BF6D8E, &h1143C44F, &h43958302, &hD0214EEB, &h022083B8, &h3FB6180C, &h18F8931E, &h281658E6
    ! DD  &h26486E3E, &h8BD78A70, &h7477E4C1, &hB506E07C, &hF32D0A25, &h79098B02, &hE4EABB81, &h28123B23
    ! DD  &h69DEAD38, &h1574CA16, &hDF871B62, &h211C40B7, &hA51A9EF9, &h0014377B, &h041E8AC8, &h09114003
    ! DD  &hBD59E4D2, &hE3D156D5, &h4FE876D5, &h2F91A340, &h557BE8DE, &h00EAE4A7, &h0CE5C2EC, &h4DB4BBA6
    ! DD  &hE756BDFF, &hDD3369AC, &hEC17B035, &h06572327, &h99AFC8B0, &h56C8C391, &h6B65811C, &h5E146119
    ! DD  &h6E85CB75, &hBE07C002, &hC2325577, &h893FF4EC, &h5BBFC92D, &hD0EC3B25, &hB7801AB7, &h8D6D3B24
    ! DD  &h20C763EF, &hC366A5FC, &h9C382880, &h0ACE3205, &hAAC9548A, &hECA1D7C7, &h041AFA32, &h1D16625A
    ! DD  &h6701902C, &h9B757A54, &h31D477F7, &h9126B031, &h36CC6FDB, &hC70B8B46, &hD9E66A48, &h56E55A79
    ! DD  &h026A4CEB, &h52437EFF, &h2F8F76B4, &h0DF980A5, &h8674CDE3, &hEDDA04EB, &h17A9BE04, &h2C18F4DF
    ! DD  &hB7747F9D, &hAB2AF7B4, &hEFC34D20, &h2E096B7C, &h1741A254, &hE5B6A035, &h213D42F6, &h2C1C7C26
    ! DD  &h61C2F50F, &h6552DAF9, &hD2C231F8, &h25130F69, &hD8167FA2, &h0418F2C8, &h001A96A6, &h0D1526AB
    ! DD  &h63315C21, &h5E0A72EC, &h49BAFEFD, &h187908D9, &h8D0DBD86, &h311170A7, &h3E9B640C, &hCC3E10D7
    ! DD  &hD5CAD3B6, &h0CAEC388, &hF73001E1, &h6C728AFF, &h71EAE2A1, &h1F9AF36E, &hCFCBD12F, &hC1DE8417
    ! DD  &hAC07BE6B, &hCB44A1D8, &h8B9B0F56, &h013988C3, &hB1C52FCA, &hB4BE31CD, &hD8782806, &h12A3A4E2
    ! DD  &h6F7DE532, &h58FD7EB6, &hD01EE900, &h24ADFFC2, &hF4990FC5, &h9711AAC5, &h001D7B95, &h82E5E7D2
    ! DD  &h109873F6, &h00613096, &hC32D9521, &hADA121FF, &h29908415, &h7FBB977F, &hAF9EB3DB, &h29C9ED2A
    ! DD  &h5CE2A465, &hA730F32C, &hD0AA3FE8, &h8A5CC091, &hD49E2CE7, &h0CE454A9, &hD60ACD86, &h015F1919
    ! DD  &h77079103, &hDEA03AF6, &h78A8565E, &hDEE356DF, &h21F05CBE, &h8B75E387, &hB3C50651, &hB8A5C3EF
    ! DD  &hD8EEB6D2, &hE523BE77, &hC2154529, &h2F69EFDF, &hAFE67AFB, &hF470C4B2, &hF3E0EB5B, &hD6CC9876
    ! DD  &h39E4460C, &h1FDA8538, &h1987832F, &hCA007367, &hA99144F8, &h296B299E, &h492FC295, &h9266BEAB
    ! DD  &hB5676E69, &h9BD3DDDA, &hDF7E052F, &hDB25701C, &h1B5E51EE, &hF65324E6, &h6AFCE36C, &h0316CC04
    ! DD  &h8644213E, &hB7DC59D0, &h7965291F, &hCCD6FD43, &h41823979, &h932BCDF6, &hB657C34D, &h4EDFD282
    ! DD  &h7AE5290C, &h3CB9536B, &h851E20FE, &h9833557E, &h13ECF0B0, &hD3FFB372, &h3F85C5C1, &h0AEF7ED2
       
    S_BOX5:
    ! DD  &h7ec90c04, &h2c6e74b9, &h9b0e66df, &ha6337911, &hb86a7fff, &h1dd358f5, &h44dd9d44, &h1731167f
    ! DD  &h08fbf1fa, &he7f511cc, &hd2051b00, &h735aba00, &h2ab722d8, &h386381cb, &hacf6243a, &h69befd7a
    ! DD  &he6a2e77f, &hf0c720cd, &hc4494816, &hccf5c180, &h38851640, &h15b0a848, &he68b18cb, &h4caadeff
    ! DD  &h5f480a01, &h0412b2aa, &h259814fc, &h41d0efe2, &h4e40b48d, &h248eb6fb, &h8dba1cfe, &h41a99b02
    ! DD  &h1a550a04, &hba8f65cb, &h7251f4e7, &h95a51725, &hc106ecd7, &h97a5980a, &hc539b9aa, &h4d79fe6a
    ! DD  &hf2f3f763, &h68af8040, &hed0c9e56, &h11b4958b, &he1eb5a88, &h8709e6b0, &hd7e07156, &h4e29fea7
    ! DD  &h6366e52d, &h02d1c000, &hc4ac8e05, &h9377f571, &h0c05372a, &h578535f2, &h2261be02, &hd642a0c9
    ! DD  &hdf13a280, &h74b55bd2, &h682199c0, &hd421e5ec, &h53fb3ce8, &hc8adedb3, &h28a87fc9, &h3d959981
    ! DD  &h5c1ff900, &hfe38d399, &h0c4eff0b, &h062407ea, &haa2f4fb1, &h4fb96976, &h90c79505, &hb0a8a774
    ! DD  &hef55a1ff, &he59ca2c2, &ha6b62d27, &he66a4263, &hdf65001f, &h0ec50966, &hdfdd55bc, &h29de0655
    ! DD  &h911e739a, &h17af8975, &h32c7911c, &h89f89468, &h0d01e980, &h524755f4, &h03b63cc9, &h0cc844b2
    ! DD  &hbcf3f0aa, &h87ac36e9, &he53a7426, &h01b3d82b, &h1a9e7449, &h64ee2d7e, &hcddbb1da, &h01c94910
    ! DD  &hb868bf80, &h0d26f3fd, &h9342ede7, &h04a5c284, &h636737b6, &h50f5b616, &hf24766e3, &h8eca36c1
    ! DD  &h136e05db, &hfef18391, &hfb887a37, &hd6e7f7d4, &hc7fb7dc9, &h3063fcdf, &hb6f589de, &hec2941da
    ! DD  &h26e46695, &hb7566419, &hf654efc5, &hd08d58b7, &h48925401, &hc1bacb7f, &he5ff550f, &hb6083049
    ! DD  &h5bb5d0e8, &h87d72e5a, &hab6a6ee1, &h223a66ce, &hc62bf3cd, &h9e0885f9, &h68cb3e47, &h086c010f
    ! DD  &ha21de820, &hd18b69de, &hf3f65777, &hfa02c3f6, &h407edac3, &hcbb3d550, &h1793084d, &hb0d70eba
    ! DD  &h0ab378d5, &hd951fb0c, &hded7da56, &h4124bbe4, &h94ca0b56, &h0f5755d1, &he0e1e56e, &h6184b5be
    ! DD  &h580a249f, &h94f74bc0, &he327888e, &h9f7b5561, &hc3dc0280, &h05687715, &h646c6bd7, &h44904db3
    ! DD  &h66b4f0a3, &hc0f1648a, &h697ed5af, &h49e92ff6, &h309e374f, &h2cb6356a, &h85808573, &h4991f840
    ! DD  &h76f0ae02, &h083be84d, &h28421c9a, &h44489406, &h736e4cb8, &hc1092910, &h8bc95fc6, &h7d869cf4
    ! DD  &h134f616f, &h2e77118d, &hb31b2be1, &haa90b472, &h3ca5d717, &h7d161bba, &h9cad9010, &haf462ba2
    ! DD  &h9fe459d2, &h45d34559, &hd9f2da13, &hdbc65487, &hf3e4f94e, &h176d486f, &h097c13ea, &h631da5c7
    ! DD  &h445f7382, &h175683f4, &hcdc66a97, &h70be0288, &hb3cdcf72, &h6e5dd2f3, &h20936079, &h459b80a5
    ! DD  &hbe60e2db, &ha9c23101, &heba5315c, &h224e42f2, &h1c5c1572, &hf6721b2c, &h1ad2fff3, &h8c25404e
    ! DD  &h324ed72f, &h4067b7fd, &h0523138e, &h5ca3bc78, &hdc0fd66e, &h75922283, &h784d6b17, &h58ebb16e
    ! DD  &h44094f85, &h3f481d87, &hfcfeae7b, &h77b5ff76, &h8c2302bf, &haaf47556, &h5f46b02a, &h2b092801
    ! DD  &h3d38f5f7, &h0ca81f36, &h52af4a8a, &h66d5e7c0, &hdf3b0874, &h95055110, &h1b5ad7a8, &hf61ed5ad
    ! DD  &h6cf6e479, &h20758184, &hd0cefa65, &h88f7be58, &h4a046826, &h0ff6f8f3, &ha09c7f70, &h5346aba0
    ! DD  &h5ce96c28, &he176eda3, &h6bac307f, &h376829d2, &h85360fa9, &h17e3fe2a, &h24b79767, &hf5a96b20
    ! DD  &hd6cd2595, &h68ff1ebf, &h7555442c, &hf19f06be, &hf9e0659a, &heeb9491d, &h34010718, &hbb30cab8
    ! DD  &he822fe15, &h88570983, &h750e6249, &hda627e55, &h5e76ffa8, &hb1534546, &h6d47de08, &hefe9e7d4
       
    S_BOX6:
    ! DD  &hf6fa8f9d, &h2cac6ce1, &h4ca34867, &he2337f7c, &h95db08e7, &h016843b4, &heced5cbc, &h325553ac
    ! DD  &hbf9f0960, &hdfa1e2ed, &h83f0579d, &h63ed86b9, &h1ab6a6b8, &hde5ebe39, &hf38ff732, &h8989b138
    ! DD  &h33f14961, &hc01937bd, &hf506c6da, &he4625e7e, &ha308ea99, &h4e23e33c, &h79cbd7cc, &h48a14367
    ! DD  &ha3149619, &hfec94bd5, &ha114174a, &heaa01866, &ha084db2d, &h09a8486f, &ha888614a, &h2900af98
    ! DD  &h01665991, &he1992863, &hc8f30c60, &h2e78ef3c, &hd0d51932, &hcf0fec14, &hf7ca07d2, &hd0a82072
    ! DD  &hfd41197e, &h9305a6b0, &he86be3da, &h74bed3cd, &h372da53c, &h4c7f4448, &hdab5d440, &h6dba0ec3
    ! DD  &h083919a7, &h9fbaeed9, &h49dbcfb0, &h4e670c53, &h5c3d9c01, &h64bdb941, &h2c0e636a, &hba7dd9cd
    ! DD  &hea6f7388, &he70bc762, &h35f29adb, &h5c4cdd8d, &hf0d48d8c, &hb88153e2, &h08a19866, &h1ae2eac8
    ! DD  &h284caf89, &haa928223, &h9334be53, &h3b3a21bf, &h16434be3, &h9aea3906, &hefe8c36e, &hf890cdd9
    ! DD  &h80226dae, &hc340a4a3, &hdf7e9c09, &ha694a807, &h5b7c5ecc, &h221db3a6, &h9a69a02f, &h68818a54
    ! DD  &hceb2296f, &h53c0843a, &hfe893655, &h25bfe68a, &hb4628abc, &hcf222ebf, &h25ac6f48, &ha9a99387
    ! DD  &h53bddb65, &he76ffbe7, &he967fd78, &h0ba93563, &h8e342bc1, &he8a11be9, &h4980740d, &hc8087dfc
    ! DD  &h8de4bf99, &ha11101a0, &h7fd37975, &hda5a26c0, &he81f994f, &h9528cd89, &hfd339fed, &hb87834bf
    ! DD  &h5f04456d, &h22258698, &hc9c4c83b, &h2dc156be, &h4f628daa, &h57f55ec5, &he2220abe, &hd2916ebf
    ! DD  &h4ec75b95, &h24f2c3c0, &h42d15d99, &hcd0d7fa0, &h7b6e27ff, &ha8dc8af0, &h7345c106, &hf41e232f
    ! DD  &h35162386, &he6ea8926, &h3333b094, &h157ec6f2, &h372b74af, &h692573e4, &he9a9d848, &hf3160289
    ! DD  &h3a62ef1d, &ha787e238, &hf3a5f676, &h74364853, &h20951063, &h4576698d, &hb6fad407, &h592af950
    ! DD  &h36f73523, &h4cfb6e87, &h7da4cec0, &h6c152daa, &hcb0396a8, &hc50dfe5d, &hfcd707ab, &h0921c42f
    ! DD  &h89dff0bb, &h5fe2be78, &h448f4f33, &h754613c9, &h2b05d08d, &h48b9d585, &hdc049441, &hc8098f9b
    ! DD  &h7dede786, &hc39a3373, &h42410005, &h6a091751, &h0ef3c8a6, &h890072d6, &h28207682, &ha9a9f7be
    ! DD  &hbf32679d, &hd45b5b75, &hb353fd00, &hcbb0e358, &h830f220a, &h1f8fb214, &hd372cf08, &hcc3c4a13
    ! DD  &h8cf63166, &h061c87be, &h88c98f88, &h6062e397, &h47cf8e7a, &hb6c85283, &h3cc2acfb, &h3fc06976
    ! DD  &h4e8f0252, &h64d8314d, &hda3870e3, &h1e665459, &hc10908f0, &h513021a5, &h6c5b68b7, &h822f8aa0
    ! DD  &h3007cd3e, &h74719eef, &hdc872681, &h073340d4, &h7e432fd9, &h0c5ec241, &h8809286c, &hf592d891
    ! DD  &h08a930f6, &h957ef305, &hb7fbffbd, &hc266e96f, &h6fe4ac98, &hb173ecc0, &hbc60b42a, &h953498da
    ! DD  &hfba1ae12, &h2d4bd736, &h0f25faab, &ha4f3fceb, &he2969123, &h257f0c3d, &h9348af49, &h361400bc
    ! DD  &he8816f4a, &h3814f200, &ha3f94043, &h9c7a54c2, &hbc704f57, &hda41e7f9, &hc25ad33a, &h54f4a084
    ! DD  &hb17f5505, &h59357cbe, &hedbd15c8, &h7f97c5ab, &hba5ac7b5, &hb6f6deaf, &h3a479c3a, &h5302da25
    ! DD  &h653d7e6a, &h54268d49, &h51a477ea, &h5017d55b, &hd7d25d88, &h44136c76, &h0404a8c8, &hb8e5a121
    ! DD  &hb81a928a, &h60ed5869, &h97c55b96, &heaec991b, &h29935913, &h01fdb7f1, &h088e8dfa, &h9ab6f6f5
    ! DD  &h3b4cbf9f, &h4a5de3ab, &he6051d35, &ha0e1d855, &hd36b4cf1, &hf544edeb, &hb0e93524, &hbebb8fbd
    ! DD  &ha2d762cf, &h49c92f54, &h38b5f331, &h7128a454, &h48392905, &ha65b1db8, &h851c97bd, &hd675cf2f
       
    S_BOX7:
    ! DD  &h85e04019, &h332bf567, &h662dbfff, &hcfc65693, &h2a8d7f6f, &hab9bc912, &hde6008a1, &h2028da1f
    ! DD  &h0227bce7, &h4d642916, &h18fac300, &h50f18b82, &h2cb2cb11, &hb232e75c, &h4b3695f2, &hb28707de
    ! DD  &ha05fbcf6, &hcd4181e9, &he150210c, &he24ef1bd, &hb168c381, &hfde4e789, &h5c79b0d8, &h1e8bfd43
    ! DD  &h4d495001, &h38be4341, &h913cee1d, &h92a79c3f, &h089766be, &hbaeeadf4, &h1286becf, &hb6eacb19
    ! DD  &h2660c200, &h7565bde4, &h64241f7a, &h8248dca9, &hc3b3ad66, &h28136086, &h0bd8dfa8, &h356d1cf2
    ! DD  &h107789be, &hb3b2e9ce, &h0502aa8f, &h0bc0351e, &h166bf52a, &heb12ff82, &he3486911, &hd34d7516
    ! DD  &h4e7b3aff, &h5f43671b, &h9cf6e037, &h4981ac83, &h334266ce, &h8c9341b7, &hd0d854c0, &hcb3a6c88
    ! DD  &h47bc2829, &h4725ba37, &ha66ad22b, &h7ad61f1e, &h0c5cbafa, &h4437f107, &hb6e79962, &h42d2d816
    ! DD  &h0a961288, &he1a5c06e, &h13749e67, &h72fc081a, &hb1d139f7, &hf9583745, &hcf19df58, &hbec3f756
    ! DD  &hc06eba30, &h07211b24, &h45c28829, &hc95e317f, &hbc8ec511, &h38bc46e9, &hc6e6fa14, &hbae8584a
    ! DD  &had4ebc46, &h468f508b, &h7829435f, &hf124183b, &h821dba9f, &haff60ff4, &hea2c4e6d, &h16e39264
    ! DD  &h92544a8b, &h009b4fc3, &haba68ced, &h9ac96f78, &h06a5b79a, &hb2856e6e, &h1aec3ca9, &hbe838688
    ! DD  &h0e0804e9, &h55f1be56, &he7e5363b, &hb3a1f25d, &hf7debb85, &h61fe033c, &h16746233, &h3c034c28
    ! DD  &hda6d0c74, &h79aac56c, &h3ce4e1ad, &h51f0c802, &h98f8f35a, &h1626a49f, &heed82b29, &h1d382fe3
    ! DD  &h0c4fb99a, &hbb325778, &h3ec6d97b, &h6e77a6a9, &hcb658b5c, &hd45230c7, &h2bd1408b, &h60c03eb7
    ! DD  &hb9068d78, &ha33754f4, &hf430c87d, &hc8a71302, &hb96d8c32, &hebd4e7be, &hbe8b9d2d, &h7979fb06
    ! DD  &he7225308, &h8b75cf77, &h11ef8da4, &he083c858, &h8d6b786f, &h5a6317a6, &hfa5cf7a0, &h5dda0033
    ! DD  &hf28ebfb0, &hf5b9c310, &ha0eac280, &h08b9767a, &ha3d9d2b0, &h79d34217, &h021a718d, &h9ac6336a
    ! DD  &h2711fd60, &h438050e3, &h069908a8, &h3d7fedc4, &h826d2bef, &h4eeb8476, &h488dcf25, &h36c9d566
    ! DD  &h28e74e41, &hc2610aca, &h3d49a9cf, &hbae3b9df, &hb65f8de6, &h92aeaf64, &h3ac7d5e6, &h9ea80509
    ! DD  &hf22b017d, &ha4173f70, &hdd1e16c3, &h15e0d7f9, &h50b1b887, &h2b9f4fd5, &h625aba82, &h6a017962
    ! DD  &h2ec01b9c, &h15488aa9, &hd716e740, &h40055a2c, &h93d29a22, &he32dbf9a, &h058745b9, &h3453dc1e
    ! DD  &hd699296e, &h496cff6f, &h1c9f4986, &hdfe2ed07, &hb87242d1, &h19de7eae, &h053e561a, &h15ad6f8c
    ! DD  &h66626c1c, &h7154c24c, &hea082b2a, &h93eb2939, &h17dcb0f0, &h58d4f2ae, &h9ea294fb, &h52cf564c
    ! DD  &h9883fe66, &h2ec40581, &h763953c3, &h01d6692e, &hd3a0c108, &ha1e7160e, &he4f2dfa6, &h693ed285
    ! DD  &h74904698, &h4c2b0edd, &h4f757656, &h5d393378, &ha132234f, &h3d321c5d, &hc3f5e194, &h4b269301
    ! DD  &hc79f022f, &h3c997e7e, &h5e4f9504, &h3ffafbbd, &h76f7ad0e, &h296693f4, &h3d1fce6f, &hc61e45be
    ! DD  &hd3b5ab34, &hf72bf9b7, &h1b0434c0, &h4e72b567, &h5592a33d, &hb5229301, &hcfd2a87f, &h60aeb767
    ! DD  &h1814386b, &h30bcc33d, &h38a0c07d, &hfd1606f2, &hc363519b, &h589dd390, &h5479f8e6, &h1cb8d647
    ! DD  &h97fd61a9, &hea7759f4, &h2d57539d, &h569a58cf, &he84e63ad, &h462e1b78, &h6580f87e, &hf3817914
    ! DD  &h91da55f4, &h40a230f3, &hd1988f35, &hb6e318d2, &h3ffa50bc, &h3d40f021, &hc3c0bdae, &h4958c24c
    ! DD  &h518f36b2, &h84b1d370, &h0fedce83, &h878ddada, &hf2a279c7, &h94e01be8, &h90716f4b, &h954b8aa3
       
    S_BOX8:
    ! DD  &he216300d, &hbbddfffc, &ha7ebdabd, &h35648095, &h7789f8b7, &he6c1121b, &h0e241600, &h052ce8b5
    ! DD  &h11a9cfb0, &he5952f11, &hece7990a, &h9386d174, &h2a42931c, &h76e38111, &hb12def3a, &h37ddddfc
    ! DD  &hde9adeb1, &h0a0cc32c, &hbe197029, &h84a00940, &hbb243a0f, &hb4d137cf, &hb44e79f0, &h049eedfd
    ! DD  &h0b15a15d, &h480d3168, &h8bbbde5a, &h669ded42, &hc7ece831, &h3f8f95e7, &h72df191b, &h7580330d
    ! DD  &h94074251, &h5c7dcdfa, &habbe6d63, &haa402164, &hb301d40a, &h02e7d1ca, &h53571dae, &h7a3182a2
    ! DD  &h12a8ddec, &hfdaa335d, &h176f43e8, &h71fb46d4, &h38129022, &hce949ad4, &hb84769ad, &h965bd862
    ! DD  &h82f3d055, &h66fb9767, &h15b80b4e, &h1d5b47a0, &h4cfde06f, &hc28ec4b8, &h57e8726e, &h647a78fc
    ! DD  &h99865d44, &h608bd593, &h6c200e03, &h39dc5ff6, &h5d0b00a3, &hae63aff2, &h7e8bd632, &h70108c0c
    ! DD  &hbbd35049, &h2998df04, &h980cf42a, &h9b6df491, &h9e7edd53, &h06918548, &h58cb7e07, &h3b74ef2e
    ! DD  &h522fffb1, &hd24708cc, &h1c7e27cd, &ha4eb215b, &h3cf1d2e2, &h19b47a38, &h424f7618, &h35856039
    ! DD  &h9d17dee7, &h27eb35e6, &hc9aff67b, &h36baf5b8, &h09c467cd, &hc18910b1, &he11dbf7b, &h06cd1af8
    ! DD  &h7170c608, &h2d5e3354, &hd4de495a, &h64c6d006, &hbcc0c62c, &h3dd00db3, &h708f8f34, &h77d51b42
    ! DD  &h264f620f, &h24b8d2bf, &h15c1b79e, &h46a52564, &hf8d7e54e, &h3e378160, &h7895cda5, &h859c15a5
    ! DD  &he6459788, &hc37bc75f, &hdb07ba0c, &h0676a3ab, &h7f229b1e, &h31842e7b, &h24259fd7, &hf8bef472
    ! DD  &h835ffcb8, &h6df4c1f2, &h96f5b195, &hfd0af0fc, &hb0fe134c, &he2506d3d, &h4f9b12ea, &hf215f225
    ! DD  &ha223736f, &h9fb4c428, &h25d04979, &h34c713f8, &hc4618187, &hea7a6e98, &h7cd16efc, &h1436876c
    ! DD  &hf1544107, &hbedeee14, &h56e9af27, &ha04aa441, &h3cf7c899, &h92ecbae6, &hdd67016d, &h151682eb
    ! DD  &ha842eedf, &hfdba60b4, &hf1907b75, &h20e3030f, &h24d8c29e, &he139673b, &hefa63fb8, &h71873054
    ! DD  &hb6f2cf3b, &h9f326442, &hcb15a4cc, &hb01a4504, &hf1e47d8d, &h844a1be5, &hbae7dfdc, &h42cbda70
    ! DD  &hcd7dae0a, &h57e85b7a, &hd53f5af6, &h20cf4d8c, &hcea4d428, &h79d130a4, &h3486ebfb, &h33d3cddc
    ! DD  &h77853b53, &h37effcb5, &hc5068778, &he580b3e6, &h4e68b8f4, &hc5c8b37e, &h0d809ea2, &h398feb7c
    ! DD  &h132a4f94, &h43b7950e, &h2fee7d1c, &h223613bd, &hdd06caa2, &h37df932b, &hc4248289, &hacf3ebc3
    ! DD  &h5715f6b7, &hef3478dd, &hf267616f, &hc148cbe4, &h9052815e, &h5e410fab, &hb48a2465, &h2eda7fa4
    ! DD  &he87b40e4, &he98ea084, &h5889e9e1, &hefd390fc, &hdd07d35b, &hdb485694, &h38d7e5b2, &h57720101
    ! DD  &h730edebc, &h5b643113, &h94917e4f, &h503c2fba, &h646f1282, &h7523d24a, &he0779695, &hf9c17a8f
    ! DD  &h7a5b2121, &hd187b896, &h29263a4d, &hba510cdf, &h81f47c9f, &had1163ed, &hea7b5965, &h1a00726e
    ! DD  &h11403092, &h00da6d77, &h4a0cdd61, &had1f4603, &h605bdfb0, &h9eedc364, &h22ebe6a8, &hcee7d28a
    ! DD  &ha0e736a0, &h5564a6b9, &h10853209, &hc7eb8f37, &h2de705ca, &h8951570f, &hdf09822b, &hbd691a6c
    ! DD  &haa12e4f2, &h87451c0f, &he0f6a27a, &h3ada4819, &h4cf1764f, &h0d771c2b, &h67cdb156, &h350d8384
    ! DD  &h5938fa0f, &h42399ef3, &h36997b07, &h0e84093d, &h4aa93e61, &h8360d87b, &h1fa98b0c, &h1149382c
    ! DD  &he97625a5, &h0614d1b7, &h0e25244b, &h0c768347, &h589e8d82, &h0d2059d1, &ha466bb1e, &hf8da0a82
    ! DD  &h04f19130, &hba6e4ec0, &h99265164, &h1ee7230d, &h50b2ad80, &heaee6801, &h8db2a283, &hea8bf59e
    END SUB
    '-- end CAST-128.BAS
       
       
    '=====================================================================
    '                       CAST-128 Test Bed code
    '               Compiles with either PBWIN 7.0+ or PBCC 3.0+
    '=====================================================================
    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL
    '============
    DEFLNG A-Z
    %NOGDI     = 1 ' no GDI (Graphics Device Interface) functions
    %NOMMIDS   = 1 ' no Multimedia ID definitions
    %NONEWWAVE = 1 ' no new waveform types except WAVEFORMATEX are defined
    %NONEWRIFF = 1 ' no new RIFF formats are defined
    %NOJPEGDIB = 1 ' no JPEG DIB definitions
    %NONEWIC   = 1 ' no new Image Compressor types are defined
    %NOBITMAP  = 1 ' no extended bitmap info header definition
    #INCLUDE "WIN32API.INC"
       
    '--------------------
    '-- Utility macros
    '--------------------
       
    #IF %def(%pb_win32)
       MACRO eol=$CR
       MACRO mbox(t)=msgbox t
    #ELSEIF %def(%pb_cc32)
       MACRO eol=$CRLF
       MACRO mbox(t)=stdout t
    #ENDIF
       
    '--------------------
    MACRO EnterCC
    #IF %def(%pb_cc32)
       LOCAL launched&
       if (cursory = 1) and (cursorx = 1) then launched = -1
    #ENDIF
    END MACRO
       
    '--------------------
    MACRO ExitCC
    #IF %def(%pb_cc32)
       if launched then
          input flush
          stdout "Press any key to end"
          waitkey$
       end if
    #ENDIF
    END MACRO
       
    ''--------------------
    'MACRO zbs(x)=string$(x,0)
       
       
    #INCLUDE "CAST-128.BAS"
       
    DECLARE FUNCTION Hex2Show$(Buffer$)
       
    '====================
    FUNCTION PBMain&()
    REGISTER i&
    LOCAL key$, plain$, cipher$, shouldbe$, t$
    LOCAL ctx AS ENCRYPTION_CONTEXT  ' defined in CAST-128.BAS
    EnterCC
       
    CAST128_Init ctx
       
    '-- Standard CAST-128 test vectors:
    '-- 128-bit key
    key      = chr$(&h01,&h23,&h45,&h67,&h12,&h34,&h56,&h78,&h23,&h45,&h67,&h89,&h34,&h56,&h78,&h9A)
    plain    = chr$(&h01,&h23,&h45,&h67,&h89,&hAB,&hCD,&hEF)
    cipher   = zbs(len(plain$))
    shouldbe = chr$(&h23,&h8B,&h4F,&hE5,&h84,&h7E,&h44,&hB2)
       
    t = "Key length (bits):" + str$(len(key)*8) + eol
    t = t + "plain:    " + Hex2Show$(plain$) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol
    '-- Be sure to reload key$
    key = chr$(&h01,&h23,&h45,&h67,&h12,&h34,&h56,&h78,&h23,&h45,&h67,&h89,&h34,&h56,&h78,&h9A)
    gosub DoDecrypt
    t = t + "plain:    " + Hex2Show$(plain) + eol + eol
       
       
    '-- 80-bit key
    key      = chr$(&h01,&h23,&h45,&h67,&h12,&h34,&h56,&h78,&h23,&h45)
    plain    = chr$(&h01,&h23,&h45,&h67,&h89,&hAB,&hCD,&hEF)
    cipher   = zbs(len(plain))
    shouldbe = chr$(&hEB,&h6A,&h71,&h1A,&h2C,&h02,&h27,&h1B)
       
    t = t + "Key length (bits):" + str$((len(key$)*8)) + eol
    t = t + "plain:    " + Hex2Show$(plain) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol
       
    key = chr$(&h01,&h23,&h45,&h67,&h12,&h34,&h56,&h78,&h23,&h45)
    gosub DoDecrypt
    t = t + "plain:    " + Hex2Show$(plain) + eol + eol
       
       
    '-- 40-bit key
    key      = chr$(&h01,&h23,&h45,&h67,&h12)
    plain    = chr$(&h01,&h23,&h45,&h67,&h89,&hAB,&hCD,&hEF)
    cipher   = zbs(len(plain))
    shouldbe = chr$(&h7A,&hC8,&h16,&hD1,&h6E,&h9B,&h30,&h2E)
       
    t = t + "Key length (bits):" + str$((len(key$)*8)) + eol
    t = t + "plain:    " + Hex2Show$(plain) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol
       
    key = chr$(&h01,&h23,&h45,&h67,&h12)
    gosub DoDecrypt
    t = t + "plain:    " + Hex2Show$(plain) + eol + eol
       
    mbox(t)
       
    ExitCC
    exit function
       
    '============
    DoEncrypt:
    ctx.UserKey       = strptr(key$)
    ctx.UserKeyLength = len(key$)
    ctx.InBlock       = strptr(plain$)
    ctx.OutBlock      = strptr(cipher$)
    if Set_Key&(ctx) then 
       for i = 1 to (len(plain$)\%BLOCKSIZE)  '<-- Required: (len(plain$) mod 8) = 0
          EncryptBlock ctx
          ctx.InBlock  = ctx.InBlock  + %BLOCKSIZE
          ctx.OutBlock = ctx.OutBlock + %BLOCKSIZE
       next i&
    else
       mbox("Key setup error")
    end if
    '-- Burn the subkey
    poke$ Ctx.K, zbs(sizeof(Ctx.K_Buffer))
    RETURN
       
    '============
    DoDecrypt:
    ctx.UserKey       = strptr(key$)
    ctx.UserKeyLength = len(key$)
    ctx.InBlock       = strptr(cipher$)
    ctx.OutBlock      = strptr(plain$)
    if Set_Key&(ctx) then 
       for i = 1 to (len(plain$)\%BLOCKSIZE)  '<-- Required: (len(plain$) mod 8) = 0
          DecryptBlock ctx
          ctx.InBlock  = ctx.InBlock  + %BLOCKSIZE
          ctx.OutBlock = ctx.OutBlock + %BLOCKSIZE
       next i
    else
       mbox("Setup error")
    end if
    '-- Burn the subkey
    poke$ Ctx.K, zbs(sizeof(Ctx.K_Buffer))
    RETURN
    END FUNCTION
       
    '====================
    FUNCTION Hex2Show$(Buffer$)
    LOCAL t$, i&, b AS BYTE PTR
    b = strptr(Buffer$)
    for i = 0 to len(Buffer$)-1
       t = t + hex$(@b[i],2) + " "
    next i
    function = t
    END FUNCTION
    '-- end TESTBED.BAS

    [This message has been edited by Greg Turgeon (edited June 22, 2002).]
Working...
X