From VisualWorks®, 7.6 of February 1, 2008 on February 1, 2008 at 12:31:34 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>ARC4</name> <environment>Security</environment> <super>Security.StreamCipher</super> <private>false</private> none sBox i j <imports></imports> <category>Security-Ciphers</category> <attributes> <package>ARC4</package> </attributes> </class> <comment> Security.ARC4
This is an implementation of the "alleged" RC4 algorithm as described in Applied Cryptography by Bruce Schneier. The algorithm uses a secret key which is expected to be a ByteArray of size up to 256 bytes (anything above that mark will be ignored). Instance Variables: sBox <ByteArray> a key dependent substitution box, 256 bytes i <SmallInteger> s-box index j <SmallInteger> s-box index
</comment> <methods> Security.ARC4 <category>services</category>
decryptByte: aByte ^self encryptByte: aByte
encryptByte: aByte | si sj | "Algorithm definition is included in the comments, note that we need to adjust for the 0-based indexing" "i = (i + 1) mod 256" i := (i + 1) bitAnd: 255. "j = (j + Si) mod 256" si := sBox at: i + 1. j := (j + si) bitAnd: 255. "swap Si and Sj" sj := sBox at: j + 1. sBox at: i + 1 put: sj. sBox at: j + 1 put: si. "t = (Si + Sj) mod 256 K = St" ^aByte bitXor: (sBox at: ((si + sj) bitAnd: 255) + 1)
</methods> <methods> Security.ARC4 <category>initialization</category>
setKey: aByteArray "Note that due to the nature of the SBox initialization algorithm it doesn't make sense to pass in a ByteArray of size bigger than 256. Anything above that mark will be simply ignored" | kBox step | kBox := ByteArray new: 256. step := aByteArray size min: kBox size. 1 to: 256 by: step do: [ :start | kBox replaceFrom: start to: (start + step - 1 min: 256) with: aByteArray startingAt: 1 ]. "Algorithm definition is included in the comments, note that we need to adjust for the 0-based indexing" sBox := (0 to: 255) inject: (ByteArray new: 256) into: [ :array :index | array at: index + 1 put: index; yourself ]. i := 1. j := 0. "for i = 0 to 255:" [ i < 257] whileTrue: [ | s | "j = (j + Si + Ki) mod 256" j := (j + (sBox at: i) + (kBox at: i)) bitAnd: 255. "swap Si and Sj" s := sBox at: i. sBox at: i put: (sBox at: j + 1). sBox at: j + 1 put: s. i := i + 1 ]. "Reset the indexes" i := 0. j := 0
</methods> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>StreamCipher</name> <environment>Security</environment> <super>Security.SymmetricCipher</super> <private>false</private> none <imports></imports> <category>Security-Ciphers</category> <attributes> <package>CiphersBase</package> </attributes> </class>