[squeak-dev] The Inbox: CryptographyPlugins-mt.25.mcz

Marcel Taeumel marcel.taeumel at hpi.de
Mon Dec 13 10:17:14 UTC 2021


Hi Eliot, hi Levente --

Here is a fix for Windows 64-bit and all 32-bit platforms. I have no write access in the Cryptography repository.

Please ignore the text diff here. It is wrong. I just changed SHA2Plugin >> #copyDoubleWords:into:count:.

Best,
Marcel
Am 13.12.2021 11:14:46 schrieb commits at source.squeak.org <commits at source.squeak.org>:
A new version of CryptographyPlugins was added to project The Inbox:
http://source.squeak.org/inbox/CryptographyPlugins-mt.25.mcz

==================== Summary ====================

Name: CryptographyPlugins-mt.25
Author: mt
Time: 13 December 2021, 11:10:27.539788 am
UUID: 198be26c-3a58-ff48-8855-8670e598627b
Ancestors: CryptographyPlugins-eem.24

Fixes type-casting issue on Windows 64-bit systems. We must use "long long" if we mean "double word".

==================== Snapshot ====================

SystemOrganization addCategory: #CryptographyPlugins!

InterpreterPlugin subclass: #DESPlugin
instanceVariableNames: 'byteBit bigByte pc1 pc2 totRot sp1 sp2 sp3 sp4 sp5 sp6 sp7 sp8'
classVariableNames: ''
poolDictionaries: ''
category: 'CryptographyPlugins'!

!DESPlugin commentStamp: '' prior: 0!
This plugin implements the Data Encryption Standard (DES).

You should build this plugin with the module name 'DESPrims'.

See class comments for 'DES' for usage.

Submitted by Duane Maxwell
!

----- Method: DESPlugin class>>declareCVarsIn: (in category 'translation') -----
declareCVarsIn: cg
cg var: 'byteBit' declareC: 'unsigned short byteBit[8] = {
128,64,32,16,8,4,2,1 }'.
cg var: 'bigByte' declareC:
(String streamContents:[:s|
s nextPutAll:'unsigned int bigByte[24] = { '.
23 to: 0 by: -1 do: [ :i |
s nextPutAll: (1
s nextPutAll:' }']).
cg var: 'pc1' declareC: 'unsigned char pc1[56] = {
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }'.
cg var: 'pc2' declareC: 'unsigned char pc2[48] = {
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }'.
cg var: 'totRot' declareC:
'unsigned char totRot[16] = { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }'.
cg var: 'sp1' declareC: 'unsigned int sp1[64] = {
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004L }'.
cg var: 'sp2' declareC: 'unsigned int sp2[64] = {
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000L }'.
cg var: 'sp3' declareC: 'unsigned int sp3[64] = {
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200L }'.
cg var: 'sp4' declareC: 'unsigned int sp4[64] = {
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080L }'.
cg var: 'sp5' declareC: 'unsigned int sp5[64] = {
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100 }'.
cg var: 'sp6' declareC: 'unsigned int sp6[64] = {
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010L }'.
cg var: 'sp7' declareC: 'unsigned int sp7[64] = {
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002 }'.
cg var: 'sp8' declareC: 'unsigned int sp8[64] = {
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000 }'.


!

----- Method: DESPlugin class>>simulatorClass (in category 'simulation') -----
simulatorClass
^DESPluginSimulator!

----- Method: DESPlugin>>cookKey:to: (in category 'support') -----
cookKey: rawPtr to: cookPtr
"preprocess the key to more useful format"

| raw0 raw1 cook |

"32 words"
"32 words"


0 to: 15 do: [ :i |
raw0 := rawPtr at: i*2.
raw1 := rawPtr at: i*2 + 1.
cook := (raw0 bitAnd: 16r00FC0000)
cook := cook bitOr: (raw0 bitAnd: 16r00000FC0)
cook := cook bitOr: (raw1 bitAnd: 16r00FC0000) >> 10.
cook := cook bitOr: (raw1 bitAnd: 16r00000FC0) >> 6.
cookPtr at: (i * 2) put: cook.
cook := (raw0 bitAnd: 16r0003F000)
cook := cook bitOr: (raw0 bitAnd: 16r0000003F)
cook := cook bitOr: (raw1 bitAnd: 16r0003F000) >> 4.
cook := cook bitOr: (raw1 bitAnd: 16r0000003F).
cookPtr at: (i*2+1) put: cook.
].

!

----- Method: DESPlugin>>encrypt:with: (in category 'support') -----
encrypt: dataPtr with: key
| fVal work right left |







left := dataPtr at: 0.
right := dataPtr at: 1.

"perform required but otherwise pointless bit twizzling"
work := ((left >> 4) bitXor: right) bitAnd: 16r0F0F0F0F.
right := right bitXor: work.
left := left bitXor: (work
work := ((left >> 16) bitXor: right) bitAnd: 16r0000FFFF.
right := right bitXor: work.
left := left bitXor: (work
work := ((right >> 2) bitXor: left) bitAnd: 16r33333333.
left := left bitXor: work.
right := right bitXor: (work
work := ((right >> 8) bitXor: left) bitAnd: 16r00FF00FF.
left := left bitXor: work.
right := right bitXor: (work
right := ((right > 31) bitAnd: 1)) bitAnd: 16rFFFFFFFF.
work := (left bitXor: right) bitAnd: 16rAAAAAAAA.
left := left bitXor: work.
right := right bitXor: work.
left := ((left > 31) bitAnd: 1)) bitAnd:
16rFFFFFFFF.

"perform the 8 rounds of real encryption"
0 to: 28 by: 4 do: [ :round |
work := right > 4.
work := work bitXor: (key at: round).
fVal := sp7 at: (work bitAnd: 16r3F).
fVal := fVal bitOr: (sp5 at: (work >> 8 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp3 at: (work >> 16 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp1 at: (work >> 24 bitAnd: 16r3F)).

work := right bitXor: (key at: round+1).
fVal := fVal bitOr: (sp8 at: (work bitAnd: 16r3F)).
fVal := fVal bitOr: (sp6 at: (work >> 8 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp4 at: (work >> 16 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp2 at: (work >> 24 bitAnd: 16r3F)).
left := left bitXor: fVal.

work := left > 4.
work := work bitXor: (key at: round+2).
fVal := sp7 at: (work bitAnd: 16r3F).
fVal := fVal bitOr: (sp5 at: (work >> 8 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp3 at: (work >> 16 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp1 at: (work >> 24 bitAnd: 16r3F)).

work := left bitXor: (key at: round+3).
fVal := fVal bitOr: (sp8 at: (work bitAnd: 16r3F)).
fVal := fVal bitOr: (sp6 at: (work >> 8 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp4 at: (work >> 16 bitAnd: 16r3F)).
fVal := fVal bitOr: (sp2 at: (work >> 24 bitAnd: 16r3F)).
right := right bitXor: fVal.
].

"undo the pointless twizzling"
right := right>1.
work := (left bitXor: right) bitAnd: 16rAAAAAAAA.
left := left bitXor: work.
right := right bitXor: work.
left := left>1.
work := (left>>8 bitXor: right) bitAnd: 16r00FF00FF.
right := right bitXor: work.
left := left bitXor: work
work := (left >> 2 bitXor: right) bitAnd: 16r33333333.
right := right bitXor: work.
left := left bitXor: work
work := (right>>16 bitXor: left) bitAnd: 16r0000FFFF.
left := left bitXor: work.
right := right bitXor: work
work := (right>>4 bitXor: left) bitAnd: 16r0F0F0F0F.
left := left bitXor: work.
right := right bitXor: work

self cCode: [
dataPtr at: 0 put: right.
dataPtr at: 1 put: left.]
inSmalltalk: [
dataPtr at: 0 put: (right bitAnd: 16rFFFFFFFF).
dataPtr at: 1 put: (left bitAnd: 16rFFFFFFFF).]

!

----- Method: DESPlugin>>primitiveDESCookKey (in category 'primitives') -----
primitiveDESCookKey
"preprocess the key to more useful format

param1 = raw key: ByteArray[8]
param2 = 1->encode 0->decode
param3 = cooked key: WordArray[32]"



| rawOop cookedOop encode |
interpreterProxy methodArgumentCount = 3
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
rawOop := interpreterProxy stackValue: 2.
((interpreterProxy isBytes: rawOop)
and: [ (interpreterProxy stSizeOf: rawOop) = 8 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
encode := interpreterProxy stackIntegerValue: 1.
cookedOop := interpreterProxy stackValue: 0.
((interpreterProxy isWords: cookedOop)
and: [ (interpreterProxy stSizeOf: cookedOop) = 32 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
self
processKey: (interpreterProxy firstIndexableField: rawOop)
mode: encode~=0
to: (interpreterProxy firstIndexableField: cookedOop).
interpreterProxy pop: 3!

----- Method: DESPlugin>>primitiveDESPluginAvailable (in category 'primitives') -----
primitiveDESPluginAvailable

interpreterProxy methodReturnBool: true!

----- Method: DESPlugin>>primitiveDESTransform (in category 'primitives') -----
primitiveDESTransform
"encrypt/decrypt some data

param1 = data key: ByteArray[8]
param2 = cooked key: WordArray[32]"


| dataOop work cookedOop data |


self cCode: '/* Hi ho, Hi ho...*/' inSmalltalk: [work := CArrayAccessor on: (WordArray new: 2)].
interpreterProxy methodArgumentCount = 2
ifFalse:[ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
dataOop := interpreterProxy stackValue: 1.
((interpreterProxy isBytes: dataOop)
and: [ (interpreterProxy stSizeOf: dataOop) = 8 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
cookedOop := interpreterProxy stackValue: 0.
((interpreterProxy isWords: cookedOop)
and: [ (interpreterProxy stSizeOf: cookedOop) = 32 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
data := interpreterProxy firstIndexableField: dataOop.
self scrunch: data to: work.
self encrypt: work with: (interpreterProxy firstIndexableField: cookedOop).
self unscrunch: work to: data.
interpreterProxy pop: 2
!

----- Method: DESPlugin>>processKey:mode:to: (in category 'support') -----
processKey: keyPtr mode: encode to: cookedPtr
| l m n pc1m pcr rawKey |





self cCode: '/* Who is Keyser Soze? */' inSmalltalk: [pcr := CArrayAccessor on: (ByteArray new: 56). pc1m := CArrayAccessor on: (ByteArray new: 56). rawKey := CArrayAccessor on: (WordArray new: 32)].
0 to: 55 do: [ :j |
l := pc1 at: j.
m := l bitAnd: 7.
((((keyPtr at: (l >> 3)) bitAnd: (byteBit at: m))) ~= 0)
ifTrue: [ pc1m at: j put: 1 ]
ifFalse: [ pc1m at: j put: 0].
].
0 to: 15 do: [ :i |
encode ifFalse: [ m := 15 - i
n := m + 1.
rawKey at: m put: (rawKey at: n put: 0).
0 to: 27 do: [ :j |
l := j + (totRot at: i).
l
[pcr at: j put: (pc1m at: l-28)].
].
28 to: 55 do: [ :j |
l := j + (totRot at: i).
l
[pcr at: j put: (pc1m at: l-28)].
].
0 to: 23 do: [ :j |
(pcr at: (pc2 at: j)) ~= 0 ifTrue:
[rawKey at: m put: ((rawKey at: m) bitOr:
(bigByte at: j))].
(pcr at: (pc2 at: j+24)) ~= 0 ifTrue:
[rawKey at: n put: ((rawKey at: n) bitOr:
(bigByte at: j))].
].
].
self cookKey: rawKey to: cookedPtr!

----- Method: DESPlugin>>scrunch:to: (in category 'support') -----
scrunch: bytePtr to: wordPtr


wordPtr at: 0 put:
(bytePtr at: 0)
((bytePtr at: 1)
((bytePtr at: 2)
(bytePtr at: 3).
wordPtr at: 1 put:
(bytePtr at: 4)
((bytePtr at: 5)
((bytePtr at: 6)
(bytePtr at: 7)!

----- Method: DESPlugin>>unscrunch:to: (in category 'support') -----
unscrunch: wordPtr to: bytePtr


bytePtr at: 0 put: (((wordPtr at: 0)>>24) bitAnd: 16rFF).
bytePtr at: 1 put: (((wordPtr at: 0)>>16) bitAnd: 16rFF).
bytePtr at: 2 put: (((wordPtr at: 0)>>8) bitAnd: 16rFF).
bytePtr at: 3 put: ((wordPtr at: 0) bitAnd: 16rFF).
bytePtr at: 4 put: (((wordPtr at: 1)>>24) bitAnd: 16rFF).
bytePtr at: 5 put: (((wordPtr at: 1)>>16) bitAnd: 16rFF).
bytePtr at: 6 put: (((wordPtr at: 1)>>8) bitAnd: 16rFF).
bytePtr at: 7 put: ((wordPtr at: 1) bitAnd: 16rFF).
!

DESPlugin subclass: #DESPluginSimulator
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CryptographyPlugins'!

----- Method: DESPluginSimulator class>>shouldBeTranslated (in category 'translation') -----
shouldBeTranslated
^false!

----- Method: DESPluginSimulator>>initialize (in category 'initialize-release') -----
initialize
byteBit := CArrayAccessor on: #[ 128 64 32 16 8 4 2 1 ].
bigByte := CArrayAccessor on: ((23 to: 0 by: -1) collect: [:i | 1
pc1 := CArrayAccessor on: #[
56 48 40 32 24 16 8 0 57 49 41 33 25 17
9 1 58 50 42 34 26 18 10 2 59 51 43 35
62 54 46 38 30 22 14 6 61 53 45 37 29 21
13 5 60 52 44 36 28 20 12 4 27 19 11 3 ].
pc2 := CArrayAccessor on: #[
13 16 10 23 0 4 2 27 14 5 20 9
22 18 11 3 25 7 15 6 26 19 12 1
40 51 30 36 46 54 29 39 50 44 32 47
43 48 38 55 33 52 45 41 49 35 28 31 ].
totRot := CArrayAccessor on: #[ 1 2 4 6 8 10 12 14 15 17 19 21 23 25 27 28 ].
sp1 := CArrayAccessor on: #(
16r01010400 16r00000000 16r00010000 16r01010404
16r01010004 16r00010404 16r00000004 16r00010000
16r00000400 16r01010400 16r01010404 16r00000400
16r01000404 16r01010004 16r01000000 16r00000004
16r00000404 16r01000400 16r01000400 16r00010400
16r00010400 16r01010000 16r01010000 16r01000404
16r00010004 16r01000004 16r01000004 16r00010004
16r00000000 16r00000404 16r00010404 16r01000000
16r00010000 16r01010404 16r00000004 16r01010000
16r01010400 16r01000000 16r01000000 16r00000400
16r01010004 16r00010000 16r00010400 16r01000004
16r00000400 16r00000004 16r01000404 16r00010404
16r01010404 16r00010004 16r01010000 16r01000404
16r01000004 16r00000404 16r00010404 16r01010400
16r00000404 16r01000400 16r01000400 16r00000000
16r00010004 16r00010400 16r00000000 16r01010004 ).
sp2 := CArrayAccessor on: #(
16r80108020 16r80008000 16r00008000 16r00108020
16r00100000 16r00000020 16r80100020 16r80008020
16r80000020 16r80108020 16r80108000 16r80000000
16r80008000 16r00100000 16r00000020 16r80100020
16r00108000 16r00100020 16r80008020 16r00000000
16r80000000 16r00008000 16r00108020 16r80100000
16r00100020 16r80000020 16r00000000 16r00108000
16r00008020 16r80108000 16r80100000 16r00008020
16r00000000 16r00108020 16r80100020 16r00100000
16r80008020 16r80100000 16r80108000 16r00008000
16r80100000 16r80008000 16r00000020 16r80108020
16r00108020 16r00000020 16r00008000 16r80000000
16r00008020 16r80108000 16r00100000 16r80000020
16r00100020 16r80008020 16r80000020 16r00100020
16r00108000 16r00000000 16r80008000 16r00008020
16r80000000 16r80100020 16r80108020 16r00108000 ).
sp3 := CArrayAccessor on: #(
16r00000208 16r08020200 16r00000000 16r08020008
16r08000200 16r00000000 16r00020208 16r08000200
16r00020008 16r08000008 16r08000008 16r00020000
16r08020208 16r00020008 16r08020000 16r00000208
16r08000000 16r00000008 16r08020200 16r00000200
16r00020200 16r08020000 16r08020008 16r00020208
16r08000208 16r00020200 16r00020000 16r08000208
16r00000008 16r08020208 16r00000200 16r08000000
16r08020200 16r08000000 16r00020008 16r00000208
16r00020000 16r08020200 16r08000200 16r00000000
16r00000200 16r00020008 16r08020208 16r08000200
16r08000008 16r00000200 16r00000000 16r08020008
16r08000208 16r00020000 16r08000000 16r08020208
16r00000008 16r00020208 16r00020200 16r08000008
16r08020000 16r08000208 16r00000208 16r08020000
16r00020208 16r00000008 16r08020008 16r00020200 ).
sp4 := CArrayAccessor on: #(
16r00802001 16r00002081 16r00002081 16r00000080
16r00802080 16r00800081 16r00800001 16r00002001
16r00000000 16r00802000 16r00802000 16r00802081
16r00000081 16r00000000 16r00800080 16r00800001
16r00000001 16r00002000 16r00800000 16r00802001
16r00000080 16r00800000 16r00002001 16r00002080
16r00800081 16r00000001 16r00002080 16r00800080
16r00002000 16r00802080 16r00802081 16r00000081
16r00800080 16r00800001 16r00802000 16r00802081
16r00000081 16r00000000 16r00000000 16r00802000
16r00002080 16r00800080 16r00800081 16r00000001
16r00802001 16r00002081 16r00002081 16r00000080
16r00802081 16r00000081 16r00000001 16r00002000
16r00800001 16r00002001 16r00802080 16r00800081
16r00002001 16r00002080 16r00800000 16r00802001
16r00000080 16r00800000 16r00002000 16r00802080 ).
sp5 := CArrayAccessor on: #(
16r00000100 16r02080100 16r02080000 16r42000100
16r00080000 16r00000100 16r40000000 16r02080000
16r40080100 16r00080000 16r02000100 16r40080100
16r42000100 16r42080000 16r00080100 16r40000000
16r02000000 16r40080000 16r40080000 16r00000000
16r40000100 16r42080100 16r42080100 16r02000100
16r42080000 16r40000100 16r00000000 16r42000000
16r02080100 16r02000000 16r42000000 16r00080100
16r00080000 16r42000100 16r00000100 16r02000000
16r40000000 16r02080000 16r42000100 16r40080100
16r02000100 16r40000000 16r42080000 16r02080100
16r40080100 16r00000100 16r02000000 16r42080000
16r42080100 16r00080100 16r42000000 16r42080100
16r02080000 16r00000000 16r40080000 16r42000000
16r00080100 16r02000100 16r40000100 16r00080000
16r00000000 16r40080000 16r02080100 16r40000100 ).
sp6 := CArrayAccessor on: #(
16r20000010 16r20400000 16r00004000 16r20404010
16r20400000 16r00000010 16r20404010 16r00400000
16r20004000 16r00404010 16r00400000 16r20000010
16r00400010 16r20004000 16r20000000 16r00004010
16r00000000 16r00400010 16r20004010 16r00004000
16r00404000 16r20004010 16r00000010 16r20400010
16r20400010 16r00000000 16r00404010 16r20404000
16r00004010 16r00404000 16r20404000 16r20000000
16r20004000 16r00000010 16r20400010 16r00404000
16r20404010 16r00400000 16r00004010 16r20000010
16r00400000 16r20004000 16r20000000 16r00004010
16r20000010 16r20404010 16r00404000 16r20400000
16r00404010 16r20404000 16r00000000 16r20400010
16r00000010 16r00004000 16r20400000 16r00404010
16r00004000 16r00400010 16r20004010 16r00000000
16r20404000 16r20000000 16r00400010 16r20004010 ).
sp7 := CArrayAccessor on: #(
16r00200000 16r04200002 16r04000802 16r00000000
16r00000800 16r04000802 16r00200802 16r04200800
16r04200802 16r00200000 16r00000000 16r04000002
16r00000002 16r04000000 16r04200002 16r00000802
16r04000800 16r00200802 16r00200002 16r04000800
16r04000002 16r04200000 16r04200800 16r00200002
16r04200000 16r00000800 16r00000802 16r04200802
16r00200800 16r00000002 16r04000000 16r00200800
16r04000000 16r00200800 16r00200000 16r04000802
16r04000802 16r04200002 16r04200002 16r00000002
16r00200002 16r04000000 16r04000800 16r00200000
16r04200800 16r00000802 16r00200802 16r04200800
16r00000802 16r04000002 16r04200802 16r04200000
16r00200800 16r00000000 16r00000002 16r04200802
16r00000000 16r00200802 16r04200000 16r00000800
16r04000002 16r04000800 16r00000800 16r00200002 ).
sp8 := CArrayAccessor on: #(
16r10001040 16r00001000 16r00040000 16r10041040
16r10000000 16r10001040 16r00000040 16r10000000
16r00040040 16r10040000 16r10041040 16r00041000
16r10041000 16r00041040 16r00001000 16r00000040
16r10040000 16r10000040 16r10001000 16r00001040
16r00041000 16r00040040 16r10040040 16r10041000
16r00001040 16r00000000 16r00000000 16r10040040
16r10000040 16r10001000 16r00041040 16r00040000
16r00041040 16r00040000 16r10041000 16r00001000
16r00000040 16r10040040 16r00001000 16r00041040
16r10001000 16r00000040 16r10000040 16r10040000
16r10040040 16r10000000 16r00040000 16r10001040
16r00000000 16r10041040 16r00040040 16r10000040
16r10040000 16r10001000 16r10001040 16r00000000
16r10041040 16r00041000 16r00041000 16r00001040
16r00001040 16r00040040 16r10000000 16r10041000 ).!

InterpreterPlugin subclass: #DSAPlugin
instanceVariableNames: 'dsaRemainder dsaDivisor dsaQuotient remainderDigitCount divisorDigitCount'
classVariableNames: ''
poolDictionaries: ''
category: 'CryptographyPlugins'!

!DSAPlugin commentStamp: '' prior: 0!
This plugin defines primitives that support the DigitalSignatureAlgorithm class. Three of these primitives support fast multiplication and division of very large integers, three others support the SecureHashAlgorithm.
!

----- Method: DSAPlugin class>>declareCVarsIn: (in category 'translation') -----
declareCVarsIn: cg
cg var: #dsaRemainder type: #'unsigned char*'.
cg var: #dsaDivisor type: #'unsigned char*'.
cg var: #dsaQuotient type: #'unsigned char*'!

----- Method: DSAPlugin class>>moduleName (in category 'translation') -----
moduleName
"Time millisecondsToRun: [
DSAPlugin translateDoInlining: true]"

^ 'DSAPrims' "Yes - it needs to be named this way or else we'll not find it"
!

----- Method: DSAPlugin>>addBackDivisorDigitShift: (in category 'private') -----
addBackDivisorDigitShift: digitShift
"Add back the divisor shifted left by the given number of digits. This is done only when the estimate of quotient digit was one larger than the correct value."

| carry rIndex sum |
carry := 0.
rIndex := digitShift + 1.
1 to: divisorDigitCount do: [:i |
sum := (dsaRemainder at: rIndex) + (dsaDivisor at: i) + carry.
dsaRemainder at: rIndex put: (sum bitAnd: 16rFF).
carry := sum bitShift: -8.
rIndex := rIndex + 1].

"do final carry"
sum := (dsaRemainder at: rIndex) + carry.
dsaRemainder at: rIndex put: (sum bitAnd: 16rFF).

"Note: There should be a final carry that cancels out the excess borrow."
"Assert: (sum bitShift: -8) ~= 1 ifTrue: [self halt: 'no carry!!']."
!

----- Method: DSAPlugin>>bigDivideLoop (in category 'private') -----
bigDivideLoop
"This is the core of the divide algorithm. This loop steps through the digit positions of the quotient, each time estimating the right quotient digit, subtracting from the remainder the divisor times the quotient digit shifted left by the appropriate number of digits. When the loop terminates, all digits of the quotient have been filled in and the remainder contains a value less than the divisor. The tricky bit is estimating the next quotient digit. Knuth shows that the digit estimate computed here will never be less than it should be and cannot be more than one over what it should be. Furthermore, the case where the estimate is one too large is extremely rare. For example, in a typical test of 100000 random 60-bit division problems, the rare case only occured five times. See Knuth, volume 2 ('Semi-Numerical Algorithms') 2nd edition, pp. 257-260"

| d1 d2 firstDigit firstTwoDigits thirdDigit q digitShift qTooBig |
"extract the top two digits of the divisor"
d1 := dsaDivisor at: divisorDigitCount.
d2 := dsaDivisor at: divisorDigitCount - 1.

remainderDigitCount to: divisorDigitCount + 1 by: -1 do: [:j |
"extract the top several digits of remainder."
firstDigit := dsaRemainder at: j.
firstTwoDigits := (firstDigit bitShift: 8) + (dsaRemainder at: j - 1).
thirdDigit := dsaRemainder at: j - 2.

"estimate q, the next digit of the quotient"
firstDigit = d1
ifTrue: [q := 255]
ifFalse: [q := firstTwoDigits // d1].

"adjust the estimate of q if necessary"
(d2 * q) > (((firstTwoDigits - (q * d1)) bitShift: 8) + thirdDigit) ifTrue: [
q := q - 1.
(d2 * q) > (((firstTwoDigits - (q * d1)) bitShift: 8) + thirdDigit) ifTrue: [
q := q - 1]].

digitShift := j - divisorDigitCount - 1.
q > 0 ifTrue: [
qTooBig := self subtractDivisorMultipliedByDigit: q digitShift: digitShift.
qTooBig ifTrue: [ "this case is extremely rare"
self addBackDivisorDigitShift: digitShift.
q := q - 1]].

"record this digit of the quotient"
dsaQuotient at: digitShift + 1 put: q].
!

----- Method: DSAPlugin>>leftRotate:by: (in category 'private') -----
leftRotate: anInteger by: bits
"Rotate the given 32-bit integer left by the given number of bits and answer the result."



^self
cCode: [(anInteger > (32 - bits))]
inSmalltalk: [(anInteger > (32 - bits))]!

----- Method: DSAPlugin>>primitiveBigDivide (in category 'primitives-integers') -----
primitiveBigDivide
"Called with three LargePositiveInteger arguments, rem, div, quo. Divide div into rem and store the quotient into quo, leaving the remainder in rem."
"Assume: quo starts out filled with zeros."


| rem div quo clpi |
interpreterProxy methodArgumentCount = 3 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
quo := interpreterProxy stackValue: 0.
div := interpreterProxy stackValue: 1.
rem := interpreterProxy stackValue: 2.
clpi := interpreterProxy classLargePositiveInteger.
((interpreterProxy fetchClassOf: rem) = clpi
and: [(interpreterProxy fetchClassOf: div) = clpi
and: [(interpreterProxy fetchClassOf: quo) = clpi]]) ifFalse:
[^interpreterProxy primitiveFailFor: PrimErrBadArgument].

dsaRemainder := interpreterProxy firstIndexableField: rem.
dsaDivisor := interpreterProxy firstIndexableField: div.
dsaQuotient := interpreterProxy firstIndexableField: quo.

divisorDigitCount := interpreterProxy stSizeOf: div.
remainderDigitCount := interpreterProxy stSizeOf: rem.

"adjust pointers for base-1 indexing"
dsaRemainder := dsaRemainder - 1.
dsaDivisor := dsaDivisor - 1.
dsaQuotient := dsaQuotient - 1.

self bigDivideLoop.
interpreterProxy pop: 3!

----- Method: DSAPlugin>>primitiveBigMultiply (in category 'primitives-integers') -----
primitiveBigMultiply
"Multiple f1 by f2, placing the result into prod. f1, f2, and prod must be LargePositiveIntegers, and the length of prod must be the sum of the lengths of f1 and f2."
"Assume: prod starts out filled with zeros"


| prod f2 f1 clpi prodLen f1Len f2Len prodPtr f2Ptr f1Ptr digit carry k sum |




interpreterProxy methodArgumentCount = 3 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
prod := interpreterProxy stackValue: 0.
f2 := interpreterProxy stackValue: 1.
f1 := interpreterProxy stackValue: 2.
clpi := interpreterProxy classLargePositiveInteger.
((interpreterProxy fetchClassOf: prod) = clpi
and: [(interpreterProxy fetchClassOf: f2) = clpi
and: [(interpreterProxy fetchClassOf: f1) = clpi]]) ifFalse:
[^interpreterProxy primitiveFailFor: PrimErrBadArgument].

prodLen := interpreterProxy stSizeOf: prod.
f1Len := interpreterProxy stSizeOf: f1.
f2Len := interpreterProxy stSizeOf: f2.
prodLen = (f1Len + f2Len) ifFalse:
[^interpreterProxy primitiveFailFor: PrimErrBadArgument].

prodPtr := interpreterProxy firstIndexableField: prod.
f2Ptr := interpreterProxy firstIndexableField: f2.
f1Ptr := interpreterProxy firstIndexableField: f1.

0 to: f1Len-1 do: [:i |
(digit := f1Ptr at: i) ~= 0 ifTrue: [
carry := 0.
k := i.
"Loop invariants: 0


| expanded buf wordPtr bytePtr src v |



interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
expanded := interpreterProxy stackValue: 0.
buf := interpreterProxy stackValue: 1.

((interpreterProxy isWords: expanded)
and: [(interpreterProxy isBytes: buf)
and: [(interpreterProxy stSizeOf: expanded) = 80
and: [(interpreterProxy stSizeOf: buf) = 64]]]) ifFalse:
[^interpreterProxy primitiveFailFor: PrimErrBadArgument].

wordPtr := interpreterProxy firstIndexableField: expanded.
bytePtr := interpreterProxy firstIndexableField: buf.

src := 0.
0 to: 15 do: [:i |
v := ((bytePtr at: src)
((bytePtr at: src + 1)
((bytePtr at: src + 2)
(bytePtr at: src + 3).
wordPtr at: i put: v.
src := src + 4].

16 to: 79 do: [:i |
v := (((wordPtr at: i - 3) bitXor:
(wordPtr at: i - 8)) bitXor:
(wordPtr at: i - 14)) bitXor:
(wordPtr at: i - 16).
v := self leftRotate: v by: 1.
wordPtr at: i put: v].

interpreterProxy pop: 2!

----- Method: DSAPlugin>>primitiveHasSecureHashPrimitive (in category 'primitives-SHA') -----
primitiveHasSecureHashPrimitive
"Answer true if the secure hash primitive is implemented."


interpreterProxy methodReturnBool: true!

----- Method: DSAPlugin>>primitiveHashBlock (in category 'primitives-SHA') -----
primitiveHashBlock
"Hash a Bitmap of 80 32-bit words (the first argument), using the given state (the second argument)."


| state buf statePtr bufPtr a b c d e tmp |



interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
state := interpreterProxy stackValue: 0.
buf := interpreterProxy stackValue: 1.
((interpreterProxy isWords: state)
and: [(interpreterProxy isWords: buf)
and: [(interpreterProxy stSizeOf: state) = 5
and: [(interpreterProxy stSizeOf: buf) = 80]]]) ifFalse:
[^interpreterProxy primitiveFailFor: PrimErrBadArgument].

statePtr := interpreterProxy firstIndexableField: state.
bufPtr := interpreterProxy firstIndexableField: buf.

a := statePtr at: 0.
b := statePtr at: 1.
c := statePtr at: 2.
d := statePtr at: 3.
e := statePtr at: 4.

0 to: 19 do: [:i |
tmp := 16r5A827999 + ((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) +
(self leftRotate: a by: 5) + e + (bufPtr at: i).
e := d. d := c. c := self leftRotate: b by: 30. b := a. a := tmp].

20 to: 39 do: [:i |
tmp := 16r6ED9EBA1 + ((b bitXor: c) bitXor: d) +
(self leftRotate: a by: 5) + e + (bufPtr at: i).
e := d. d := c. c := self leftRotate: b by: 30. b := a. a := tmp].

40 to: 59 do: [:i |
tmp := 16r8F1BBCDC + (((b bitAnd: c) bitOr: (b bitAnd: d)) bitOr: (c bitAnd: d)) +
(self leftRotate: a by: 5) + e + (bufPtr at: i).
e := d. d := c. c := self leftRotate: b by: 30. b := a. a := tmp].

60 to: 79 do: [:i |
tmp := 16rCA62C1D6 + ((b bitXor: c) bitXor: d) +
(self leftRotate: a by: 5) + e + (bufPtr at: i).
e := d. d := c. c := self leftRotate: b by: 30. b := a. a := tmp].

statePtr at: 0 put: (statePtr at: 0) + a.
statePtr at: 1 put: (statePtr at: 1) + b.
statePtr at: 2 put: (statePtr at: 2) + c.
statePtr at: 3 put: (statePtr at: 3) + d.
statePtr at: 4 put: (statePtr at: 4) + e.

interpreterProxy pop: 2!

----- Method: DSAPlugin>>primitiveHighestNonZeroDigitIndex (in category 'primitives-integers') -----
primitiveHighestNonZeroDigitIndex
"Called with one LargePositiveInteger argument. Answer the index of the top-most non-zero digit."


| arg bigIntPtr i |


interpreterProxy methodArgumentCount = 1 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
arg := interpreterProxy stackValue: 0.
(interpreterProxy fetchClassOf: arg) = interpreterProxy classLargePositiveInteger ifFalse:
[^interpreterProxy primitiveFailFor: PrimErrBadArgument].

bigIntPtr := interpreterProxy firstIndexableField: arg.
i := interpreterProxy stSizeOf: arg.
[i > 0 and: [(bigIntPtr at: (i := i - 1)) = 0]] whileTrue. "scan down from end to first non-zero digit"

interpreterProxy pop: 1.
interpreterProxy pushInteger: i + 1!

----- Method: DSAPlugin>>subtractDivisorMultipliedByDigit:digitShift: (in category 'private') -----
subtractDivisorMultipliedByDigit: digit digitShift: digitShift
"Multiply the divisor by the given digit (an integer in the range 0..255), shift it left by the given number of digits, and subtract the result from the current remainder. Answer true if there is an excess borrow, indicating that digit was one too large. (This case is quite rare.)"

| borrow rIndex prod resultDigit |
borrow := 0.
rIndex := digitShift + 1.
1 to: divisorDigitCount do: [:i |
prod := ((dsaDivisor at: i) * digit) + borrow.
borrow := prod bitShift: -8.
resultDigit := (dsaRemainder at: rIndex) - (prod bitAnd: 16rFF).
resultDigit
resultDigit := resultDigit + 256.
borrow := borrow + 1].
dsaRemainder at: rIndex put: resultDigit.
rIndex := rIndex + 1].

"propagate the final borrow if necessary"
borrow = 0 ifTrue: [^ false].
resultDigit := (dsaRemainder at: rIndex) - borrow.
resultDigit
ifTrue: [ "digit was too large (this case is quite rare)"
dsaRemainder at: rIndex put: resultDigit + 256.
^ true]
ifFalse: [
dsaRemainder at: rIndex put: resultDigit.
^ false].
!

InterpreterPlugin subclass: #MD5Plugin
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CryptographyPlugins'!

!MD5Plugin commentStamp: 'ul 3/7/2008 19:01' prior: 0!
I'm an MD5 plugin, my implementation is based on RFC 1321 (http://tools.ietf.org/html/rfc1321) Appendix A.
Please do it:

MD5Plugin compileMethods.

before compiling the plugin with VMMaker (especially on big endian platforms).!

----- Method: MD5Plugin class>>abcd (in category 'code generation - tables') -----
abcd

^#(
(a b c d)
(d a b c)
(c d a b)
(b c d a)
)!

----- Method: MD5Plugin class>>compileMethods (in category 'code generation') -----
compileMethods
"self compileMethods"

self compile: self generateProcessBufferWithState
classified: 'generated'!

----- Method: MD5Plugin class>>fX:y:z: (in category 'code generation - macros') -----
fX: x y: y z: z

^'(({1} bitAnd: {2}) bitOr: ({1} bitInvert32 bitAnd: {3}))' format: { x. y. z }!

----- Method: MD5Plugin class>>ffA:b:c:d:x:s:ac: (in category 'code generation - macros') -----
ffA: a b: b c: c d: d x: x s: s ac: ac

^'
{1} := {1} + ({2} + {3} + {4}).
{1} := {5} + {6}.' format: { a. self fX: b y: c z: d. x. ac. self rotateLeftX: a n: s. b }!

----- Method: MD5Plugin class>>gX:y:z: (in category 'code generation - macros') -----
gX: x y: y z: z

^'(({1} bitAnd: {3}) bitOr: ({2} bitAnd: {3} bitInvert32))' format: { x. y. z }!

----- Method: MD5Plugin class>>generateProcessBufferWithState (in category 'code generation') -----
generateProcessBufferWithState
"self generateProcessBufferWithState"

^ String streamContents:
[ : stream |
stream
nextPutAll: self processBufferWithStateHeader;
crtab; nextPutAll: 'self decode: buffer sizeInIntegers: 16.'.
0 to: 63 do: [ : i |
stream nextPutAll: (self round: i) ].
stream nextPutAll: self processBufferWithStateFooter]!

----- Method: MD5Plugin class>>ggA:b:c:d:x:s:ac: (in category 'code generation - macros') -----
ggA: a b: b c: c d: d x: x s: s ac: ac

^'
{1} := {1} + ({2} + {3} + {4}).
{1} := {5} + {6}.' format: { a. self gX: b y: c z: d. x. ac. self rotateLeftX: a n: s. b }!

----- Method: MD5Plugin class>>hX:y:z: (in category 'code generation - macros') -----
hX: x y: y z: z

^'(({1} bitXor: {2}) bitXor: {3})' format: { x. y. z }!

----- Method: MD5Plugin class>>hhA:b:c:d:x:s:ac: (in category 'code generation - macros') -----
hhA: a b: b c: c d: d x: x s: s ac: ac

^'
{1} := {1} + ({2} + {3} + {4}).
{1} := {5} + {6}.' format: { a. self hX: b y: c z: d. x. ac. self rotateLeftX: a n: s. b }!

----- Method: MD5Plugin class>>iX:y:z: (in category 'code generation - macros') -----
iX: x y: y z: z

^'({2} bitXor: ({1} bitOr: {3} bitInvert32))' format: { x. y. z }!

----- Method: MD5Plugin class>>iiA:b:c:d:x:s:ac: (in category 'code generation - macros') -----
iiA: a b: b c: c d: d x: x s: s ac: ac

^'
{1} := {1} + ({2} + {3} + {4}).
{1} := {5} + {6}.' format: { a. self iX: b y: c z: d. x. ac. self rotateLeftX: a n: s. b }!

----- Method: MD5Plugin class>>indexArray (in category 'code generation - tables') -----
indexArray

"(0 to: 15) asArray,
((16 to: 31) collect: [ :i | (5 * i + 1) \\ 16]),
((32 to: 47) collect: [ :i | (3 * i + 5) \\ 16]),
((48 to: 63) collect: [ :i | (7 * i) \\ 16]) "
^ #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 6 11 0 5 10 15 4 9 14 3 8 13 2 7 12 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9)!

----- Method: MD5Plugin class>>processBufferWithStateFooter (in category 'code generation') -----
processBufferWithStateFooter

^ '
state at: 0 put: (state at: 0) + a.
state at: 1 put: (state at: 1) + b.
state at: 2 put: (state at: 2) + c.
state at: 3 put: (state at: 3) + d.'!

----- Method: MD5Plugin class>>processBufferWithStateHeader (in category 'code generation') -----
processBufferWithStateHeader

^ 'md5ProcessBuffer: buffer withState: state
"This method is generated. See #compileMethods on the class side."

| a b c d |








a := state at: 0.
b := state at: 1.
c := state at: 2.
d := state at: 3.'!

----- Method: MD5Plugin class>>rotateLeftX:n: (in category 'code generation - macros') -----
rotateLeftX: x n: n

^'(({1} > (32 - {2})))' format: { x. n }
!

----- Method: MD5Plugin class>>round: (in category 'code generation') -----
round: i

| selector |
selector := #(ffA:b:c:d:x:s:ac: ggA:b:c:d:x:s:ac: hhA:b:c:d:x:s:ac: iiA:b:c:d:x:s:ac:) at: (i // 16) + 1.
^self
perform: selector
withArguments:
(self abcd at: (i \\ 4) + 1),
{
'(buffer at: {1})' format: { self indexArray at: i + 1 }.
self shiftArray at: i + 1.
self sineArray at: i + 1 }!

----- Method: MD5Plugin class>>shiftArray (in category 'code generation - tables') -----
shiftArray

^#(
7 12 17 22 7 12 17 22 7 12 17 22 7 12 17 22
5 9 14 20 5 9 14 20 5 9 14 20 5 9 14 20
4 11 16 23 4 11 16 23 4 11 16 23 4 11 16 23
6 10 15 21 6 10 15 21 6 10 15 21 6 10 15 21
)!

----- Method: MD5Plugin class>>simulatorClass (in category 'simulation') -----
simulatorClass
"We can simulate this plugin accurately via MD5PluginSimulator if we
have the rewrite engine to create an accurate simulation override for
#md5ProcessBuffer:withState:"
^((Smalltalk classNamed: #RBParseTreeRewriter) notNil
and: [Integer includesSelector: #asC_unsigned_int])
ifTrue: [MD5PluginSimulator]
ifFalse: [super simulatorClass]!

----- Method: MD5Plugin class>>sineArray (in category 'code generation - tables') -----
sineArray

"| twoPow32 |
twoPow32 := 2 raisedTo: 32.
(1 to: 64) collect: [ :each |
(each sin abs * twoPow32) truncated ]."
^#(3614090360 3905402710 606105819 3250441966 4118548399 1200080426 2821735955 4249261313 1770035416 2336552879 4294925233 2304563134 1804603682 4254626195 2792965006 1236535329 4129170786 3225465664 643717713 3921069994 3593408605 38016083 3634488961 3889429448 568446438 3275163606 4107603335 1163531501 2850285829 4243563512 1735328473 2368359562 4294588738 2272392833 1839030562 4259657740 2763975236 1272893353 4139469664 3200236656 681279174 3936430074 3572445317 76029189 3654602809 3873151461 530742520 3299628645 4096336452 1126891415 2878612391 4237533241 1700485571 2399980690 4293915773 2240044497 1873313359 4264355552 2734768916 1309151649 4149444226 3174756917 718787259 3951481745)!

----- Method: MD5Plugin>>decode:sizeInIntegers: (in category 'plugin support') -----
decode: array sizeInIntegers: n
"Change the endianness of the first n integers in array. Used only on big endian platforms."






VMBIGENDIAN ifTrue: [
0 to: n - 1 do: [ :i |
array at: i put: (array at: i) byteSwap32 ] ]!

----- Method: MD5Plugin>>md5InitializeState: (in category 'plugin support') -----
md5InitializeState: state





state at: 0 put: 16r67452301.
state at: 1 put: 16rEFCDAB89.
state at: 2 put: 16r98BADCFE.
state at: 3 put: 16r10325476
!

----- Method: MD5Plugin>>md5ProcessBuffer:withState: (in category 'generated') -----
md5ProcessBuffer: buffer withState: state
"This method is generated. See #compileMethods on the class side."

| a b c d |








a := state at: 0.
b := state at: 1.
c := state at: 2.
d := state at: 3.
self decode: buffer sizeInIntegers: 16.
a := a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 0) + 3614090360).
a := ((a > (32 - 7))) + b.
d := d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 1) + 3905402710).
d := ((d > (32 - 12))) + a.
c := c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 2) + 606105819).
c := ((c > (32 - 17))) + d.
b := b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 3) + 3250441966).
b := ((b > (32 - 22))) + c.
a := a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 4) + 4118548399).
a := ((a > (32 - 7))) + b.
d := d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 5) + 1200080426).
d := ((d > (32 - 12))) + a.
c := c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 6) + 2821735955).
c := ((c > (32 - 17))) + d.
b := b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 7) + 4249261313).
b := ((b > (32 - 22))) + c.
a := a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 8) + 1770035416).
a := ((a > (32 - 7))) + b.
d := d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 9) + 2336552879).
d := ((d > (32 - 12))) + a.
c := c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 10) + 4294925233).
c := ((c > (32 - 17))) + d.
b := b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 11) + 2304563134).
b := ((b > (32 - 22))) + c.
a := a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 12) + 1804603682).
a := ((a > (32 - 7))) + b.
d := d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 13) + 4254626195).
d := ((d > (32 - 12))) + a.
c := c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 14) + 2792965006).
c := ((c > (32 - 17))) + d.
b := b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 15) + 1236535329).
b := ((b > (32 - 22))) + c.
a := a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 1) + 4129170786).
a := ((a > (32 - 5))) + b.
d := d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 6) + 3225465664).
d := ((d > (32 - 9))) + a.
c := c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 11) + 643717713).
c := ((c > (32 - 14))) + d.
b := b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 0) + 3921069994).
b := ((b > (32 - 20))) + c.
a := a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 5) + 3593408605).
a := ((a > (32 - 5))) + b.
d := d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 10) + 38016083).
d := ((d > (32 - 9))) + a.
c := c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 15) + 3634488961).
c := ((c > (32 - 14))) + d.
b := b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 4) + 3889429448).
b := ((b > (32 - 20))) + c.
a := a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 9) + 568446438).
a := ((a > (32 - 5))) + b.
d := d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 14) + 3275163606).
d := ((d > (32 - 9))) + a.
c := c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 3) + 4107603335).
c := ((c > (32 - 14))) + d.
b := b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 8) + 1163531501).
b := ((b > (32 - 20))) + c.
a := a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 13) + 2850285829).
a := ((a > (32 - 5))) + b.
d := d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 2) + 4243563512).
d := ((d > (32 - 9))) + a.
c := c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 7) + 1735328473).
c := ((c > (32 - 14))) + d.
b := b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 12) + 2368359562).
b := ((b > (32 - 20))) + c.
a := a + (((b bitXor: c) bitXor: d) + (buffer at: 5) + 4294588738).
a := ((a > (32 - 4))) + b.
d := d + (((a bitXor: b) bitXor: c) + (buffer at: 8) + 2272392833).
d := ((d > (32 - 11))) + a.
c := c + (((d bitXor: a) bitXor: b) + (buffer at: 11) + 1839030562).
c := ((c > (32 - 16))) + d.
b := b + (((c bitXor: d) bitXor: a) + (buffer at: 14) + 4259657740).
b := ((b > (32 - 23))) + c.
a := a + (((b bitXor: c) bitXor: d) + (buffer at: 1) + 2763975236).
a := ((a > (32 - 4))) + b.
d := d + (((a bitXor: b) bitXor: c) + (buffer at: 4) + 1272893353).
d := ((d > (32 - 11))) + a.
c := c + (((d bitXor: a) bitXor: b) + (buffer at: 7) + 4139469664).
c := ((c > (32 - 16))) + d.
b := b + (((c bitXor: d) bitXor: a) + (buffer at: 10) + 3200236656).
b := ((b > (32 - 23))) + c.
a := a + (((b bitXor: c) bitXor: d) + (buffer at: 13) + 681279174).
a := ((a > (32 - 4))) + b.
d := d + (((a bitXor: b) bitXor: c) + (buffer at: 0) + 3936430074).
d := ((d > (32 - 11))) + a.
c := c + (((d bitXor: a) bitXor: b) + (buffer at: 3) + 3572445317).
c := ((c > (32 - 16))) + d.
b := b + (((c bitXor: d) bitXor: a) + (buffer at: 6) + 76029189).
b := ((b > (32 - 23))) + c.
a := a + (((b bitXor: c) bitXor: d) + (buffer at: 9) + 3654602809).
a := ((a > (32 - 4))) + b.
d := d + (((a bitXor: b) bitXor: c) + (buffer at: 12) + 3873151461).
d := ((d > (32 - 11))) + a.
c := c + (((d bitXor: a) bitXor: b) + (buffer at: 15) + 530742520).
c := ((c > (32 - 16))) + d.
b := b + (((c bitXor: d) bitXor: a) + (buffer at: 2) + 3299628645).
b := ((b > (32 - 23))) + c.
a := a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 0) + 4096336452).
a := ((a > (32 - 6))) + b.
d := d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 7) + 1126891415).
d := ((d > (32 - 10))) + a.
c := c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 14) + 2878612391).
c := ((c > (32 - 15))) + d.
b := b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 5) + 4237533241).
b := ((b > (32 - 21))) + c.
a := a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 12) + 1700485571).
a := ((a > (32 - 6))) + b.
d := d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 3) + 2399980690).
d := ((d > (32 - 10))) + a.
c := c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 10) + 4293915773).
c := ((c > (32 - 15))) + d.
b := b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 1) + 2240044497).
b := ((b > (32 - 21))) + c.
a := a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 8) + 1873313359).
a := ((a > (32 - 6))) + b.
d := d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 15) + 4264355552).
d := ((d > (32 - 10))) + a.
c := c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 6) + 2734768916).
c := ((c > (32 - 15))) + d.
b := b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 13) + 1309151649).
b := ((b > (32 - 21))) + c.
a := a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 4) + 4149444226).
a := ((a > (32 - 6))) + b.
d := d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 11) + 3174756917).
d := ((d > (32 - 10))) + a.
c := c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 2) + 718787259).
c := ((c > (32 - 15))) + d.
b := b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 9) + 3951481745).
b := ((b > (32 - 21))) + c.
state at: 0 put: (state at: 0) + a.
state at: 1 put: (state at: 1) + b.
state at: 2 put: (state at: 2) + c.
state at: 3 put: (state at: 3) + d.!

----- Method: MD5Plugin>>primitiveDecodeState (in category 'primitives') -----
primitiveDecodeState



| bytesOop |
interpreterProxy methodArgumentCount = 1 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
bytesOop := interpreterProxy stackObjectValue: 0.
((interpreterProxy isBytes: bytesOop)
and: [ (interpreterProxy stSizeOf: bytesOop) = 16 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
self
decode: (interpreterProxy firstIndexableField: bytesOop)
sizeInIntegers: 4.
interpreterProxy methodReturnReceiver!

----- Method: MD5Plugin>>primitiveInitializeState (in category 'primitives') -----
primitiveInitializeState



| bytesOop |
interpreterProxy methodArgumentCount = 1 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
bytesOop := interpreterProxy stackObjectValue: 0.
((interpreterProxy isBytes: bytesOop)
and: [ (interpreterProxy stSizeOf: bytesOop) = 16 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
self md5InitializeState: (interpreterProxy firstIndexableField: bytesOop).
interpreterProxy methodReturnReceiver
!

----- Method: MD5Plugin>>primitivePluginAvailable (in category 'primitives') -----
primitivePluginAvailable



interpreterProxy methodReturnBool: true!

----- Method: MD5Plugin>>primitiveProcessBufferWithState (in category 'primitives') -----
primitiveProcessBufferWithState



| bufferOop stateOop |
interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].

bufferOop := interpreterProxy stackObjectValue: 1.
((interpreterProxy isBytes: bufferOop)
and: [ (interpreterProxy stSizeOf: bufferOop) = 64 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

stateOop := interpreterProxy stackObjectValue: 0.
((interpreterProxy isBytes: stateOop)
and: [ (interpreterProxy stSizeOf: stateOop) = 16 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

self
md5ProcessBuffer: (interpreterProxy firstIndexableField: bufferOop)
withState: (interpreterProxy firstIndexableField: stateOop).

interpreterProxy methodReturnReceiver!

MD5Plugin subclass: #MD5PluginSimulator
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CryptographyPlugins'!

----- Method: MD5PluginSimulator class>>shouldBeTranslated (in category 'translation') -----
shouldBeTranslated
^false!

----- Method: MD5PluginSimulator>>ensureUpToDateOverrideFor: (in category 'simulation support') -----
ensureUpToDateOverrideFor: aSelector
"Ensure that an override that uses 32-bit integer arithmetic exists for aSelector"
| source |
source := self transformedSourceFor: self class superclass >> aSelector.
(self class sourceCodeAt: aSelector ifAbsent: ['']) ~= source ifTrue:
[self class compile: source classified: 'generated overrides']!

----- Method: MD5PluginSimulator>>initialize (in category 'initialization') -----
initialize
self ensureUpToDateOverrideFor: #md5ProcessBuffer:withState:!

----- Method: MD5PluginSimulator>>md5ProcessBuffer:withState: (in category 'generated overrides') -----
md5ProcessBuffer: buffer withState: state
"This method is generated. See #compileMethods on the class side."









| a b c d |
a := (state at: 0) asC_unsigned_int.
b := (state at: 1) asC_unsigned_int.
c := (state at: 2) asC_unsigned_int.
d := (state at: 3) asC_unsigned_int.
self decode: buffer sizeInIntegers: 16.
a := (a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 0) + 3614090360)) asC_unsigned_int.
a := ((a > (32 - 7)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 1) + 3905402710)) asC_unsigned_int.
d := ((d > (32 - 12)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 2) + 606105819)) asC_unsigned_int.
c := ((c > (32 - 17)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 3) + 3250441966)) asC_unsigned_int.
b := ((b > (32 - 22)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 4) + 4118548399)) asC_unsigned_int.
a := ((a > (32 - 7)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 5) + 1200080426)) asC_unsigned_int.
d := ((d > (32 - 12)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 6) + 2821735955)) asC_unsigned_int.
c := ((c > (32 - 17)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 7) + 4249261313)) asC_unsigned_int.
b := ((b > (32 - 22)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 8) + 1770035416)) asC_unsigned_int.
a := ((a > (32 - 7)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 9) + 2336552879)) asC_unsigned_int.
d := ((d > (32 - 12)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 10) + 4294925233)) asC_unsigned_int.
c := ((c > (32 - 17)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 11) + 2304563134)) asC_unsigned_int.
b := ((b > (32 - 22)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: c) bitOr: (b bitInvert32 bitAnd: d)) + (buffer at: 12) + 1804603682)) asC_unsigned_int.
a := ((a > (32 - 7)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: b) bitOr: (a bitInvert32 bitAnd: c)) + (buffer at: 13) + 4254626195)) asC_unsigned_int.
d := ((d > (32 - 12)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: a) bitOr: (d bitInvert32 bitAnd: b)) + (buffer at: 14) + 2792965006)) asC_unsigned_int.
c := ((c > (32 - 17)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: d) bitOr: (c bitInvert32 bitAnd: a)) + (buffer at: 15) + 1236535329)) asC_unsigned_int.
b := ((b > (32 - 22)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 1) + 4129170786)) asC_unsigned_int.
a := ((a > (32 - 5)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 6) + 3225465664)) asC_unsigned_int.
d := ((d > (32 - 9)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 11) + 643717713)) asC_unsigned_int.
c := ((c > (32 - 14)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 0) + 3921069994)) asC_unsigned_int.
b := ((b > (32 - 20)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 5) + 3593408605)) asC_unsigned_int.
a := ((a > (32 - 5)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 10) + 38016083)) asC_unsigned_int.
d := ((d > (32 - 9)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 15) + 3634488961)) asC_unsigned_int.
c := ((c > (32 - 14)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 4) + 3889429448)) asC_unsigned_int.
b := ((b > (32 - 20)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 9) + 568446438)) asC_unsigned_int.
a := ((a > (32 - 5)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 14) + 3275163606)) asC_unsigned_int.
d := ((d > (32 - 9)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 3) + 4107603335)) asC_unsigned_int.
c := ((c > (32 - 14)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 8) + 1163531501)) asC_unsigned_int.
b := ((b > (32 - 20)) + c) asC_unsigned_int.
a := (a + (((b bitAnd: d) bitOr: (c bitAnd: d bitInvert32)) + (buffer at: 13) + 2850285829)) asC_unsigned_int.
a := ((a > (32 - 5)) + b) asC_unsigned_int.
d := (d + (((a bitAnd: c) bitOr: (b bitAnd: c bitInvert32)) + (buffer at: 2) + 4243563512)) asC_unsigned_int.
d := ((d > (32 - 9)) + a) asC_unsigned_int.
c := (c + (((d bitAnd: b) bitOr: (a bitAnd: b bitInvert32)) + (buffer at: 7) + 1735328473)) asC_unsigned_int.
c := ((c > (32 - 14)) + d) asC_unsigned_int.
b := (b + (((c bitAnd: a) bitOr: (d bitAnd: a bitInvert32)) + (buffer at: 12) + 2368359562)) asC_unsigned_int.
b := ((b > (32 - 20)) + c) asC_unsigned_int.
a := (a + (((b bitXor: c) bitXor: d) + (buffer at: 5) + 4294588738)) asC_unsigned_int.
a := ((a > (32 - 4)) + b) asC_unsigned_int.
d := (d + (((a bitXor: b) bitXor: c) + (buffer at: 8) + 2272392833)) asC_unsigned_int.
d := ((d > (32 - 11)) + a) asC_unsigned_int.
c := (c + (((d bitXor: a) bitXor: b) + (buffer at: 11) + 1839030562)) asC_unsigned_int.
c := ((c > (32 - 16)) + d) asC_unsigned_int.
b := (b + (((c bitXor: d) bitXor: a) + (buffer at: 14) + 4259657740)) asC_unsigned_int.
b := ((b > (32 - 23)) + c) asC_unsigned_int.
a := (a + (((b bitXor: c) bitXor: d) + (buffer at: 1) + 2763975236)) asC_unsigned_int.
a := ((a > (32 - 4)) + b) asC_unsigned_int.
d := (d + (((a bitXor: b) bitXor: c) + (buffer at: 4) + 1272893353)) asC_unsigned_int.
d := ((d > (32 - 11)) + a) asC_unsigned_int.
c := (c + (((d bitXor: a) bitXor: b) + (buffer at: 7) + 4139469664)) asC_unsigned_int.
c := ((c > (32 - 16)) + d) asC_unsigned_int.
b := (b + (((c bitXor: d) bitXor: a) + (buffer at: 10) + 3200236656)) asC_unsigned_int.
b := ((b > (32 - 23)) + c) asC_unsigned_int.
a := (a + (((b bitXor: c) bitXor: d) + (buffer at: 13) + 681279174)) asC_unsigned_int.
a := ((a > (32 - 4)) + b) asC_unsigned_int.
d := (d + (((a bitXor: b) bitXor: c) + (buffer at: 0) + 3936430074)) asC_unsigned_int.
d := ((d > (32 - 11)) + a) asC_unsigned_int.
c := (c + (((d bitXor: a) bitXor: b) + (buffer at: 3) + 3572445317)) asC_unsigned_int.
c := ((c > (32 - 16)) + d) asC_unsigned_int.
b := (b + (((c bitXor: d) bitXor: a) + (buffer at: 6) + 76029189)) asC_unsigned_int.
b := ((b > (32 - 23)) + c) asC_unsigned_int.
a := (a + (((b bitXor: c) bitXor: d) + (buffer at: 9) + 3654602809)) asC_unsigned_int.
a := ((a > (32 - 4)) + b) asC_unsigned_int.
d := (d + (((a bitXor: b) bitXor: c) + (buffer at: 12) + 3873151461)) asC_unsigned_int.
d := ((d > (32 - 11)) + a) asC_unsigned_int.
c := (c + (((d bitXor: a) bitXor: b) + (buffer at: 15) + 530742520)) asC_unsigned_int.
c := ((c > (32 - 16)) + d) asC_unsigned_int.
b := (b + (((c bitXor: d) bitXor: a) + (buffer at: 2) + 3299628645)) asC_unsigned_int.
b := ((b > (32 - 23)) + c) asC_unsigned_int.
a := (a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 0) + 4096336452)) asC_unsigned_int.
a := ((a > (32 - 6)) + b) asC_unsigned_int.
d := (d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 7) + 1126891415)) asC_unsigned_int.
d := ((d > (32 - 10)) + a) asC_unsigned_int.
c := (c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 14) + 2878612391)) asC_unsigned_int.
c := ((c > (32 - 15)) + d) asC_unsigned_int.
b := (b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 5) + 4237533241)) asC_unsigned_int.
b := ((b > (32 - 21)) + c) asC_unsigned_int.
a := (a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 12) + 1700485571)) asC_unsigned_int.
a := ((a > (32 - 6)) + b) asC_unsigned_int.
d := (d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 3) + 2399980690)) asC_unsigned_int.
d := ((d > (32 - 10)) + a) asC_unsigned_int.
c := (c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 10) + 4293915773)) asC_unsigned_int.
c := ((c > (32 - 15)) + d) asC_unsigned_int.
b := (b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 1) + 2240044497)) asC_unsigned_int.
b := ((b > (32 - 21)) + c) asC_unsigned_int.
a := (a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 8) + 1873313359)) asC_unsigned_int.
a := ((a > (32 - 6)) + b) asC_unsigned_int.
d := (d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 15) + 4264355552)) asC_unsigned_int.
d := ((d > (32 - 10)) + a) asC_unsigned_int.
c := (c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 6) + 2734768916)) asC_unsigned_int.
c := ((c > (32 - 15)) + d) asC_unsigned_int.
b := (b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 13) + 1309151649)) asC_unsigned_int.
b := ((b > (32 - 21)) + c) asC_unsigned_int.
a := (a + ((c bitXor: (b bitOr: d bitInvert32)) + (buffer at: 4) + 4149444226)) asC_unsigned_int.
a := ((a > (32 - 6)) + b) asC_unsigned_int.
d := (d + ((b bitXor: (a bitOr: c bitInvert32)) + (buffer at: 11) + 3174756917)) asC_unsigned_int.
d := ((d > (32 - 10)) + a) asC_unsigned_int.
c := (c + ((a bitXor: (d bitOr: b bitInvert32)) + (buffer at: 2) + 718787259)) asC_unsigned_int.
c := ((c > (32 - 15)) + d) asC_unsigned_int.
b := (b + ((d bitXor: (c bitOr: a bitInvert32)) + (buffer at: 9) + 3951481745)) asC_unsigned_int.
b := ((b > (32 - 21)) + c) asC_unsigned_int.
state at: 0 put: ((state at: 0) + a) asC_unsigned_int.
state at: 1 put: ((state at: 1) + b) asC_unsigned_int.
state at: 2 put: ((state at: 2) + c) asC_unsigned_int.
state at: 3 put: ((state at: 3) + d) asC_unsigned_int!

----- Method: MD5PluginSimulator>>transformedSourceFor: (in category 'simulation support') -----
transformedSourceFor: m
"Transform all references to #int variables in the source code of m into var asC_int
and all references to #'unsigned int' variables into var asC_unsigned_int"
| tm rules cgen |
tm := m asTranslationMethodOfClass: TMethod.
tm recordDeclarationsIn: (cgen := CCodeGenerator new).
rules := RBParseTreeRewriter new.
#(#'int *' #'unsigned int *')
with: #(asC_int asC_unsigned_int)
do: [:type :coercionMessage|
(tm declarations keys select: [:v| (tm typeFor: v in: cgen) = type]) do:
[:var| "make this use ``@expr and editSource breaks"
rules replace: var, ' at: `@index put: `@expr' with: var, ' at: `@index put: `@expr ', coercionMessage]].
#(#'int' #'unsigned int')
with: #(asC_int asC_unsigned_int)
do: [:type :coercionMessage|
(tm declarations keys select: [:v| (tm typeFor: v in: cgen) = type]) do:
[:var|
rules
replace: var, ' := `@args' with: var, ' := `@args ', coercionMessage;
replace: var with: var, ' ', coercionMessage]].
(rules executeTree: (m methodClass parseTreeFor: m selector)) ifTrue:
[^rules tree newSource].
self error: 'parse tree rewrite failed'!

InterpreterPlugin subclass: #SHA2Plugin
instanceVariableNames: 'sha512k sha256k'
classVariableNames: ''
poolDictionaries: ''
category: 'CryptographyPlugins'!

!SHA2Plugin commentStamp: 'ul 3/9/2020 03:38' prior: 0!
I'm implement plugin that can be used to speed up all variants of the SHA-2 family of cryptographic hash functions (http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-2_algorithm).
This means that, I obsolete the SHA256Plugin.
I implement the two algorithms via primitiveSHA256ProcessBufferUpdatingHash and primitiveSHA512ProcessBufferUpdatingHash.
These methods take a chunk of the input (64 or 128 bytes, respectively) and the initial or intermediate hash values, and update the hash value according to the algorithm.
The intermediate hash values, including the initial hash values are always passed by the image as a WordArray or a DoubleWordArray.
The final hash value can be converted to a ByteArray with the help of primitiveCopyWordsToBytes and primitiveCopyDoubleWordsToBytes.
The rest of the algorithms, including chunk creation and padding, is done on the image side.!

----- Method: SHA2Plugin class>>declareCVarsIn: (in category 'translation') -----
declareCVarsIn: aCCodeGenerator

super declareCVarsIn: aCCodeGenerator.
aCCodeGenerator
var: #sha256k
type: 'const unsigned int'
array: self sha256kArray;
var: #sha512k
type: 'const unsigned long long'
array: self sha512kArray!

----- Method: SHA2Plugin class>>sha256kArray (in category 'accessing') -----
sha256kArray

"(Integer primesUpTo: 312) collect: [:x | (((x raisedTo: 1/3) fractionPart) * (2.0 raisedTo: 32)) truncated ]"
^ #(1116352408 1899447441 3049323471 3921009573 961987163 1508970993 2453635748 2870763221 3624381080 310598401 607225278 1426881987 1925078388 2162078206 2614888103 3248222580 3835390401 4022224774 264347078 604807628 770255983 1249150122 1555081692 1996064986 2554220882 2821834349 2952996808 3210313671 3336571891 3584528711 113926993 338241895 666307205 773529912 1294757372 1396182291 1695183700 1986661051 2177026350 2456956037 2730485921 2820302411 3259730800 3345764771 3516065817 3600352804 4094571909 275423344 430227734 506948616 659060556 883997877 958139571 1322822218 1537002063 1747873779 1955562222 2024104815 2227730452 2361852424 2428436474 2756734187 3204031479 3329325298)!

----- Method: SHA2Plugin class>>sha512kArray (in category 'accessing') -----
sha512kArray

^#(
16r428a2f98d728ae22 16r7137449123ef65cd 16rb5c0fbcfec4d3b2f 16re9b5dba58189dbbc 16r3956c25bf348b538
16r59f111f1b605d019 16r923f82a4af194f9b 16rab1c5ed5da6d8118 16rd807aa98a3030242 16r12835b0145706fbe
16r243185be4ee4b28c 16r550c7dc3d5ffb4e2 16r72be5d74f27b896f 16r80deb1fe3b1696b1 16r9bdc06a725c71235
16rc19bf174cf692694 16re49b69c19ef14ad2 16refbe4786384f25e3 16r0fc19dc68b8cd5b5 16r240ca1cc77ac9c65
16r2de92c6f592b0275 16r4a7484aa6ea6e483 16r5cb0a9dcbd41fbd4 16r76f988da831153b5 16r983e5152ee66dfab
16ra831c66d2db43210 16rb00327c898fb213f 16rbf597fc7beef0ee4 16rc6e00bf33da88fc2 16rd5a79147930aa725
16r06ca6351e003826f 16r142929670a0e6e70 16r27b70a8546d22ffc 16r2e1b21385c26c926 16r4d2c6dfc5ac42aed
16r53380d139d95b3df 16r650a73548baf63de 16r766a0abb3c77b2a8 16r81c2c92e47edaee6 16r92722c851482353b
16ra2bfe8a14cf10364 16ra81a664bbc423001 16rc24b8b70d0f89791 16rc76c51a30654be30 16rd192e819d6ef5218
16rd69906245565a910 16rf40e35855771202a 16r106aa07032bbd1b8 16r19a4c116b8d2d0c8 16r1e376c085141ab53
16r2748774cdf8eeb99 16r34b0bcb5e19b48a8 16r391c0cb3c5c95a63 16r4ed8aa4ae3418acb 16r5b9cca4f7763e373
16r682e6ff3d6b2b8a3 16r748f82ee5defb2fc 16r78a5636f43172f60 16r84c87814a1f0ab72 16r8cc702081a6439ec
16r90befffa23631e28 16ra4506cebde82bde9 16rbef9a3f7b2c67915 16rc67178f2e372532b 16rca273eceea26619c
16rd186b8c721c0c207 16reada7dd6cde0eb1e 16rf57d4f7fee6ed178 16r06f067aa72176fba 16r0a637dc5a2c898a6
16r113f9804bef90dae 16r1b710b35131c471b 16r28db77f523047d84 16r32caab7b40c72493 16r3c9ebe0a15c9bebc
16r431d67c49c100d4c 16r4cc5d4becb3e42b6 16r597f299cfc657e2a 16r5fcb6fab3ad6faec 16r6c44198c4a475817
)!

----- Method: SHA2Plugin>>copyDoubleWords:into:count: (in category 'primitives sha512') -----
copyDoubleWords: source into: target count: count
"Copy count double words from source into target ensuring big-endian byte order."





VMBIGENDIAN
ifTrue: [ self memcpy: target _: source _: count * 8 ]
ifFalse: [
0 to: count - 1 do: [ :i |
target at: i put: (source at: i) byteSwap64 ] ]!

----- Method: SHA2Plugin>>copyWords:into:count: (in category 'primitives sha256') -----
copyWords: source into: target count: count
"Copy count words from source into target ensuring big-endian byte order."





VMBIGENDIAN
ifTrue: [ self memcpy: target _: source _: count * 4 ]
ifFalse: [
0 to: count - 1 do: [ :i |
target at: i put: (source at: i) byteSwap32 ] ]!

----- Method: SHA2Plugin>>primitiveCopyDoubleWordsIntoBytesBigEndian (in category 'primitives sha512') -----
primitiveCopyDoubleWordsIntoBytesBigEndian


| doubleWordsOop bytesOop doubleWordCount byteCount doubleWords bytes |



interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].

doubleWordsOop := interpreterProxy stackObjectValue: 1.
"TODO: there's no easy way to check whether doubleWordsOop is a DoubleWord object, so be creative here"
(interpreterProxy isWordsOrBytes: doubleWordsOop) ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
doubleWordCount := interpreterProxy stSizeOf: doubleWordsOop.
(interpreterProxy byteSizeOf: doubleWordsOop) = (doubleWordCount * 8) ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

bytesOop := interpreterProxy stackObjectValue: 0.
(interpreterProxy isBytes: bytesOop) ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
byteCount := interpreterProxy stSizeOf: bytesOop.
doubleWordCount * 8 = byteCount ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

doubleWords := interpreterProxy firstIndexableField: doubleWordsOop.
bytes := interpreterProxy firstIndexableField: bytesOop.
self
copyDoubleWords: doubleWords
into: (self cCoerce: bytes to: #'unsigned long long*')
count: doubleWordCount.
interpreterProxy methodReturnReceiver!

----- Method: SHA2Plugin>>primitiveCopyWordsIntoBytesBigEndian (in category 'primitives sha256') -----
primitiveCopyWordsIntoBytesBigEndian
"Copy all words into bytes in big-endian byte order."


| wordsOop bytesOop wordCount byteCount words bytes |



interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].
wordsOop := interpreterProxy stackObjectValue: 1.
(interpreterProxy isWords: wordsOop) ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
bytesOop := interpreterProxy stackObjectValue: 0.
(interpreterProxy isBytes: bytesOop) ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
wordCount := interpreterProxy stSizeOf: wordsOop.
byteCount := interpreterProxy stSizeOf: bytesOop.
wordCount * 4 = byteCount ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].
words := interpreterProxy firstIndexableField: wordsOop.
bytes := interpreterProxy firstIndexableField: bytesOop.
self
copyWords: words
into: bytes
count: wordCount.
interpreterProxy methodReturnReceiver!

----- Method: SHA2Plugin>>primitiveIsPluginAvailable (in category 'primitives') -----
primitiveIsPluginAvailable



interpreterProxy methodReturnBool: true!

----- Method: SHA2Plugin>>primitiveSHA256ProcessBufferUpdatingHash (in category 'primitives sha256') -----
primitiveSHA256ProcessBufferUpdatingHash

| bufferOop hashOop buffer hash |



interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].

hashOop := interpreterProxy stackValue: 0.
bufferOop := interpreterProxy stackValue: 1.
((interpreterProxy isBytes: bufferOop)
and: [ (interpreterProxy byteSizeOf: bufferOop) = 64
and: [ (interpreterProxy isWords: hashOop)
and: [ (interpreterProxy stSizeOf: hashOop) = 8 ]]])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

buffer := interpreterProxy firstIndexableField: bufferOop.
hash := interpreterProxy firstIndexableField: hashOop.

self sha256ProcessBuffer: buffer updatingHash: hash.

interpreterProxy methodReturnReceiver!

----- Method: SHA2Plugin>>primitiveSHA512ProcessBufferUpdatingHash (in category 'primitives sha512') -----
primitiveSHA512ProcessBufferUpdatingHash





| bufferOop hashOop buffer hash |

interpreterProxy methodArgumentCount = 2 ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadNumArgs ].

bufferOop := interpreterProxy stackObjectValue: 1.
((interpreterProxy isBytes: bufferOop)
and: [ (interpreterProxy stSizeOf: bufferOop) = 128 ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

hashOop := interpreterProxy stackObjectValue: 0.
"TODO: there's no easy way to check whether doubleWordsOop is a DoubleWord object, so be creative here"
((interpreterProxy isWordsOrBytes: hashOop)
and: [ (interpreterProxy stSizeOf: hashOop) = 8
and: [ (interpreterProxy byteSizeOf: hashOop) = 64 ] ])
ifFalse: [ ^interpreterProxy primitiveFailFor: PrimErrBadArgument ].

buffer := interpreterProxy firstIndexableField: bufferOop.
hash := interpreterProxy firstIndexableField: hashOop.

self sha512ProcessBuffer: buffer updatingHash: hash.

interpreterProxy methodReturnReceiver!

----- Method: SHA2Plugin>>rotateRight32:by: (in category 'primitives sha256') -----
rotateRight32: value by: amount






^(value >> amount) bitOr: (value

----- Method: SHA2Plugin>>rotateRight64:by: (in category 'primitives sha512') -----
rotateRight64: value by: amount






^(value >> amount) bitOr: (value

----- Method: SHA2Plugin>>sha256CopyAndExpandBuffer:into: (in category 'primitives sha256') -----
sha256CopyAndExpandBuffer: buffer into: w

| s0 s1 |






self
copyWords: (self cCoerce: buffer to: #'unsigned int*')
into: w
count: 16.

16 to: 63 do: [ :i |
s0 := ((self rotateRight32: (w at: i - 15) by: 7)
bitXor: (self rotateRight32: (w at: i - 15) by: 18))
bitXor: (w at: i - 15) >> 3.
s1 := ((self rotateRight32: (w at: i - 2) by: 17)
bitXor: (self rotateRight32: (w at: i - 2) by: 19))
bitXor: (w at: i - 2) >> 10.
w at: i put: s0 + s1 + (w at: i - 16) + (w at: i - 7) ]!

----- Method: SHA2Plugin>>sha256ProcessBuffer:updatingHash: (in category 'primitives sha256') -----
sha256ProcessBuffer: buffer updatingHash: hash





















| a b c d e f g h s0 s1 t1 t2 maj ch w |
self cCode: '' inSmalltalk: [ w := CArrayAccessor on: (WordArray new: 64) ].
self sha256CopyAndExpandBuffer: buffer into: w.

a := hash at: 0.
b := hash at: 1.
c := hash at: 2.
d := hash at: 3.
e := hash at: 4.
f := hash at: 5.
g := hash at: 6.
h := hash at: 7.

0 to: 63 do: [ :i |
s0 := ((self rotateRight32: a by: 2)
bitXor: (self rotateRight32: a by: 13))
bitXor: (self rotateRight32: a by: 22).
maj := ((a bitOr: b) bitAnd: c) bitOr: (a bitAnd: b). "optimized form of (a and b) xor (a and c) xor (b and c)"
t2 := s0 + maj.
s1 := ((self rotateRight32: e by: 6)
bitXor: (self rotateRight32: e by: 11))
bitXor: (self rotateRight32: e by: 25).
ch := ((f bitXor: g) bitAnd: e) bitXor: g. "optimized form of (e and f) xor ((not e) and g)"
t1 := h + s1 + ch + (sha256k at: i) + (w at: i).

h := g.
g := f.
f := e.
e := d + t1.
d := c.
c := b.
b := a.
a := t1 + t2 ].

hash at: 0 put: (hash at: 0) + a.
hash at: 1 put: (hash at: 1) + b.
hash at: 2 put: (hash at: 2) + c.
hash at: 3 put: (hash at: 3) + d.
hash at: 4 put: (hash at: 4) + e.
hash at: 5 put: (hash at: 5) + f.
hash at: 6 put: (hash at: 6) + g.
hash at: 7 put: (hash at: 7) + h!

----- Method: SHA2Plugin>>sha512CopyAndExpandBuffer:into: (in category 'primitives sha512') -----
sha512CopyAndExpandBuffer: buffer into: w







| s0 s1 |
self
copyDoubleWords: (self cCoerce: buffer to: #'unsigned long long*')
into: w
count: 16.

16 to: 79 do: [ :i |
s0 := ((self rotateRight64: (w at: i - 15) by: 1)
bitXor: (self rotateRight64: (w at: i - 15) by: 8))
bitXor: (w at: i - 15) >> 7.
s1 := ((self rotateRight64: (w at: i - 2) by: 19)
bitXor: (self rotateRight64: (w at: i - 2) by: 61))
bitXor: (w at: i - 2) >> 6.
w at: i put: s0 + s1 + (w at: i - 16) + (w at: i - 7) ]!

----- Method: SHA2Plugin>>sha512ProcessBuffer:updatingHash: (in category 'primitives sha512') -----
sha512ProcessBuffer: buffer updatingHash: hash





















| a b c d e f g h s0 s1 t1 t2 maj ch w |
self cCode: '' inSmalltalk: [ w := CArrayAccessor on: (DoubleWordArray new: 80) ].
self sha512CopyAndExpandBuffer: buffer into: w.

a := hash at: 0.
b := hash at: 1.
c := hash at: 2.
d := hash at: 3.
e := hash at: 4.
f := hash at: 5.
g := hash at: 6.
h := hash at: 7.

0 to: 79 do: [ :i |
s0 := ((self rotateRight64: a by: 28)
bitXor: (self rotateRight64: a by: 34))
bitXor: (self rotateRight64: a by: 39).
maj := ((a bitOr: b) bitAnd: c) bitOr: (a bitAnd: b). "optimized form of (a and b) xor (a and c) xor (b and c)"
t2 := s0 + maj.
s1 := ((self rotateRight64: e by: 14)
bitXor: (self rotateRight64: e by: 18))
bitXor: (self rotateRight64: e by: 41).
ch := ((f bitXor: g) bitAnd: e) bitXor: g. "optimized form of (e and f) xor ((not e) and g)"
t1 := h + s1 + ch + (sha512k at: i) + (w at: i).

h := g.
g := f.
f := e.
e := d + t1.
d := c.
c := b.
b := a.
a := t1 + t2 ].

hash at: 0 put: (hash at: 0) + a.
hash at: 1 put: (hash at: 1) + b.
hash at: 2 put: (hash at: 2) + c.
hash at: 3 put: (hash at: 3) + d.
hash at: 4 put: (hash at: 4) + e.
hash at: 5 put: (hash at: 5) + f.
hash at: 6 put: (hash at: 6) + g.
hash at: 7 put: (hash at: 7) + h!



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211213/301f1fac/attachment-0001.html>


More information about the Squeak-dev mailing list