2024-04-29

Navigation

Skip Navigation Links

Hash algorithms

Asymmetric Algorithms

Symmetric Cipher Algorithms

Encoding Algorithms

Compression Algorithms

Pseudo Random Number Algorithms

Steganography

Library Wrappers

String Comparison

Others

Syntax highlighting by Prism
PBCrypto.com Mirror

CAST-256

Algorithm creator(s)

Entrust Inc.


PB author(s)

Greg Turgeon


Description

A DES-like Substitution-Permutation Network (SPN) cryptosystem which appears to have good resistance to differential cryptanalysis, linear cryptanalysis, and related-key cryptanalysis. This cipher also possesses a number of other desirable cryptographic properties, including avalanche, Strict Avalanche Criterion (SAC), Bit Independence Criterion (BIC), no complementation property, and an absence of weak and semi-weak keys. It thus appears to be a good candidate for general-purpose use throughout the Internet community wherever a cryptographically-strong, freely-available encryption algorithm is required.


Note

This sample source is compatible with PBWIN7 and uses macros.


Source

https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/24041-cast-256-encryption-for-3-0-7-0?t=23416


See also


Source Code

Download source code file cast-256.bas (Right-click -> "Save as ...")

#IF 0 
=====================================================================
                        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.+. Implementation Notes 
-- 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

Mirror provided by Knuth Konrad