From VisualWorks®, 7.6 of February 1, 2008 on February 1, 2008 at 12:31:36 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>AESWord</name> <environment>Security</environment> <super>Core.Object</super> <private>false</private> none first second third fourth <imports></imports> <category>Rijndael</category> <attributes> <package>AES</package> </attributes> </class> <comment> Security.AESWord
Represents a 32-bit word as defined in section 3.5 of FIPS 197. Used as an AESState column (see section 3.5 of FIPS 197). Knows how to read/write itself from/to a ByteArray and a handful of useful AES transformations. Instance Variables: first <SmallInteger> first byte second <SmallInteger> second byte third <SmallInteger> third byte fourth <SmallInteger> fourth byte
</comment> <class> <name>AESState</name> <environment>Security</environment> <super>Security.AESWord</super> <private>false</private> none <imports></imports> <category>Rijndael</category> <attributes> <package>AES</package> </attributes> </class> <comment> Security.AESState
Represents AES state as described in section 3.5 of FIPS 197. The four columns are held in instance variables first, second, third, fourth (instances of AESWord). Knows how to read/write itself from/to a ByteArray and a handful of useful AES transformations.
</comment> <class> <name>AESInvalidKey</name> <environment>Security</environment> <super>Core.Error</super> <private>false</private> none <imports></imports> <category>Rijndael</category> <attributes> <package>AES</package> </attributes> </class> <class> <name>AES</name> <environment>Security</environment> <super>Security.BlockCipher</super> <private>false</private> none rounds keySchedule <imports></imports> <category>Rijndael</category> <attributes> <package>AES</package> </attributes> </class> <comment> Security.AES
Implements the Advanced Encryption Standard (AES) as described in FIPS 197 (see http://csrc.nist.gov/encryption/aes for details). This implementation focuses on the AES specification thus supporting only the key and block sizes described there, i.e. block size is always 128 bits (16 bytes) and the allowed key sizes are 128, 192 and 256 bits (16, 24 and 32 bytes respectively). Instance Variables: keySchedule <(Array of: AESWord)> key schedule generated for a given key rounds <SmallInteger> number of rounds of the algorithm (depends on the key size)
</comment> <name>KeySizeToRounds</name> <environment>Security.AES</environment> <private>false</private> <constant>false</constant> <category>constants</category> <initializer>AES keySizeToRounds</initializer> <attributes> <package>AES</package> </attributes> <name>SBox</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord sBox</initializer> <attributes> <package>AES</package> </attributes> <name>TimesD</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord timesD</initializer> <attributes> <package>AES</package> </attributes> <name>TimesB</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord timesB</initializer> <attributes> <package>AES</package> </attributes> <name>TimesE</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord timesE</initializer> <attributes> <package>AES</package> </attributes> <name>Times2</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord times2</initializer> <attributes> <package>AES</package> </attributes> <name>ISBox</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord isBox</initializer> <attributes> <package>AES</package> </attributes> <name>Times3</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord times3</initializer> <attributes> <package>AES</package> </attributes> <name>Times9</name> <environment>Security.AESWord</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>AESWord times9</initializer> <attributes> <package>AES</package> </attributes> <methods> Security.AESWord <category>accessing</category>
first ^first
first: anObject first := anObject
fourth ^fourth
fourth: anObject fourth := anObject
second ^second
second: anObject second := anObject
third ^third
third: anObject third := anObject
</methods> <methods> Security.AESWord <category>transformations</category>
addRoundKey: aColumn "AddRoundKey() transformation. As described in section 5.1.4 of FIPS 197." first := first bitXor: aColumn first. second := second bitXor: aColumn second. third := third bitXor: aColumn third. fourth := fourth bitXor: aColumn fourth.
invMixColumns "InvMixColumns() transformation. As described in section 5.3.3 of FIPS 197." | first1 second1 third1 fourth1 | first := ( ( (TimesE at: (first1 := first + 1)) bitXor: (TimesB at: (second1 := second + 1)) ) bitXor: (TimesD at: (third1 := third + 1)) ) bitXor: (Times9 at: (fourth1 := fourth + 1)). second := ( ( (Times9 at: first1) bitXor: (TimesE at: second1) ) bitXor: (TimesB at: third1) ) bitXor: (TimesD at: fourth1). third := ( ( (TimesD at: first1) bitXor: (Times9 at: second1) ) bitXor: (TimesE at: third1) ) bitXor: (TimesB at: fourth1). fourth := ( ( (TimesB at: first1) bitXor: (TimesD at: second1) ) bitXor: (Times9 at: third1) ) bitXor: (TimesE at: fourth1)
invSubBytes "InvSubBytes() transformation. As described in section 5.3.2 of FIPS 197." first := ISBox at: first + 1. second := ISBox at: second + 1. third := ISBox at: third + 1. fourth := ISBox at: fourth + 1
mixColumns "MixColumns() transformation. As described in section 5.1.3 of FIPS 197." | newFirst newSecond newThird | newFirst := ( ( (Times2 at: first + 1) bitXor: (Times3 at: second + 1) ) bitXor: third ) bitXor: fourth. newSecond := ( ( first bitXor: (Times2 at: second + 1) ) bitXor: (Times3 at: third + 1) ) bitXor: fourth. newThird := ( ( first bitXor: second ) bitXor: (Times2 at: third + 1) ) bitXor: (Times3 at: fourth + 1). fourth := ( ( (Times3 at: first + 1) bitXor: second ) bitXor: third ) bitXor: (Times2 at: fourth + 1). first := newFirst. second := newSecond. third := newThird
rotWord "RotWord() key expansion function. As described in section 5.2 of FIPS 197." | temp | temp := first. first := second. second := third. third := fourth. fourth := temp.
subBytes "SubBytes() transformation. As described in section 5.1.1 of FIPS 197." first := SBox at: first + 1. second := SBox at: second + 1. third := SBox at: third + 1. fourth := SBox at: fourth + 1
</methods> <methods> Security.AESWord <category>read/write</category>
from: aByteObject startingAt: index "Read according to the AES rules for state input as described in section 3.4 of FIPS 197" first := aByteObject at: index. second := aByteObject at: index + 1. third := aByteObject at: index + 2. fourth := aByteObject at: index + 3.
to: aByteObject startingAt: index "Write according to the AES rules for state output as described in section 3.4 of FIPS 197" aByteObject at: index put: first. aByteObject at: index + 1 put: second. aByteObject at: index + 2 put: third. aByteObject at: index + 3 put: fourth
</methods> <methods> Security.AESWord <category>printing</category>
printOn: aStream "print itself as an 8 digit hex number" first printOn: aStream base: 16 digitsToPad: 2 highDigit: 2. second printOn: aStream base: 16 digitsToPad: 2 highDigit: 2. third printOn: aStream base: 16 digitsToPad: 2 highDigit: 2. fourth printOn: aStream base: 16 digitsToPad: 2 highDigit: 2.
</methods> <methods> Security.AESWord class <category>constants</category>
isBox "Copy from Figure 14 of FIPS 197." ^#[ 16r52 16r09 16r6a 16rd5 16r30 16r36 16ra5 16r38 16rbf 16r40 16ra3 16r9e 16r81 16rf3 16rd7 16rfb 16r7c 16re3 16r39 16r82 16r9b 16r2f 16rff 16r87 16r34 16r8e 16r43 16r44 16rc4 16rde 16re9 16rcb 16r54 16r7b 16r94 16r32 16ra6 16rc2 16r23 16r3d 16ree 16r4c 16r95 16r0b 16r42 16rfa 16rc3 16r4e 16r08 16r2e 16ra1 16r66 16r28 16rd9 16r24 16rb2 16r76 16r5b 16ra2 16r49 16r6d 16r8b 16rd1 16r25 16r72 16rf8 16rf6 16r64 16r86 16r68 16r98 16r16 16rd4 16ra4 16r5c 16rcc 16r5d 16r65 16rb6 16r92 16r6c 16r70 16r48 16r50 16rfd 16red 16rb9 16rda 16r5e 16r15 16r46 16r57 16ra7 16r8d 16r9d 16r84 16r90 16rd8 16rab 16r00 16r8c 16rbc 16rd3 16r0a 16rf7 16re4 16r58 16r05 16rb8 16rb3 16r45 16r06 16rd0 16r2c 16r1e 16r8f 16rca 16r3f 16r0f 16r02 16rc1 16raf 16rbd 16r03 16r01 16r13 16r8a 16r6b 16r3a 16r91 16r11 16r41 16r4f 16r67 16rdc 16rea 16r97 16rf2 16rcf 16rce 16rf0 16rb4 16re6 16r73 16r96 16rac 16r74 16r22 16re7 16rad 16r35 16r85 16re2 16rf9 16r37 16re8 16r1c 16r75 16rdf 16r6e 16r47 16rf1 16r1a 16r71 16r1d 16r29 16rc5 16r89 16r6f 16rb7 16r62 16r0e 16raa 16r18 16rbe 16r1b 16rfc 16r56 16r3e 16r4b 16rc6 16rd2 16r79 16r20 16r9a 16rdb 16rc0 16rfe 16r78 16rcd 16r5a 16rf4 16r1f 16rdd 16ra8 16r33 16r88 16r07 16rc7 16r31 16rb1 16r12 16r10 16r59 16r27 16r80 16rec 16r5f 16r60 16r51 16r7f 16ra9 16r19 16rb5 16r4a 16r0d 16r2d 16re5 16r7a 16r9f 16r93 16rc9 16r9c 16ref 16ra0 16re0 16r3b 16r4d 16rae 16r2a 16rf5 16rb0 16rc8 16reb 16rbb 16r3c 16r83 16r53 16r99 16r61 16r17 16r2b 16r04 16r7e 16rba 16r77 16rd6 16r26 16re1 16r69 16r14 16r63 16r55 16r21 16r0c 16r7d]
sBox "Copy from Figure 7 of FIPS 197." ^#[ 16r63 16r7c 16r77 16r7b 16rf2 16r6b 16r6f 16rc5 16r30 16r01 16r67 16r2b 16rfe 16rd7 16rab 16r76 16rca 16r82 16rc9 16r7d 16rfa 16r59 16r47 16rf0 16rad 16rd4 16ra2 16raf 16r9c 16ra4 16r72 16rc0 16rb7 16rfd 16r93 16r26 16r36 16r3f 16rf7 16rcc 16r34 16ra5 16re5 16rf1 16r71 16rd8 16r31 16r15 16r04 16rc7 16r23 16rc3 16r18 16r96 16r05 16r9a 16r07 16r12 16r80 16re2 16reb 16r27 16rb2 16r75 16r09 16r83 16r2c 16r1a 16r1b 16r6e 16r5a 16ra0 16r52 16r3b 16rd6 16rb3 16r29 16re3 16r2f 16r84 16r53 16rd1 16r00 16red 16r20 16rfc 16rb1 16r5b 16r6a 16rcb 16rbe 16r39 16r4a 16r4c 16r58 16rcf 16rd0 16ref 16raa 16rfb 16r43 16r4d 16r33 16r85 16r45 16rf9 16r02 16r7f 16r50 16r3c 16r9f 16ra8 16r51 16ra3 16r40 16r8f 16r92 16r9d 16r38 16rf5 16rbc 16rb6 16rda 16r21 16r10 16rff 16rf3 16rd2 16rcd 16r0c 16r13 16rec 16r5f 16r97 16r44 16r17 16rc4 16ra7 16r7e 16r3d 16r64 16r5d 16r19 16r73 16r60 16r81 16r4f 16rdc 16r22 16r2a 16r90 16r88 16r46 16ree 16rb8 16r14 16rde 16r5e 16r0b 16rdb 16re0 16r32 16r3a 16r0a 16r49 16r06 16r24 16r5c 16rc2 16rd3 16rac 16r62 16r91 16r95 16re4 16r79 16re7 16rc8 16r37 16r6d 16r8d 16rd5 16r4e 16ra9 16r6c 16r56 16rf4 16rea 16r65 16r7a 16rae 16r08 16rba 16r78 16r25 16r2e 16r1c 16ra6 16rb4 16rc6 16re8 16rdd 16r74 16r1f 16r4b 16rbd 16r8b 16r8a 16r70 16r3e 16rb5 16r66 16r48 16r03 16rf6 16r0e 16r61 16r35 16r57 16rb9 16r86 16rc1 16r1d 16r9e 16re1 16rf8 16r98 16r11 16r69 16rd9 16r8e 16r94 16r9b 16r1e 16r87 16re9 16rce 16r55 16r28 16rdf 16r8c 16ra1 16r89 16r0d 16rbf 16re6 16r42 16r68 16r41 16r99 16r2d 16r0f 16rb0 16r54 16rbb 16r16]
times2 "Lookup table for multiplication by a constant polynomial 'x' (=16r2) in GF(2^8) modulo 16r11B (= 283). Generated as follows: ((0 to: 255) inject: String new writeStream into: [ :str :i | str print: i gf256Mod283Times2; space; yourself ]) contents" ^#[0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 178 180 182 184 186 188 190 192 194 196 198 200 202 204 206 208 210 212 214 216 218 220 222 224 226 228 230 232 234 236 238 240 242 244 246 248 250 252 254 27 25 31 29 19 17 23 21 11 9 15 13 3 1 7 5 59 57 63 61 51 49 55 53 43 41 47 45 35 33 39 37 91 89 95 93 83 81 87 85 75 73 79 77 67 65 71 69 123 121 127 125 115 113 119 117 107 105 111 109 99 97 103 101 155 153 159 157 147 145 151 149 139 137 143 141 131 129 135 133 187 185 191 189 179 177 183 181 171 169 175 173 163 161 167 165 219 217 223 221 211 209 215 213 203 201 207 205 195 193 199 197 251 249 255 253 243 241 247 245 235 233 239 237 227 225 231 229]
times3 "Lookup table for multiplication by a constant polynomial 'x + 1' (=16r3) in GF(2^8) modulo 16r11B (= 283). Generated as follows: ((0 to: 255) inject: String new writeStream into: [ :str :i | str print: i gf256Mod283Times3; space; yourself ]) contents" ^#[0 3 6 5 12 15 10 9 24 27 30 29 20 23 18 17 48 51 54 53 60 63 58 57 40 43 46 45 36 39 34 33 96 99 102 101 108 111 106 105 120 123 126 125 116 119 114 113 80 83 86 85 92 95 90 89 72 75 78 77 68 71 66 65 192 195 198 197 204 207 202 201 216 219 222 221 212 215 210 209 240 243 246 245 252 255 250 249 232 235 238 237 228 231 226 225 160 163 166 165 172 175 170 169 184 187 190 189 180 183 178 177 144 147 150 149 156 159 154 153 136 139 142 141 132 135 130 129 155 152 157 158 151 148 145 146 131 128 133 134 143 140 137 138 171 168 173 174 167 164 161 162 179 176 181 182 191 188 185 186 251 248 253 254 247 244 241 242 227 224 229 230 239 236 233 234 203 200 205 206 199 196 193 194 211 208 213 214 223 220 217 218 91 88 93 94 87 84 81 82 67 64 69 70 79 76 73 74 107 104 109 110 103 100 97 98 115 112 117 118 127 124 121 122 59 56 61 62 55 52 49 50 35 32 37 38 47 44 41 42 11 8 13 14 7 4 1 2 19 16 21 22 31 28 25 26]
times9 "Lookup table for multiplication by a constant polynomial 'x^3 + 1' (=16r9) in GF(2^8) modulo 16r11B (= 283). Generated as follows: ((0 to: 255) inject: String new writeStream into: [ :str :i | str print: i gf256Mod283Times9; space; yourself ]) contents" ^#[0 9 18 27 36 45 54 63 72 65 90 83 108 101 126 119 144 153 130 139 180 189 166 175 216 209 202 195 252 245 238 231 59 50 41 32 31 22 13 4 115 122 97 104 87 94 69 76 171 162 185 176 143 134 157 148 227 234 241 248 199 206 213 220 118 127 100 109 82 91 64 73 62 55 44 37 26 19 8 1 230 239 244 253 194 203 208 217 174 167 188 181 138 131 152 145 77 68 95 86 105 96 123 114 5 12 23 30 33 40 51 58 221 212 207 198 249 240 235 226 149 156 135 142 177 184 163 170 236 229 254 247 200 193 218 211 164 173 182 191 128 137 146 155 124 117 110 103 88 81 74 67 52 61 38 47 16 25 2 11 215 222 197 204 243 250 225 232 159 150 141 132 187 178 169 160 71 78 85 92 99 106 113 120 15 6 29 20 43 34 57 48 154 147 136 129 190 183 172 165 210 219 192 201 246 255 228 237 10 3 24 17 46 39 60 53 66 75 80 89 102 111 116 125 161 168 179 186 133 140 151 158 233 224 251 242 205 196 223 214 49 56 35 42 21 28 7 14 121 112 107 98 93 84 79 70]
timesB "Lookup table for multiplication by a constant polynomial 'x^3 + x + 1' (=16rB) in GF(2^8) modulo 16r11B (= 283). Generated as follows: ((0 to: 255) inject: String new writeStream into: [ :str :i | str print: i gf256Mod283TimesB; space; yourself ]) contents" ^#[0 11 22 29 44 39 58 49 88 83 78 69 116 127 98 105 176 187 166 173 156 151 138 129 232 227 254 245 196 207 210 217 123 112 109 102 87 92 65 74 35 40 53 62 15 4 25 18 203 192 221 214 231 236 241 250 147 152 133 142 191 180 169 162 246 253 224 235 218 209 204 199 174 165 184 179 130 137 148 159 70 77 80 91 106 97 124 119 30 21 8 3 50 57 36 47 141 134 155 144 161 170 183 188 213 222 195 200 249 242 239 228 61 54 43 32 17 26 7 12 101 110 115 120 73 66 95 84 247 252 225 234 219 208 205 198 175 164 185 178 131 136 149 158 71 76 81 90 107 96 125 118 31 20 9 2 51 56 37 46 140 135 154 145 160 171 182 189 212 223 194 201 248 243 238 229 60 55 42 33 16 27 6 13 100 111 114 121 72 67 94 85 1 10 23 28 45 38 59 48 89 82 79 68 117 126 99 104 177 186 167 172 157 150 139 128 233 226 255 244 197 206 211 216 122 113 108 103 86 93 64 75 34 41 52 63 14 5 24 19 202 193 220 215 230 237 240 251 146 153 132 143 190 181 168 163]
timesD "Lookup table for multiplication by a constant polynomial 'x^3 + x^2 + 1' (=16rD) in GF(2^8) modulo 16r11B (= 283). Generated as follows: ((0 to: 255) inject: String new writeStream into: [ :str :i | str print: i gf256Mod283TimesD; space; yourself ]) contents" ^#[0 13 26 23 52 57 46 35 104 101 114 127 92 81 70 75 208 221 202 199 228 233 254 243 184 181 162 175 140 129 150 155 187 182 161 172 143 130 149 152 211 222 201 196 231 234 253 240 107 102 113 124 95 82 69 72 3 14 25 20 55 58 45 32 109 96 119 122 89 84 67 78 5 8 31 18 49 60 43 38 189 176 167 170 137 132 147 158 213 216 207 194 225 236 251 246 214 219 204 193 226 239 248 245 190 179 164 169 138 135 144 157 6 11 28 17 50 63 40 37 110 99 116 121 90 87 64 77 218 215 192 205 238 227 244 249 178 191 168 165 134 139 156 145 10 7 16 29 62 51 36 41 98 111 120 117 86 91 76 65 97 108 123 118 85 88 79 66 9 4 19 30 61 48 39 42 177 188 171 166 133 136 159 146 217 212 195 206 237 224 247 250 183 186 173 160 131 142 153 148 223 210 197 200 235 230 241 252 103 106 125 112 83 94 73 68 15 2 21 24 59 54 33 44 12 1 22 27 56 53 34 47 100 105 126 115 80 93 74 71 220 209 198 203 232 229 242 255 180 185 174 163 128 141 154 151]
timesE "Lookup table for multiplication by a constant polynomial 'x^3 + x^2 + x' (=16rE) in GF(2^8) modulo 16r11B (= 283). Generated as follows: ((0 to: 255) inject: String new writeStream into: [ :str :i | str print: i gf256Mod283TimesE; space; yourself ]) contents" ^#[0 14 28 18 56 54 36 42 112 126 108 98 72 70 84 90 224 238 252 242 216 214 196 202 144 158 140 130 168 166 180 186 219 213 199 201 227 237 255 241 171 165 183 185 147 157 143 129 59 53 39 41 3 13 31 17 75 69 87 89 115 125 111 97 173 163 177 191 149 155 137 135 221 211 193 207 229 235 249 247 77 67 81 95 117 123 105 103 61 51 33 47 5 11 25 23 118 120 106 100 78 64 82 92 6 8 26 20 62 48 34 44 150 152 138 132 174 160 178 188 230 232 250 244 222 208 194 204 65 79 93 83 121 119 101 107 49 63 45 35 9 7 21 27 161 175 189 179 153 151 133 139 209 223 205 195 233 231 245 251 154 148 134 136 162 172 190 176 234 228 246 248 210 220 206 192 122 116 102 104 66 76 94 80 10 4 22 24 50 60 46 32 236 226 240 254 212 218 200 198 156 146 128 142 164 170 184 182 12 2 16 30 52 58 40 38 124 114 96 110 68 74 88 86 55 57 43 37 15 1 19 29 71 73 91 85 127 113 99 109 215 217 203 197 239 225 243 253 167 169 187 181 159 145 131 141]
</methods> <methods> Security.AESWord class <category>instance creation</category>
from: aByteObject startingAt: index ^self new from: aByteObject startingAt: index
</methods> <methods> Security.AESState <category>transformations</category>
addRound: anInteger keys: aKeySchedule "AddRoundKey() transformation. As described in section 5.1.4 of FIPS 197." | index | index := 4 * anInteger. first addRoundKey: (aKeySchedule at: index + 1). second addRoundKey: (aKeySchedule at: index + 2). third addRoundKey: (aKeySchedule at: index + 3). fourth addRoundKey: (aKeySchedule at: index + 4).
invMixColumns "InvMixColumns() transformation. As described in section 5.3.3 of FIPS 197." first invMixColumns. second invMixColumns. third invMixColumns. fourth invMixColumns.
invShiftRows "InvShiftRows() transformation. As described in section 5.3.1 of FIPS 197." | temp | "Circular right shift second row by 1" temp := fourth second. fourth second: third second. third second: second second. second second: first second. first second: temp. "Circular right shift third row by 2" temp := first third. first third: third third. third third: temp. temp := second third. second third: fourth third. fourth third: temp. "Circular right shift fourth row by 3" temp := first fourth. first fourth: second fourth. second fourth: third fourth. third fourth: fourth fourth. fourth fourth: temp.
invSubBytes "InvSubBytes() transformation. As described in section 5.3.2 of FIPS 197." first invSubBytes. second invSubBytes. third invSubBytes. fourth invSubBytes.
mixColumns "MixColumns() transformation. As described in section 5.1.3 of FIPS 197." first mixColumns. second mixColumns. third mixColumns. fourth mixColumns.
shiftRows "ShiftRows() transformation. As described in section 5.1.2 of FIPS 197." | temp | "Circular left shift second row by 1" temp := first second. first second: second second. second second: third second. third second: fourth second. fourth second: temp. "Circular left shift third row by 2" temp := first third. first third: third third. third third: temp. temp := second third. second third: fourth third. fourth third: temp. "Circular left shift fourth row by 3" temp := fourth fourth. fourth fourth: third fourth. third fourth: second fourth. second fourth: first fourth. first fourth: temp.
subBytes "SubBytes() transformation. As described in section 5.1.1 of FIPS 197." first subBytes. second subBytes. third subBytes. fourth subBytes.
</methods> <methods> Security.AESState <category>read/write</category>
from: aByteObject startingAt: index "Read according to the AES rules for state input as described in section 3.4 of FIPS 197" first := AESWord from: aByteObject startingAt: index. second := AESWord from: aByteObject startingAt: index + 4. third := AESWord from: aByteObject startingAt: index + 8. fourth := AESWord from: aByteObject startingAt: index + 12.
to: aByteObject startingAt: index "Write according to the AES rules for state output as described in section 3.4 of FIPS 197" first to: aByteObject startingAt: index. second to: aByteObject startingAt: index + 4. third to: aByteObject startingAt: index + 8. fourth to: aByteObject startingAt: index + 12
</methods> <methods> Security.AESState <category>printing</category>
printOn: aStream aStream nextPut: $(; print: first; space; print: second; space; print: third; space; print: fourth; nextPut: $)
</methods> <methods> Security.AES <category>services</category>
decryptInPlace: aByteArray at: start "Decrypt in place one block of <aByteArray> at postion <start>. Block size is defined by the encryption algorithm." | state | "input state" state := AESState from: aByteArray startingAt: start. "initial key addition" state addRound: rounds keys: keySchedule. "rounds" rounds - 1 to: 1 by: -1 do: [ :round | state invShiftRows; invSubBytes; addRound: round keys: keySchedule; invMixColumns]. "final round" state invShiftRows; invSubBytes; addRound: 0 keys: keySchedule. "output state" state to: aByteArray startingAt: start
encryptInPlace: aByteArray at: start "Encrypt in place one block of <aByteArray> at postion <start>. Block size is defined by the encryption algorithm." | state | "input state" state := AESState from: aByteArray startingAt: start. "initial key addition" state addRound: 0 keys: keySchedule. "rounds" 1 to: rounds - 1 do: [ :round | state subBytes; shiftRows; mixColumns; addRound: round keys: keySchedule ]. "final round" state subBytes; shiftRows; addRound: rounds keys: keySchedule. "output state" state to: aByteArray startingAt: start
</methods> <methods> Security.AES <category>accessing</category>
keySchedule ^keySchedule
rounds ^rounds
</methods> <methods> Security.AES <category>initialization</category>
setKey: aByteArray "Initialize the cipher with the given key. The key size should be one of 16, 24 or 32 bytes" "Number of rounds depends on the key size as follows: (keySize -> rounds): 16 -> 10, 24 -> 12, 32 -> 14" | nk rCon | rounds := KeySizeToRounds at: aByteArray size ifAbsent: [ AESInvalidKey raiseSignal: (#InvalidKeySize << #security >> 'Invalid key size (must be 16, 24 or 32 bytes)!') ]. nk := aByteArray size / 4. keySchedule := Array new: (rounds + 1) * 4. "rCon is a sequence of powers of 'x' in GF(2^8). Which can be generated using (1 to: 20) inject: (OrderedCollection with: 1) into: [ :seq :i | seq add: seq last gf256Mod283XTime; yourself ] => OrderedCollection (1 2 4 8 16 32 64 128 27 54 108 216 171 77 154 47 94 188 99 198 151) AES only needs about 11 values though." rCon := #[1 2 4 8 16 32 64 128 27 54 108 216 171 77 154]. 1 to: nk do: [ :i | keySchedule at: i put: (AESWord from: aByteArray startingAt: i * 4 - 3)]. nk to: keySchedule size - 1 do: [ :i || temp | temp := (keySchedule at: i "- 1 + 1") copy. "Note that: a) RijndaelColumn>>xor: == RijndaelColumn>>addRoundKey: b) RijndaelColumn>>subWord == RijndaelColumn>>subBytes" (i \\ nk) isZero ifTrue: [ temp rotWord subBytes. temp first: (temp first bitXor: (rCon at: i // nk)) ] ifFalse: [ (nk > 6 and: [ i \\ nk = 4 ]) ifTrue: [ temp subBytes ] ]. temp addRoundKey: (keySchedule at: (i - nk + 1)). keySchedule at: i + 1 put: temp ]
</methods> <methods> Security.AES class <category>constants</category>
keySizeToRounds ^Dictionary new at: 16 put: 10; at: 24 put: 12; at: 32 put: 14; yourself
</methods> <methods> Security.AES class <category>accessing</category>
blockSize ^16
</methods> <methods> Core.SmallInteger <category>security - aes</category>
gf256Mod283Times2 "Multiplication by a constant polynomial 'x' (=16r2) in GF(2^8) modulo 16r11B (= 283)" ^self gf256Mod283XTime
gf256Mod283Times3 "Multiplication by a constant polynomial 'x + 1' (=16r3) in GF(2^8) modulo 16r11B (= 283)" ^self bitXor: self gf256Mod283XTime
gf256Mod283Times9 "Multiplication by a constant polynomial 'x^3 + 1' (=16r9) in GF(2^8) modulo 16r11B (= 283)" ^self bitXor: self gf256Mod283XTime gf256Mod283XTime gf256Mod283XTime
gf256Mod283Times: anInteger "Multiplication in GF(2^8) modulo 16r11B (= 283). As described in section 4.2 of FIPS 197. For the purpuses of AEM we can expect an integer to be in the range 2 - 15" | xtime | xtime := self. ^#[2 4 8 16 32 64 128] inject: ((anInteger bitAnd: 1) isZero ifTrue: [0] ifFalse: [self]) into: [ :ttl :pwr | xtime := xtime gf256Mod283XTime. (anInteger bitAnd: pwr) isZero ifTrue: [ ttl ] ifFalse: [ ttl bitXor: xtime ]]
gf256Mod283TimesB "Multiplication by a constant polynomial 'x^3 + x + 1' (=16rB) in GF(2^8) modulo 16r11B (= 283)" | x | ^(self bitXor: (x := self gf256Mod283XTime)) bitXor: x gf256Mod283XTime gf256Mod283XTime
gf256Mod283TimesD "Multiplication by a constant polynomial 'x^3 + x^2 + 1' (=16rD) in GF(2^8) modulo 16r11B (= 283)" | x | ^(self bitXor: (x := self gf256Mod283XTime gf256Mod283XTime)) bitXor: x gf256Mod283XTime
gf256Mod283TimesE "Multiplication by a constant polynomial 'x^3 + x^2 + x' (=16rE) in GF(2^8) modulo 16r11B (= 283)" | x | ^((x := self gf256Mod283XTime) bitXor: (x := x gf256Mod283XTime)) bitXor: x gf256Mod283XTime
gf256Mod283XTime "Multiplication by a constant polynomial 'x' (=16r2) in GF(2^8) modulo 16r11B (= 283). As described in section 4.2.1 in FIPS 197." ^(self bitAnd: 128) isZero ifTrue: [ self bitShift: 1] ifFalse: [ (self bitShift: 1) bitXor: 16r11B ]
</methods> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>SmallInteger</name> <environment>Core</environment> <super>Core.Integer</super> <private>false</private> immediate minVal maxVal maxBits maxBytes <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>BlockCipher</name> <environment>Security</environment> <super>Security.SymmetricCipher</super> <private>false</private> none blockSize <imports></imports> <category>Security-Ciphers</category> <attributes> <package>CiphersBase</package> </attributes> </class> <class> <name>Error</name> <environment>Core</environment> <super>Core.Exception</super> <private>false</private> none <imports></imports> <category>Kernel-Exception Handling</category> <attributes> <package>Kernel-Exception Handling</package> </attributes> </class>