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