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-256 Encryption for 3.0/7.0

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

  • CAST-256 Encryption for 3.0/7.0

    #IF 0
    Code:
    =====================================================================
                            CAST-256 Encryption
    =====================================================================
       
    The CAST-256 encryption algorithm (also known as CAST6) 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/rfc2612.txt 
    CAST-256 was one of the algorithms examined in the first round of the 
    Advanced Encryption Standard selection process.
       
    The PowerBASIC implementation appearing here, which is hereby placed 
    in the public domain, is based on RFC2612 and on C and C++ 
    implementations written and placed in the public domain by Steve Reid, 
    Wei Dai, and Leonard Janke.   Use the PB code as you wish.  My hope is
    to 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-256.BAS file 
    contents.  The code requires PB compiler releases 3.+/7.+.
       
       
    <U>Implementation Notes</U>
    -- The algorithm operates on plaintext blocks of 16 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:   = 2
       final block                   = chr$(x1 to x14) + chr$(0,2)
       
       total plaintext bytes         = 40
       plaintext blocks encrypted:   = 3
       final block                   = chr$(x1 to x8) + chr$(0,0,0,0,0,0,0,8)
       
    -- Encryption key lengths can range from 16 to 32 bytes (128 to 256 
    bits).  Keys shorter than 16 bytes are padded to 16 by appending zero 
    bytes.  
       
    -- 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-256 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-256.BAS
    '=====================================================================
       
    %BLOCKSIZE      = 16
    %KEY_SIZE       = 32
    %SUBKEY_SIZE    = 96
    %MIN_KEY_SIZE   = 16
    %MAX_KEY_SIZE   = 32
       
    '-- Note: Strings (UserKey, etc) are processed as 
    '   four-byte sequences, so LONG PTRs required
    TYPE ENCRYPTION_CONTEXT
    S_Box          AS LONG PTR
    UserKeyLength  AS LONG
    UserKey        AS LONG PTR
    InBlock        AS LONG PTR
    OutBlock       AS LONG PTR
    Tm             AS LONG PTR
    Tr             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 CAST256_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 FUNCTION getbyte(x,idx)
    retval = x
    !  shr   retval, idx*8
    END MACRO = (retval AND &HFF)
       
    '--------------------
    MACRO f1(l,r,km,kr)
    t = km + r
    u = kr
    !  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)])
    l = (l XOR u)
    END MACRO
       
    '--------------------
    MACRO f2(l,r,km,kr)
    t = (km XOR r)
    u = kr
    !  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)])
    l = (l XOR u)
    END MACRO
       
    '--------------------
    MACRO f3(l,r,km,kr)
    t = (km - r)
    u = kr
    !  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)])
    l = (l XOR u)
    END MACRO
       
    '--------------------
    MACRO Omega(j,kappa)
    f1(@kappa[6],@kappa[7],@tm[(0*24)+j],@tr[(0*24)+j])
    f2(@kappa[5],@kappa[6],@tm[(1*24)+j],@tr[(1*24)+j])
    f3(@kappa[4],@kappa[5],@tm[(2*24)+j],@tr[(2*24)+j])
    f1(@kappa[3],@kappa[4],@tm[(3*24)+j],@tr[(3*24)+j])
    f2(@kappa[2],@kappa[3],@tm[(4*24)+j],@tr[(4*24)+j])
    f3(@kappa[1],@kappa[2],@tm[(5*24)+j],@tr[(5*24)+j])
    f1(@kappa[0],@kappa[1],@tm[(6*24)+j],@tr[(6*24)+j])
    f2(@kappa[7],@kappa[0],@tm[(7*24)+j],@tr[(7*24)+j])
    END MACRO
       
       
    '====================
    FUNCTION Set_Key&(Ctx AS ENCRYPTION_CONTEXT)
    LOCAL kappa_buffer$, kappa AS LONG PTR
    LOCAL k AS LONG PTR, tm AS LONG PTR, tr AS LONG PTR
    LOCAL i&, j&, t&, u&, retval&, s_box AS LONG PTR
       
    '-- 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 CAST256_Init has been called
    if Ctx.S_BOX = 0 then
       function = 0 : exit function
    end if
       
    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$)
       Ctx.UserKeyLength = %KEY_SIZE
    end if
       
    kappa_buffer$ = zbs(8*8) : kappa = strptr(kappa_buffer$)
       
    k = Ctx.UserKey
    for i = 1 to (Ctx.UserKeyLength\4)
       j = @k[i-1] : @kappa[i-1] = byte_reverse(j)
    next i&
       
    'for i = 0 to (Ctx.UserKeyLength\4)-1 : print hex8(@kappa[i]), : next i& : waitkey$
       
    k = Ctx.K : tm = Ctx.Tm : tr = Ctx.TR
    s_box = Ctx.S_BOX
       
    poke$ k, zbs(sizeof(Ctx.K_Buffer)) 'clear any previous key data
       
    for i = 0 to 11
       j = (i+i)
       Omega(j,kappa)
       incr j
       Omega(j,kappa)
       @k[8*i]     = (@kappa[0] AND &h01f)       ''31)
       @k[(8*i)+1] = (@kappa[2] AND &h01f)
       @k[(8*i)+2] = (@kappa[4] AND &h01f)
       @k[(8*i)+3] = (@kappa[6] AND &h01f)
       @k[(8*i)+4] =  @kappa[7]
       @k[(8*i)+5] =  @kappa[5]
       @k[(8*i)+6] =  @kappa[3]
       @k[(8*i)+7] =  @kappa[1]
    next i
       
    '-- Burn temp key buffer
    poke$ kappa, zbs(len(kappa_buffer$))
    function = -1
    END FUNCTION
       
       
    '--------------------
    MACRO ff1(l,r,i,j)
    f1(l,r,@k[i],@k[i+j])
    END MACRO
    '--------------------
    MACRO ff2(l,r,i,j)
    f2(l,r,@k[i],@k[i+j])
    END MACRO
    '--------------------
    MACRO ff3(l,r,i,j)
    f3(l,r,@k[i],@k[i+j])
    END MACRO
       
    '--------------------
    MACRO Q(i)
    ff1(@blk[2],@blk[3],(8*i+4),(-4))
    ff2(@blk[1],@blk[2],(8*i+5),(-4))
    ff3(@blk[0],@blk[1],(8*i+6),(-4))
    ff1(@blk[3],@blk[0],(8*i+7),(-4))
    END MACRO
       
    '--------------------
    MACRO QBar(i)
    ff1(@blk[3],@blk[0],(8*i+7),(-4))
    ff3(@blk[0],@blk[1],(8*i+6),(-4))
    ff2(@blk[1],@blk[2],(8*i+5),(-4))
    ff1(@blk[2],@blk[3],(8*i+4),(-4))
    END MACRO
       
       
    '====================
    FUNCTION EncryptBlock&(Ctx AS ENCRYPTION_CONTEXT)
    LOCAL t AS LONG, u AS LONG, block$, blk AS LONG PTR, k AS LONG PTR, s_box AS LONG PTR
    LOCAL retval& ' for macro use
       
    block$ = zbs(%BLOCKSIZE) : blk = strptr(BLOCK$)
    t = Ctx.@InBlock[0] : @blk[0] = byte_reverse(t)
    t = Ctx.@InBlock[1] : @blk[1] = byte_reverse(t)
    t = Ctx.@InBlock[2] : @blk[2] = byte_reverse(t)
    t = Ctx.@InBlock[3] : @blk[3] = byte_reverse(t)
       
    k = Ctx.K : s_box = Ctx.S_BOX
       
    '-- Perform 6 forward quad rounds
    Q(0)
    Q(1)
    Q(2)
    Q(3)
    Q(4)
    Q(5)
       
    '-- Perform 6 reverse quad rounds
    QBar(6)
    QBar(7)
    QBar(8)
    QBar(9)
    QBar(10)
    QBar(11)
       
    t = @blk[0] : Ctx.@OutBlock[0] = byte_reverse(t)
    t = @blk[1] : Ctx.@OutBlock[1] = byte_reverse(t)
    t = @blk[2] : Ctx.@OutBlock[2] = byte_reverse(t)
    t = @blk[3] : Ctx.@OutBlock[3] = byte_reverse(t)
    END FUNCTION
       
       
    '====================
    FUNCTION DecryptBlock&(Ctx AS ENCRYPTION_CONTEXT)
    LOCAL t AS LONG, u AS LONG, block$, blk AS LONG PTR, k AS LONG PTR, s_box AS LONG PTR
    LOCAL retval& ' for macro use
       
    block$ = zbs(%BLOCKSIZE) : blk = strptr(BLOCK$)
    t = Ctx.@InBlock[0] : @blk[0] = byte_reverse(t)
    t = Ctx.@InBlock[1] : @blk[1] = byte_reverse(t)
    t = Ctx.@InBlock[2] : @blk[2] = byte_reverse(t)
    t = Ctx.@InBlock[3] : @blk[3] = byte_reverse(t)
       
    k = Ctx.K : s_box = Ctx.S_BOX ' local copies
       
    '-- Perform 6 forward quad rounds
    Q(11)
    Q(10)
    Q(9)
    Q(8)
    Q(7)
    Q(6)
       
    '-- Perform 6 reverse quad rounds
    QBar(5)
    QBar(4)
    QBar(3)
    QBar(2)
    QBar(1)
    QBar(0)
       
    t = @blk[0] : Ctx.@OutBlock[0] = byte_reverse(t)
    t = @blk[1] : Ctx.@OutBlock[1] = byte_reverse(t)
    t = @blk[2] : Ctx.@OutBlock[2] = byte_reverse(t)
    t = @blk[3] : Ctx.@OutBlock[3] = byte_reverse(t)
    END FUNCTION
       
       
    '====================
    SUB CAST256_Init(Ctx AS ENCRYPTION_CONTEXT)
    Ctx.K_Buffer = zbs(%SUBKEY_SIZE*4)
    Ctx.K     = varptr(Ctx.K_Buffer)
    Ctx.S_BOX = codeptr(S_BOX1)
    Ctx.Tm    = codeptr(TM_ARRAY)
    Ctx.Tr    = codeptr(TR_ARRAY)
    exit sub
       
    TM_ARRAY:
    ! DD  &h5a827999, &hd151d6a1, &h482133a9, &hbef090b1, &h35bfedb9, &hac8f4ac1, &h235ea7c9, &h9a2e04d1
    ! DD  &h10fd61d9, &h87ccbee1, &hfe9c1be9, &h756b78f1, &hec3ad5f9, &h630a3301, &hd9d99009, &h50a8ed11
    ! DD  &hc7784a19, &h3e47a721, &hb5170429, &h2be66131, &ha2b5be39, &h19851b41, &h90547849, &h0723d551 
    ! DD  &hc95c653a, &h402bc242, &hb6fb1f4a, &h2dca7c52, &ha499d95a, &h1b693662, &h9238936a, &h0907f072
    ! DD  &h7fd74d7a, &hf6a6aa82, &h6d76078a, &he4456492, &h5b14c19a, &hd1e41ea2, &h48b37baa, &hbf82d8b2
    ! DD  &h365235ba, &had2192c2, &h23f0efca, &h9ac04cd2, &h118fa9da, &h885f06e2, &hff2e63ea, &h75fdc0f2 
    ! DD  &h383650db, &haf05ade3, &h25d50aeb, &h9ca467f3, &h1373c4fb, &h8a432203, &h01127f0b, &h77e1dc13
    ! DD  &heeb1391b, &h65809623, &hdc4ff32b, &h531f5033, &hc9eead3b, &h40be0a43, &hb78d674b, &h2e5cc453
    ! DD  &ha52c215b, &h1bfb7e63, &h92cadb6b, &h099a3873, &h8069957b, &hf738f283, &h6e084f8b, &he4d7ac93 
    ! DD  &ha7103c7c, &h1ddf9984, &h94aef68c, &h0b7e5394, &h824db09c, &hf91d0da4, &h6fec6aac, &he6bbc7b4
    ! DD  &h5d8b24bc, &hd45a81c4, &h4b29decc, &hc1f93bd4, &h38c898dc, &haf97f5e4, &h266752ec, &h9d36aff4
    ! DD  &h14060cfc, &h8ad56a04, &h01a4c70c, &h78742414, &hef43811c, &h6612de24, &hdce23b2c, &h53b19834 
    ! DD  &h15ea281d, &h8cb98525, &h0388e22d, &h7a583f35, &hf1279c3d, &h67f6f945, &hdec6564d, &h5595b355
    ! DD  &hcc65105d, &h43346d65, &hba03ca6d, &h30d32775, &ha7a2847d, &h1e71e185, &h95413e8d, &h0c109b95
    ! DD  &h82dff89d, &hf9af55a5, &h707eb2ad, &he74e0fb5, &h5e1d6cbd, &hd4ecc9c5, &h4bbc26cd, &hc28b83d5 
    ! DD  &h84c413be, &hfb9370c6, &h7262cdce, &he9322ad6, &h600187de, &hd6d0e4e6, &h4da041ee, &hc46f9ef6
    ! DD  &h3b3efbfe, &hb20e5906, &h28ddb60e, &h9fad1316, &h167c701e, &h8d4bcd26, &h041b2a2e, &h7aea8736
    ! DD  &hf1b9e43e, &h68894146, &hdf589e4e, &h5627fb56, &hccf7585e, &h43c6b566, &hba96126e, &h31656f76 
    ! DD  &hf39dff5f, &h6a6d5c67, &he13cb96f, &h580c1677, &hcedb737f, &h45aad087, &hbc7a2d8f, &h33498a97
    ! DD  &haa18e79f, &h20e844a7, &h97b7a1af, &h0e86feb7, &h85565bbf, &hfc25b8c7, &h72f515cf, &he9c472d7
    ! DD  &h6093cfdf, &hd7632ce7, &h4e3289ef, &hc501e6f7, &h3bd143ff, &hb2a0a107, &h296ffe0f, &ha03f5b17 
    ! DD  &h6277eb00, &hd9474808, &h5016a510, &hc6e60218, &h3db55f20, &hb484bc28, &h2b541930, &ha2237638
    ! DD  &h18f2d340, &h8fc23048, &h06918d50, &h7d60ea58, &hf4304760, &h6affa468, &he1cf0170, &h589e5e78
    ! DD  &hcf6dbb80, &h463d1888, &hbd0c7590, &h33dbd298, &haaab2fa0, &h217a8ca8, &h9849e9b0, &h0f1946b8 
       
    TR_ARRAY:
    ! DD  19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11
    ! DD  4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28 
    ! DD  21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13 
    ! DD  6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30 
    ! DD  23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15 
    ! DD  8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0
    ! DD  25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17 
    ! DD  10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2
       
    '-- 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
       
    END SUB
    '-- end CAST-256.BAS
       
       
    '=====================================================================
    '                       CAST-256 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) 'also defined in CAST-256.BAS
       
    #INCLUDE "CAST-256.BAS"
       
    DECLARE FUNCTION Hex2Show$(Buffer$)
       
    '====================
    FUNCTION PBMain&()
    REGISTER i&
    LOCAL key$, plain$, cipher$, shouldbe$, t$
    LOCAL ctx AS ENCRYPTION_CONTEXT  ' defined in CAST-256.BAS
    EnterCC
       
    CAST256_Init ctx
       
    '-- Standard CAST-256 test vectors:
    '-- 256-bit key
    key = chr$(&h23,&h42,&hbb,&h9e,&hfa,&h38,&h54,&h2c,&hbe,&hd0,&hac,&h83,&h94,&h0a,&hc2,&h98, _
                &h8d,&h7c,&h47,&hce,&h26,&h49,&h08,&h46,&h1c,&hc1,&hb5,&h13,&h7a,&he6,&hb6,&h04)
    plain = zbs(%BLOCKSIZE)
    cipher = zbs(len(plain))
    shouldbe = chr$(&h4f,&h6a,&h20,&h38,&h28,&h68,&h97,&hb9,&hc9,&h87,&h01,&h36,&h55,&h33,&h17,&hfa)
       
    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$(&h23,&h42,&hbb,&h9e,&hfa,&h38,&h54,&h2c,&hbe,&hd0,&hac,&h83,&h94,&h0a,&hc2,&h98, _
                &h8d,&h7c,&h47,&hce,&h26,&h49,&h08,&h46,&h1c,&hc1,&hb5,&h13,&h7a,&he6,&hb6,&h04)
    gosub DoDecrypt
    t = t + "plain:    " + Hex2Show$(plain) + eol + eol
       
       
    '-- 192-bit key
    key = chr$(&h23,&h42,&hbb,&h9e,&hfa,&h38,&h54,&h2c,&hbe,&hd0,&hac,&h83,&h94,&h0a,&hc2,&h98, _
               &hba,&hc7,&h7a,&h77,&h17,&h94,&h28,&h63)
    plain = zbs(%BLOCKSIZE)
    cipher = zbs(len(plain))
    shouldbe = chr$(&h1b,&h38,&h6c,&h02,&h10,&hdc,&had,&hcb,&hdd,&h0e,&h41,&haa,&h08,&ha7,&ha7,&he8)
       
    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
    '-- Be sure to reload key$
    key = chr$(&h23,&h42,&hbb,&h9e,&hfa,&h38,&h54,&h2c,&hbe,&hd0,&hac,&h83,&h94,&h0a,&hc2,&h98, _
               &hba,&hc7,&h7a,&h77,&h17,&h94,&h28,&h63)
    gosub DoDecrypt
    t = t + "plain:    " + Hex2Show$(plain) + eol + eol
       
       
    '-- 128-bit key
    key = chr$(&h23,&h42,&hbb,&h9e,&hfa,&h38,&h54,&h2c,&h0a,&hf7,&h56,&h47,&hf2,&h9f,&h61,&h5d)
    plain = zbs(%BLOCKSIZE)
    cipher = zbs(len(plain))
    shouldbe = chr$(&hc8,&h42,&ha0,&h89,&h72,&hb4,&h3d,&h20,&h83,&h6c,&h91,&hd1,&hb7,&h53,&h0f,&h6b)
       
    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
    '-- Be sure to reload key$
    key = chr$(&h23,&h42,&hbb,&h9e,&hfa,&h38,&h54,&h2c,&h0a,&hf7,&h56,&h47,&hf2,&h9f,&h61,&h5d)
    gosub DoDecrypt
    t = t + "plain:    " + Hex2Show$(plain) + eol + eol
       
    mbox(t)
       
    ExitPBMain:
    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 16) = 0
          EncryptBlock ctx
          ctx.InBlock  = ctx.InBlock  + %BLOCKSIZE
          ctx.OutBlock = ctx.OutBlock + %BLOCKSIZE
       next i&
    else
       mbox("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 16) = 0
          DecryptBlock ctx
          ctx.InBlock  = ctx.InBlock  + %BLOCKSIZE
          ctx.OutBlock = ctx.OutBlock + %BLOCKSIZE
       next i
    else
       mbox("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
    ------------------
    -- Greg
    gturgeon@compuserve.com
Working...
X