Tobias Pape uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-topa.775.mcz
==================== Summary ====================
Name: System-topa.775
Author: topa
Time: 29 October 2015, 1:06:23.749 am
UUID: a2ad05e2-8cf3-4974-84c4-7a5d93e304e3
Ancestors: System-ul.774
Cache NaturalLanguageTranslator when looking up yet inexisting ones.
Induced by tim Rowledge
(see http://forum.world.st/image-startup-complications-td4858390.html)
=============== Diff against System-ul.774 ===============
Item was changed:
----- Method: NaturalLanguageTranslator class>>availableForLocaleID: (in category 'accessing') -----
availableForLocaleID: localeID
"Answer available locale ID.
If translator is not found for correct locale ID, then isoLanguage is
attempted for the key."
^ self translators
at: localeID
+ ifAbsentPut: [localeID hasParent
- ifAbsent: [localeID hasParent
ifTrue: [self translators
at: localeID parent
ifAbsent: [self default]]
ifFalse: [self default]]!
Tobias Pape uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-topa.775.mcz
==================== Summary ====================
Name: System-topa.775
Author: topa
Time: 29 October 2015, 1:06:23.749 am
UUID: a2ad05e2-8cf3-4974-84c4-7a5d93e304e3
Ancestors: System-ul.774
Cache NaturalLanguageTranslator when looking up yet inexisting ones.
Induced by tim Rowledge
(see http://forum.world.st/image-startup-complications-td4858390.html)
=============== Diff against System-ul.774 ===============
Item was changed:
----- Method: NaturalLanguageTranslator class>>availableForLocaleID: (in category 'accessing') -----
availableForLocaleID: localeID
"Answer available locale ID.
If translator is not found for correct locale ID, then isoLanguage is
attempted for the key."
^ self translators
at: localeID
+ ifAbsentPut: [localeID hasParent
- ifAbsent: [localeID hasParent
ifTrue: [self translators
at: localeID parent
ifAbsent: [self default]]
ifFalse: [self default]]!
Levente Uzonyi uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ul.773.mcz
==================== Summary ====================
Name: System-ul.773
Author: ul
Time: 26 October 2015, 3:58:12.896 am
UUID: 6bc40bec-54a9-43e1-ae6d-f4fc730cdc16
Ancestors: System-mt.772
SecureHashAlgorithm speedups:
- avoid allocations
- simplified hash function
=============== Diff against System-mt.772 ===============
Item was changed:
Object subclass: #SecureHashAlgorithm
+ instanceVariableNames: 'totalA totalB totalC totalD totalE totals expandBuffer t1 t2 a b c d e t'
+ classVariableNames: 'K1 K2 K3 K4 TA TB TC TD TE TI'
- instanceVariableNames: 'totalA totalB totalC totalD totalE totals'
- classVariableNames: 'K1 K2 K3 K4'
poolDictionaries: ''
category: 'System-Digital Signatures'!
!SecureHashAlgorithm commentStamp: '<historical>' prior: 0!
This class implements the Secure Hash Algorithm (SHA) described in the U.S. government's Secure Hash Standard (SHS). This standard is described in FIPS PUB 180-1, "SECURE HASH STANDARD", April 17, 1995.
The Secure Hash Algorithm is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996.
See the comment in class DigitalSignatureAlgorithm for details on its use.
Implementation notes:
The secure hash standard was created with 32-bit hardware in mind. All arithmetic in the hash computation must be done modulo 2^32. This implementation uses ThirtyTwoBitRegister objects to simulate hardware registers; this implementation is about six times faster than using LargePositiveIntegers (measured on a Macintosh G3 Powerbook). Implementing a primitive to process each 64-byte buffer would probably speed up the computation by a factor of 20 or more.
!
Item was changed:
----- Method: SecureHashAlgorithm class>>initialize (in category 'class initialization') -----
initialize
"SecureHashAlgorithm initialize"
"For the curious, here's where these constants come from:
#(2 3 5 10) collect: [:x | ((x sqrt / 4.0) * (2.0 raisedTo: 32)) truncated hex]"
K1 := ThirtyTwoBitRegister fromInteger: 16r5A827999.
K2 := ThirtyTwoBitRegister fromInteger: 16r6ED9EBA1.
K3 := ThirtyTwoBitRegister fromInteger: 16r8F1BBCDC.
K4 := ThirtyTwoBitRegister fromInteger: 16rCA62C1D6.
+
+ TA := ThirtyTwoBitRegister fromInteger: 16r67452301.
+ TB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
+ TC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
+ TD := ThirtyTwoBitRegister fromInteger: 16r10325476.
+ TE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
+ (TI := Bitmap new: 5)
+ at: 1 put: 16r67452301;
+ at: 2 put: 16rEFCDAB89;
+ at: 3 put: 16r98BADCFE;
+ at: 4 put: 16r10325476;
+ at: 5 put: 16rC3D2E1F0!
- !
Item was changed:
----- Method: SecureHashAlgorithm>>expandedBlock: (in category 'private') -----
expandedBlock: aByteArray
"Convert the given 64 byte buffer into 80 32-bit registers and answer the result."
+
+ | src |
- | out src v |
- out := Array new: 80.
src := 1.
1 to: 16 do: [:i |
+ (expandBuffer at: i) loadFrom: aByteArray at: src.
- out at: i put: (ThirtyTwoBitRegister fromByteArray: aByteArray at: src).
src := src + 4].
17 to: 80 do: [:i |
+ t1
+ loadFrom: (expandBuffer at: i - 3);
+ bitXor: (expandBuffer at: i - 8);
+ bitXor: (expandBuffer at: i - 14);
+ bitXor: (expandBuffer at: i - 16);
- v := (out at: i - 3) copy.
- v bitXor: (out at: i - 8);
- bitXor: (out at: i - 14);
- bitXor: (out at: i - 16);
leftRotateBy: 1.
+ (expandBuffer at: i) loadFrom: t1 ]
- out at: i put: v].
- ^ out
!
Item was changed:
----- Method: SecureHashAlgorithm>>finalHash (in category 'private') -----
finalHash
"Concatenate the final totals to build the 160-bit integer result."
"Details: If the primitives are supported, the results are in the totals array. Otherwise, they are in the instance variables totalA through totalE."
+ | result |
+ result := ByteArray new: 20.
+ totals
+ ifNil: [ "compute final hash when not using primitives"
+ result
+ unsignedShortAt: 1 put: totalE low bigEndian: false;
+ unsignedShortAt: 3 put: totalE hi bigEndian: false;
+ unsignedShortAt: 5 put: totalD low bigEndian: false;
+ unsignedShortAt: 7 put: totalD hi bigEndian: false;
+ unsignedShortAt: 9 put: totalC low bigEndian: false;
+ unsignedShortAt: 11 put: totalC hi bigEndian: false;
+ unsignedShortAt: 13 put: totalB low bigEndian: false;
+ unsignedShortAt: 15 put: totalB hi bigEndian: false;
+ unsignedShortAt: 17 put: totalA low bigEndian: false;
+ unsignedShortAt: 19 put: totalA hi bigEndian: false ]
+ ifNotNil: [ "compute final hash when using primitives"
+ result
+ unsignedLongAt: 1 put: (totals at: 5) bigEndian: false;
+ unsignedLongAt: 5 put: (totals at: 4) bigEndian: false;
+ unsignedLongAt: 9 put: (totals at: 3) bigEndian: false;
+ unsignedLongAt: 13 put: (totals at: 2) bigEndian: false;
+ unsignedLongAt: 17 put: (totals at: 1) bigEndian: false ].
+ ^(LargePositiveInteger new: result size)
+ replaceFrom: 1
+ to: result size
+ with: result
+ startingAt: 1;
+ normalize!
- | r |
- totals ifNil: [ "compute final hash when not using primitives"
- ^ (totalA asInteger bitShift: 128) +
- (totalB asInteger bitShift: 96) +
- (totalC asInteger bitShift: 64) +
- (totalD asInteger bitShift: 32) +
- (totalE asInteger)].
-
- "compute final hash when using primitives"
- r := 0.
- 1 to: 5 do: [:i |
- r := r bitOr: ((totals at: i) bitShift: (32 * (5 - i)))].
- ^ r
- !
Item was added:
+ ----- Method: SecureHashAlgorithm>>hashFunction: (in category 'private') -----
+ hashFunction: i
+ "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
+ "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
+
+ t1 loadFrom: b.
+ i <= 20 ifTrue: [
+ t2
+ loadFrom: b;
+ bitInvert;
+ bitAnd: d.
+ ^t1
+ bitAnd: c;
+ bitOr: t2 ].
+ i <= 40 ifTrue: [
+ ^t1
+ bitXor: c;
+ bitXor: d ].
+ i <= 60 ifTrue: [
+ t2
+ loadFrom: b;
+ bitOr: c;
+ bitAnd: d.
+ ^t1
+ bitAnd: c;
+ bitOr: t2 ].
+ ^t1
+ bitXor: c;
+ bitXor: d
+ !
Item was removed:
- ----- Method: SecureHashAlgorithm>>hashFunction:of:with:with: (in category 'private') -----
- hashFunction: i of: x with: y with: z
- "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
- "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
-
- i <= 20 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitInvert; bitAnd: z)].
- i <= 40 ifTrue: [^ x copy bitXor: y; bitXor: z].
- i <= 60 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitAnd: z); bitOr: (y copy bitAnd: z)].
- ^ x copy bitXor: y; bitXor: z
- !
Item was changed:
----- Method: SecureHashAlgorithm>>hashInteger:seed: (in category 'public') -----
hashInteger: aPositiveInteger seed: seedInteger
"Hash the given positive integer. The integer to be hashed should have 512 or fewer bits. This entry point is used in the production of random numbers"
| buffer dstIndex |
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ totalA := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
+ totalB := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
+ totalC := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
+ totalD := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
+ totalE := ThirtyTwoBitRegister
+ fromInteger: (seedInteger bitAnd: 16rFFFFFFFF) ]
+ ifNotNil: [
+ totals
+ at: 1 put: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF);
+ at: 2 put: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF);
+ at: 3 put: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF);
+ at: 4 put: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF);
+ at: 5 put: (seedInteger bitAnd: 16rFFFFFFFF) ].
- totalA := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
- totalB := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
- totalC := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
- totalD := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
- totalE := ThirtyTwoBitRegister
- fromInteger: (seedInteger bitAnd: 16rFFFFFFFF).
- self initializeTotalsArray.
-
"pad integer with zeros"
buffer := ByteArray new: 64.
dstIndex := 0.
aPositiveInteger digitLength to: 1 by: -1 do: [:i |
buffer at: (dstIndex := dstIndex + 1) put: (aPositiveInteger digitAt: i)].
"process that one block"
self processBuffer: buffer.
^ self finalHash
!
Item was changed:
----- Method: SecureHashAlgorithm>>hashStream: (in category 'public') -----
hashStream: aPositionableStream
"Hash the contents of the given stream from the current position to the end using the Secure Hash Algorithm. The SHA algorithm is defined in FIPS PUB 180-1. It is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996."
"SecureHashAlgorithm new hashStream: (ReadStream on: 'foo')"
| startPosition buf bitLength |
self initializeTotals.
"(SecureHashAlgorithm new hashMessage: '') radix: 16
=> 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'"
+ aPositionableStream atEnd ifTrue: [self processFinalBuffer: #[] bitLength: 0].
- aPositionableStream atEnd ifTrue: [self processFinalBuffer: #() bitLength: 0].
startPosition := aPositionableStream position.
+ buf := ByteArray new: 64.
[aPositionableStream atEnd] whileFalse: [
+ buf := aPositionableStream next: 64 into: buf startingAt: 1.
- buf := aPositionableStream next: 64.
(aPositionableStream atEnd not and: [buf size = 64])
ifTrue: [self processBuffer: buf]
ifFalse: [
bitLength := (aPositionableStream position - startPosition) * 8.
self processFinalBuffer: buf bitLength: bitLength]].
^ self finalHash
!
Item was added:
+ ----- Method: SecureHashAlgorithm>>initialize (in category 'initialize-release') -----
+ initialize
+
+ self primHasSecureHashPrimitive
+ ifTrue: [
+ totals := Bitmap new: 5.
+ expandBuffer := Bitmap new: 80 ]
+ ifFalse: [
+ totalA := ThirtyTwoBitRegister new.
+ totalB := ThirtyTwoBitRegister new.
+ totalC := ThirtyTwoBitRegister new.
+ totalD := ThirtyTwoBitRegister new.
+ totalE := ThirtyTwoBitRegister new.
+ expandBuffer := Array new: 80.
+ 1 to: 80 do: [ :index |
+ expandBuffer at: index put: ThirtyTwoBitRegister new ].
+ t1 := ThirtyTwoBitRegister new.
+ t2 := ThirtyTwoBitRegister new.
+ t := ThirtyTwoBitRegister new.
+ a := ThirtyTwoBitRegister new.
+ b := ThirtyTwoBitRegister new.
+ c := ThirtyTwoBitRegister new.
+ d := ThirtyTwoBitRegister new.
+ e := ThirtyTwoBitRegister new ]!
Item was changed:
----- Method: SecureHashAlgorithm>>initializeTotals (in category 'private') -----
initializeTotals
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ "total registers for use when primitives are absent"
+ totalA loadFrom: TA.
+ totalB loadFrom: TB.
+ totalC loadFrom: TC.
+ totalD loadFrom: TD.
+ totalE loadFrom: TE ]
+ ifNotNil: [
+ totals
+ replaceFrom: 1
+ to: totals size
+ with: TI
+ startingAt: 1 ]!
- "total registers for use when primitives are absent"
- totalA := ThirtyTwoBitRegister fromInteger: 16r67452301.
- totalB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
- totalC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
- totalD := ThirtyTwoBitRegister fromInteger: 16r10325476.
- totalE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
- self initializeTotalsArray.
- !
Item was removed:
- ----- Method: SecureHashAlgorithm>>initializeTotalsArray (in category 'private') -----
- initializeTotalsArray
- "Initialize the totals array from the registers for use with the primitives."
-
- totals := Bitmap new: 5.
- totals at: 1 put: totalA asInteger.
- totals at: 2 put: totalB asInteger.
- totals at: 3 put: totalC asInteger.
- totals at: 4 put: totalD asInteger.
- totals at: 5 put: totalE asInteger.
- !
Item was changed:
----- Method: SecureHashAlgorithm>>processBuffer: (in category 'private') -----
processBuffer: aByteArray
"Process given 64-byte buffer, accumulating the results in totalA through totalE."
+ | tmp |
+ totals ifNotNil: [ ^self processBufferUsingPrimitives: aByteArray ].
- | a b c d e w tmp |
- self primHasSecureHashPrimitive
- ifTrue: [^ self processBufferUsingPrimitives: aByteArray]
- ifFalse: [totals := nil].
- "initialize registers a through e from the current totals"
- a := totalA copy.
- b := totalB copy.
- c := totalC copy.
- d := totalD copy.
- e := totalE copy.
-
"expand and process the buffer"
+ self expandedBlock: aByteArray.
+
+ "initialize registers a through e from the current totals"
+ a loadFrom: totalA.
+ b loadFrom: totalB.
+ c loadFrom: totalC.
+ d loadFrom: totalD.
+ e loadFrom: totalE.
- w := self expandedBlock: aByteArray.
1 to: 80 do: [:i |
+ t
+ loadFrom: a;
+ leftRotateBy: 5;
+ += (self hashFunction: i);
- tmp := (a copy leftRotateBy: 5)
- += (self hashFunction: i of: b with: c with: d);
+= e;
+ += (expandBuffer at: i);
- += (w at: i);
+= (self constantForStep: i).
+ tmp := e.
e := d.
d := c.
c := b leftRotateBy: 30.
b := a.
+ a := t.
+ t := tmp ].
- a := tmp].
"add a through e into total accumulators"
totalA += a.
totalB += b.
totalC += c.
totalD += d.
totalE += e.
!
Item was changed:
----- Method: SecureHashAlgorithm>>processBufferUsingPrimitives: (in category 'private') -----
processBufferUsingPrimitives: aByteArray
"Process given 64-byte buffer using the primitives, accumulating the results in totals."
- | w |
"expand and process the buffer"
+ self
+ primExpandBlock: aByteArray into: expandBuffer;
+ primHashBlock: expandBuffer using: totals.
- w := Bitmap new: 80.
- self primExpandBlock: aByteArray into: w.
- self primHashBlock: w using: totals.
!
Levente Uzonyi uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ul.773.mcz
==================== Summary ====================
Name: System-ul.773
Author: ul
Time: 26 October 2015, 3:58:12.896 am
UUID: 6bc40bec-54a9-43e1-ae6d-f4fc730cdc16
Ancestors: System-mt.772
SecureHashAlgorithm speedups:
- avoid allocations
- simplified hash function
=============== Diff against System-mt.772 ===============
Item was changed:
Object subclass: #SecureHashAlgorithm
+ instanceVariableNames: 'totalA totalB totalC totalD totalE totals expandBuffer t1 t2 a b c d e t'
+ classVariableNames: 'K1 K2 K3 K4 TA TB TC TD TE TI'
- instanceVariableNames: 'totalA totalB totalC totalD totalE totals'
- classVariableNames: 'K1 K2 K3 K4'
poolDictionaries: ''
category: 'System-Digital Signatures'!
!SecureHashAlgorithm commentStamp: '<historical>' prior: 0!
This class implements the Secure Hash Algorithm (SHA) described in the U.S. government's Secure Hash Standard (SHS). This standard is described in FIPS PUB 180-1, "SECURE HASH STANDARD", April 17, 1995.
The Secure Hash Algorithm is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996.
See the comment in class DigitalSignatureAlgorithm for details on its use.
Implementation notes:
The secure hash standard was created with 32-bit hardware in mind. All arithmetic in the hash computation must be done modulo 2^32. This implementation uses ThirtyTwoBitRegister objects to simulate hardware registers; this implementation is about six times faster than using LargePositiveIntegers (measured on a Macintosh G3 Powerbook). Implementing a primitive to process each 64-byte buffer would probably speed up the computation by a factor of 20 or more.
!
Item was changed:
----- Method: SecureHashAlgorithm class>>initialize (in category 'class initialization') -----
initialize
"SecureHashAlgorithm initialize"
"For the curious, here's where these constants come from:
#(2 3 5 10) collect: [:x | ((x sqrt / 4.0) * (2.0 raisedTo: 32)) truncated hex]"
K1 := ThirtyTwoBitRegister fromInteger: 16r5A827999.
K2 := ThirtyTwoBitRegister fromInteger: 16r6ED9EBA1.
K3 := ThirtyTwoBitRegister fromInteger: 16r8F1BBCDC.
K4 := ThirtyTwoBitRegister fromInteger: 16rCA62C1D6.
+
+ TA := ThirtyTwoBitRegister fromInteger: 16r67452301.
+ TB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
+ TC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
+ TD := ThirtyTwoBitRegister fromInteger: 16r10325476.
+ TE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
+ (TI := Bitmap new: 5)
+ at: 1 put: 16r67452301;
+ at: 2 put: 16rEFCDAB89;
+ at: 3 put: 16r98BADCFE;
+ at: 4 put: 16r10325476;
+ at: 5 put: 16rC3D2E1F0!
- !
Item was changed:
----- Method: SecureHashAlgorithm>>expandedBlock: (in category 'private') -----
expandedBlock: aByteArray
"Convert the given 64 byte buffer into 80 32-bit registers and answer the result."
+
+ | src |
- | out src v |
- out := Array new: 80.
src := 1.
1 to: 16 do: [:i |
+ (expandBuffer at: i) loadFrom: aByteArray at: src.
- out at: i put: (ThirtyTwoBitRegister fromByteArray: aByteArray at: src).
src := src + 4].
17 to: 80 do: [:i |
+ t1
+ loadFrom: (expandBuffer at: i - 3);
+ bitXor: (expandBuffer at: i - 8);
+ bitXor: (expandBuffer at: i - 14);
+ bitXor: (expandBuffer at: i - 16);
- v := (out at: i - 3) copy.
- v bitXor: (out at: i - 8);
- bitXor: (out at: i - 14);
- bitXor: (out at: i - 16);
leftRotateBy: 1.
+ (expandBuffer at: i) loadFrom: t1 ]
- out at: i put: v].
- ^ out
!
Item was changed:
----- Method: SecureHashAlgorithm>>finalHash (in category 'private') -----
finalHash
"Concatenate the final totals to build the 160-bit integer result."
"Details: If the primitives are supported, the results are in the totals array. Otherwise, they are in the instance variables totalA through totalE."
+ | result |
+ result := ByteArray new: 20.
+ totals
+ ifNil: [ "compute final hash when not using primitives"
+ result
+ unsignedShortAt: 1 put: totalE low bigEndian: false;
+ unsignedShortAt: 3 put: totalE hi bigEndian: false;
+ unsignedShortAt: 5 put: totalD low bigEndian: false;
+ unsignedShortAt: 7 put: totalD hi bigEndian: false;
+ unsignedShortAt: 9 put: totalC low bigEndian: false;
+ unsignedShortAt: 11 put: totalC hi bigEndian: false;
+ unsignedShortAt: 13 put: totalB low bigEndian: false;
+ unsignedShortAt: 15 put: totalB hi bigEndian: false;
+ unsignedShortAt: 17 put: totalA low bigEndian: false;
+ unsignedShortAt: 19 put: totalA hi bigEndian: false ]
+ ifNotNil: [ "compute final hash when using primitives"
+ result
+ unsignedLongAt: 1 put: (totals at: 5) bigEndian: false;
+ unsignedLongAt: 5 put: (totals at: 4) bigEndian: false;
+ unsignedLongAt: 9 put: (totals at: 3) bigEndian: false;
+ unsignedLongAt: 13 put: (totals at: 2) bigEndian: false;
+ unsignedLongAt: 17 put: (totals at: 1) bigEndian: false ].
+ ^(LargePositiveInteger new: result size)
+ replaceFrom: 1
+ to: result size
+ with: result
+ startingAt: 1;
+ normalize!
- | r |
- totals ifNil: [ "compute final hash when not using primitives"
- ^ (totalA asInteger bitShift: 128) +
- (totalB asInteger bitShift: 96) +
- (totalC asInteger bitShift: 64) +
- (totalD asInteger bitShift: 32) +
- (totalE asInteger)].
-
- "compute final hash when using primitives"
- r := 0.
- 1 to: 5 do: [:i |
- r := r bitOr: ((totals at: i) bitShift: (32 * (5 - i)))].
- ^ r
- !
Item was added:
+ ----- Method: SecureHashAlgorithm>>hashFunction: (in category 'private') -----
+ hashFunction: i
+ "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
+ "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
+
+ t1 loadFrom: b.
+ i <= 20 ifTrue: [
+ t2
+ loadFrom: b;
+ bitInvert;
+ bitAnd: d.
+ ^t1
+ bitAnd: c;
+ bitOr: t2 ].
+ i <= 40 ifTrue: [
+ ^t1
+ bitXor: c;
+ bitXor: d ].
+ i <= 60 ifTrue: [
+ t2
+ loadFrom: b;
+ bitOr: c;
+ bitAnd: d.
+ ^t1
+ bitAnd: c;
+ bitOr: t2 ].
+ ^t1
+ bitXor: c;
+ bitXor: d
+ !
Item was removed:
- ----- Method: SecureHashAlgorithm>>hashFunction:of:with:with: (in category 'private') -----
- hashFunction: i of: x with: y with: z
- "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
- "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
-
- i <= 20 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitInvert; bitAnd: z)].
- i <= 40 ifTrue: [^ x copy bitXor: y; bitXor: z].
- i <= 60 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitAnd: z); bitOr: (y copy bitAnd: z)].
- ^ x copy bitXor: y; bitXor: z
- !
Item was changed:
----- Method: SecureHashAlgorithm>>hashInteger:seed: (in category 'public') -----
hashInteger: aPositiveInteger seed: seedInteger
"Hash the given positive integer. The integer to be hashed should have 512 or fewer bits. This entry point is used in the production of random numbers"
| buffer dstIndex |
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ totalA := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
+ totalB := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
+ totalC := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
+ totalD := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
+ totalE := ThirtyTwoBitRegister
+ fromInteger: (seedInteger bitAnd: 16rFFFFFFFF) ]
+ ifNotNil: [
+ totals
+ at: 1 put: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF);
+ at: 2 put: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF);
+ at: 3 put: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF);
+ at: 4 put: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF);
+ at: 5 put: (seedInteger bitAnd: 16rFFFFFFFF) ].
- totalA := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
- totalB := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
- totalC := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
- totalD := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
- totalE := ThirtyTwoBitRegister
- fromInteger: (seedInteger bitAnd: 16rFFFFFFFF).
- self initializeTotalsArray.
-
"pad integer with zeros"
buffer := ByteArray new: 64.
dstIndex := 0.
aPositiveInteger digitLength to: 1 by: -1 do: [:i |
buffer at: (dstIndex := dstIndex + 1) put: (aPositiveInteger digitAt: i)].
"process that one block"
self processBuffer: buffer.
^ self finalHash
!
Item was changed:
----- Method: SecureHashAlgorithm>>hashStream: (in category 'public') -----
hashStream: aPositionableStream
"Hash the contents of the given stream from the current position to the end using the Secure Hash Algorithm. The SHA algorithm is defined in FIPS PUB 180-1. It is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996."
"SecureHashAlgorithm new hashStream: (ReadStream on: 'foo')"
| startPosition buf bitLength |
self initializeTotals.
"(SecureHashAlgorithm new hashMessage: '') radix: 16
=> 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'"
+ aPositionableStream atEnd ifTrue: [self processFinalBuffer: #[] bitLength: 0].
- aPositionableStream atEnd ifTrue: [self processFinalBuffer: #() bitLength: 0].
startPosition := aPositionableStream position.
+ buf := ByteArray new: 64.
[aPositionableStream atEnd] whileFalse: [
+ buf := aPositionableStream next: 64 into: buf startingAt: 1.
- buf := aPositionableStream next: 64.
(aPositionableStream atEnd not and: [buf size = 64])
ifTrue: [self processBuffer: buf]
ifFalse: [
bitLength := (aPositionableStream position - startPosition) * 8.
self processFinalBuffer: buf bitLength: bitLength]].
^ self finalHash
!
Item was added:
+ ----- Method: SecureHashAlgorithm>>initialize (in category 'initialize-release') -----
+ initialize
+
+ self primHasSecureHashPrimitive
+ ifTrue: [
+ totals := Bitmap new: 5.
+ expandBuffer := Bitmap new: 80 ]
+ ifFalse: [
+ totalA := ThirtyTwoBitRegister new.
+ totalB := ThirtyTwoBitRegister new.
+ totalC := ThirtyTwoBitRegister new.
+ totalD := ThirtyTwoBitRegister new.
+ totalE := ThirtyTwoBitRegister new.
+ expandBuffer := Array new: 80.
+ 1 to: 80 do: [ :index |
+ expandBuffer at: index put: ThirtyTwoBitRegister new ].
+ t1 := ThirtyTwoBitRegister new.
+ t2 := ThirtyTwoBitRegister new.
+ t := ThirtyTwoBitRegister new.
+ a := ThirtyTwoBitRegister new.
+ b := ThirtyTwoBitRegister new.
+ c := ThirtyTwoBitRegister new.
+ d := ThirtyTwoBitRegister new.
+ e := ThirtyTwoBitRegister new ]!
Item was changed:
----- Method: SecureHashAlgorithm>>initializeTotals (in category 'private') -----
initializeTotals
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ "total registers for use when primitives are absent"
+ totalA loadFrom: TA.
+ totalB loadFrom: TB.
+ totalC loadFrom: TC.
+ totalD loadFrom: TD.
+ totalE loadFrom: TE ]
+ ifNotNil: [
+ totals
+ replaceFrom: 1
+ to: totals size
+ with: TI
+ startingAt: 1 ]!
- "total registers for use when primitives are absent"
- totalA := ThirtyTwoBitRegister fromInteger: 16r67452301.
- totalB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
- totalC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
- totalD := ThirtyTwoBitRegister fromInteger: 16r10325476.
- totalE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
- self initializeTotalsArray.
- !
Item was removed:
- ----- Method: SecureHashAlgorithm>>initializeTotalsArray (in category 'private') -----
- initializeTotalsArray
- "Initialize the totals array from the registers for use with the primitives."
-
- totals := Bitmap new: 5.
- totals at: 1 put: totalA asInteger.
- totals at: 2 put: totalB asInteger.
- totals at: 3 put: totalC asInteger.
- totals at: 4 put: totalD asInteger.
- totals at: 5 put: totalE asInteger.
- !
Item was changed:
----- Method: SecureHashAlgorithm>>processBuffer: (in category 'private') -----
processBuffer: aByteArray
"Process given 64-byte buffer, accumulating the results in totalA through totalE."
+ | tmp |
+ totals ifNotNil: [ ^self processBufferUsingPrimitives: aByteArray ].
- | a b c d e w tmp |
- self primHasSecureHashPrimitive
- ifTrue: [^ self processBufferUsingPrimitives: aByteArray]
- ifFalse: [totals := nil].
- "initialize registers a through e from the current totals"
- a := totalA copy.
- b := totalB copy.
- c := totalC copy.
- d := totalD copy.
- e := totalE copy.
-
"expand and process the buffer"
+ self expandedBlock: aByteArray.
+
+ "initialize registers a through e from the current totals"
+ a loadFrom: totalA.
+ b loadFrom: totalB.
+ c loadFrom: totalC.
+ d loadFrom: totalD.
+ e loadFrom: totalE.
- w := self expandedBlock: aByteArray.
1 to: 80 do: [:i |
+ t
+ loadFrom: a;
+ leftRotateBy: 5;
+ += (self hashFunction: i);
- tmp := (a copy leftRotateBy: 5)
- += (self hashFunction: i of: b with: c with: d);
+= e;
+ += (expandBuffer at: i);
- += (w at: i);
+= (self constantForStep: i).
+ tmp := e.
e := d.
d := c.
c := b leftRotateBy: 30.
b := a.
+ a := t.
+ t := tmp ].
- a := tmp].
"add a through e into total accumulators"
totalA += a.
totalB += b.
totalC += c.
totalD += d.
totalE += e.
!
Item was changed:
----- Method: SecureHashAlgorithm>>processBufferUsingPrimitives: (in category 'private') -----
processBufferUsingPrimitives: aByteArray
"Process given 64-byte buffer using the primitives, accumulating the results in totals."
- | w |
"expand and process the buffer"
+ self
+ primExpandBlock: aByteArray into: expandBuffer;
+ primHashBlock: expandBuffer using: totals.
- w := Bitmap new: 80.
- self primExpandBlock: aByteArray into: w.
- self primHashBlock: w using: totals.
!
Levente Uzonyi uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ul.774.mcz
==================== Summary ====================
Name: System-ul.774
Author: ul
Time: 27 October 2015, 1:44:16.212 am
UUID: 5c00c594-7a1a-4148-9b3b-bfe6ae6486e1
Ancestors: System-ul.773
Reverted some of the less efficient optimizations.
=============== Diff against System-mt.772 ===============
Item was changed:
Object subclass: #SecureHashAlgorithm
instanceVariableNames: 'totalA totalB totalC totalD totalE totals'
+ classVariableNames: 'K1 K2 K3 K4 TA TB TC TD TE TI'
- classVariableNames: 'K1 K2 K3 K4'
poolDictionaries: ''
category: 'System-Digital Signatures'!
!SecureHashAlgorithm commentStamp: '<historical>' prior: 0!
This class implements the Secure Hash Algorithm (SHA) described in the U.S. government's Secure Hash Standard (SHS). This standard is described in FIPS PUB 180-1, "SECURE HASH STANDARD", April 17, 1995.
The Secure Hash Algorithm is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996.
See the comment in class DigitalSignatureAlgorithm for details on its use.
Implementation notes:
The secure hash standard was created with 32-bit hardware in mind. All arithmetic in the hash computation must be done modulo 2^32. This implementation uses ThirtyTwoBitRegister objects to simulate hardware registers; this implementation is about six times faster than using LargePositiveIntegers (measured on a Macintosh G3 Powerbook). Implementing a primitive to process each 64-byte buffer would probably speed up the computation by a factor of 20 or more.
!
Item was changed:
----- Method: SecureHashAlgorithm class>>initialize (in category 'class initialization') -----
initialize
"SecureHashAlgorithm initialize"
"For the curious, here's where these constants come from:
#(2 3 5 10) collect: [:x | ((x sqrt / 4.0) * (2.0 raisedTo: 32)) truncated hex]"
K1 := ThirtyTwoBitRegister fromInteger: 16r5A827999.
K2 := ThirtyTwoBitRegister fromInteger: 16r6ED9EBA1.
K3 := ThirtyTwoBitRegister fromInteger: 16r8F1BBCDC.
K4 := ThirtyTwoBitRegister fromInteger: 16rCA62C1D6.
+
+ TA := ThirtyTwoBitRegister fromInteger: 16r67452301.
+ TB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
+ TC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
+ TD := ThirtyTwoBitRegister fromInteger: 16r10325476.
+ TE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
+ (TI := Bitmap new: 5)
+ at: 1 put: 16r67452301;
+ at: 2 put: 16rEFCDAB89;
+ at: 3 put: 16r98BADCFE;
+ at: 4 put: 16r10325476;
+ at: 5 put: 16rC3D2E1F0!
- !
Item was changed:
----- Method: SecureHashAlgorithm>>expandedBlock: (in category 'private') -----
expandedBlock: aByteArray
+ "Convert the given 64 byte buffer into 80 32-bit registers and answer the result."
+
+ | out src |
- "Convert the given 64 byte buffer into 80 32-bit registers and answer the result."
- | out src v |
out := Array new: 80.
src := 1.
1 to: 16 do: [:i |
out at: i put: (ThirtyTwoBitRegister fromByteArray: aByteArray at: src).
src := src + 4].
17 to: 80 do: [:i |
+ out at: i put: (
+ (out at: i - 3) copy
+ bitXor: (out at: i - 8);
+ bitXor: (out at: i - 14);
+ bitXor: (out at: i - 16);
+ leftRotateBy: 1) ].
- v := (out at: i - 3) copy.
- v bitXor: (out at: i - 8);
- bitXor: (out at: i - 14);
- bitXor: (out at: i - 16);
- leftRotateBy: 1.
- out at: i put: v].
^ out
!
Item was changed:
----- Method: SecureHashAlgorithm>>finalHash (in category 'private') -----
finalHash
"Concatenate the final totals to build the 160-bit integer result."
"Details: If the primitives are supported, the results are in the totals array. Otherwise, they are in the instance variables totalA through totalE."
+ | result |
+ result := ByteArray new: 20.
+ totals
+ ifNil: [ "compute final hash when not using primitives"
+ result
+ unsignedShortAt: 1 put: totalE low bigEndian: false;
+ unsignedShortAt: 3 put: totalE hi bigEndian: false;
+ unsignedShortAt: 5 put: totalD low bigEndian: false;
+ unsignedShortAt: 7 put: totalD hi bigEndian: false;
+ unsignedShortAt: 9 put: totalC low bigEndian: false;
+ unsignedShortAt: 11 put: totalC hi bigEndian: false;
+ unsignedShortAt: 13 put: totalB low bigEndian: false;
+ unsignedShortAt: 15 put: totalB hi bigEndian: false;
+ unsignedShortAt: 17 put: totalA low bigEndian: false;
+ unsignedShortAt: 19 put: totalA hi bigEndian: false ]
+ ifNotNil: [ "compute final hash when using primitives"
+ result
+ unsignedLongAt: 1 put: (totals at: 5) bigEndian: false;
+ unsignedLongAt: 5 put: (totals at: 4) bigEndian: false;
+ unsignedLongAt: 9 put: (totals at: 3) bigEndian: false;
+ unsignedLongAt: 13 put: (totals at: 2) bigEndian: false;
+ unsignedLongAt: 17 put: (totals at: 1) bigEndian: false ].
+ ^(LargePositiveInteger new: result size)
+ replaceFrom: 1
+ to: result size
+ with: result
+ startingAt: 1;
+ normalize!
- | r |
- totals ifNil: [ "compute final hash when not using primitives"
- ^ (totalA asInteger bitShift: 128) +
- (totalB asInteger bitShift: 96) +
- (totalC asInteger bitShift: 64) +
- (totalD asInteger bitShift: 32) +
- (totalE asInteger)].
-
- "compute final hash when using primitives"
- r := 0.
- 1 to: 5 do: [:i |
- r := r bitOr: ((totals at: i) bitShift: (32 * (5 - i)))].
- ^ r
- !
Item was removed:
- ----- Method: SecureHashAlgorithm>>hashFunction:of:with:with: (in category 'private') -----
- hashFunction: i of: x with: y with: z
- "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
- "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
-
- i <= 20 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitInvert; bitAnd: z)].
- i <= 40 ifTrue: [^ x copy bitXor: y; bitXor: z].
- i <= 60 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitAnd: z); bitOr: (y copy bitAnd: z)].
- ^ x copy bitXor: y; bitXor: z
- !
Item was added:
+ ----- Method: SecureHashAlgorithm>>hashFunction:of:with:with:using:and: (in category 'private') -----
+ hashFunction: i of: x with: y with: z using: t1 and: t2
+ "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
+ "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
+
+ t1 loadFrom: x.
+ i <= 20 ifTrue: [
+ t2
+ loadFrom: x;
+ bitInvert;
+ bitAnd: z.
+ ^t1
+ bitAnd: y;
+ bitOr: t2 ].
+ i <= 40 ifTrue: [
+ ^t1
+ bitXor: y;
+ bitXor: z ].
+ i <= 60 ifTrue: [
+ t2
+ loadFrom: x;
+ bitOr: y;
+ bitAnd: z.
+ ^t1
+ bitAnd: y;
+ bitOr: t2 ].
+ ^t1
+ bitXor: y;
+ bitXor: z
+ !
Item was changed:
----- Method: SecureHashAlgorithm>>hashInteger:seed: (in category 'public') -----
hashInteger: aPositiveInteger seed: seedInteger
"Hash the given positive integer. The integer to be hashed should have 512 or fewer bits. This entry point is used in the production of random numbers"
| buffer dstIndex |
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ totalA := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
+ totalB := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
+ totalC := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
+ totalD := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
+ totalE := ThirtyTwoBitRegister
+ fromInteger: (seedInteger bitAnd: 16rFFFFFFFF) ]
+ ifNotNil: [
+ totals
+ at: 1 put: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF);
+ at: 2 put: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF);
+ at: 3 put: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF);
+ at: 4 put: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF);
+ at: 5 put: (seedInteger bitAnd: 16rFFFFFFFF) ].
- totalA := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
- totalB := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
- totalC := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
- totalD := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
- totalE := ThirtyTwoBitRegister
- fromInteger: (seedInteger bitAnd: 16rFFFFFFFF).
- self initializeTotalsArray.
-
"pad integer with zeros"
buffer := ByteArray new: 64.
dstIndex := 0.
aPositiveInteger digitLength to: 1 by: -1 do: [:i |
buffer at: (dstIndex := dstIndex + 1) put: (aPositiveInteger digitAt: i)].
"process that one block"
self processBuffer: buffer.
^ self finalHash
!
Item was changed:
----- Method: SecureHashAlgorithm>>hashStream: (in category 'public') -----
hashStream: aPositionableStream
"Hash the contents of the given stream from the current position to the end using the Secure Hash Algorithm. The SHA algorithm is defined in FIPS PUB 180-1. It is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996."
"SecureHashAlgorithm new hashStream: (ReadStream on: 'foo')"
| startPosition buf bitLength |
self initializeTotals.
"(SecureHashAlgorithm new hashMessage: '') radix: 16
=> 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'"
+ aPositionableStream atEnd ifTrue: [self processFinalBuffer: #[] bitLength: 0].
- aPositionableStream atEnd ifTrue: [self processFinalBuffer: #() bitLength: 0].
startPosition := aPositionableStream position.
+ buf := ByteArray new: 64.
[aPositionableStream atEnd] whileFalse: [
+ buf := aPositionableStream next: 64 into: buf startingAt: 1.
- buf := aPositionableStream next: 64.
(aPositionableStream atEnd not and: [buf size = 64])
ifTrue: [self processBuffer: buf]
ifFalse: [
bitLength := (aPositionableStream position - startPosition) * 8.
self processFinalBuffer: buf bitLength: bitLength]].
^ self finalHash
!
Item was added:
+ ----- Method: SecureHashAlgorithm>>initialize (in category 'initialize-release') -----
+ initialize
+
+ self primHasSecureHashPrimitive
+ ifTrue: [ totals := Bitmap new: 5 ]
+ ifFalse: [
+ totalA := ThirtyTwoBitRegister new.
+ totalB := ThirtyTwoBitRegister new.
+ totalC := ThirtyTwoBitRegister new.
+ totalD := ThirtyTwoBitRegister new.
+ totalE := ThirtyTwoBitRegister new ]!
Item was changed:
----- Method: SecureHashAlgorithm>>initializeTotals (in category 'private') -----
initializeTotals
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ "total registers for use when primitives are absent"
+ totalA loadFrom: TA.
+ totalB loadFrom: TB.
+ totalC loadFrom: TC.
+ totalD loadFrom: TD.
+ totalE loadFrom: TE ]
+ ifNotNil: [
+ totals
+ replaceFrom: 1
+ to: totals size
+ with: TI
+ startingAt: 1 ]!
- "total registers for use when primitives are absent"
- totalA := ThirtyTwoBitRegister fromInteger: 16r67452301.
- totalB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
- totalC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
- totalD := ThirtyTwoBitRegister fromInteger: 16r10325476.
- totalE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
- self initializeTotalsArray.
- !
Item was removed:
- ----- Method: SecureHashAlgorithm>>initializeTotalsArray (in category 'private') -----
- initializeTotalsArray
- "Initialize the totals array from the registers for use with the primitives."
-
- totals := Bitmap new: 5.
- totals at: 1 put: totalA asInteger.
- totals at: 2 put: totalB asInteger.
- totals at: 3 put: totalC asInteger.
- totals at: 4 put: totalD asInteger.
- totals at: 5 put: totalE asInteger.
- !
Item was changed:
----- Method: SecureHashAlgorithm>>processBuffer: (in category 'private') -----
processBuffer: aByteArray
"Process given 64-byte buffer, accumulating the results in totalA through totalE."
+ | a b c d e t tmp w tmp2 tmp3 |
+ totals ifNotNil: [ ^self processBufferUsingPrimitives: aByteArray ].
- | a b c d e w tmp |
- self primHasSecureHashPrimitive
- ifTrue: [^ self processBufferUsingPrimitives: aByteArray]
- ifFalse: [totals := nil].
"initialize registers a through e from the current totals"
a := totalA copy.
b := totalB copy.
c := totalC copy.
d := totalD copy.
e := totalE copy.
"expand and process the buffer"
w := self expandedBlock: aByteArray.
+ tmp := ThirtyTwoBitRegister new.
+ tmp2 := ThirtyTwoBitRegister new.
+ tmp3 := ThirtyTwoBitRegister new.
1 to: 80 do: [:i |
+ tmp
+ loadFrom: a;
+ leftRotateBy: 5;
+ += (self hashFunction: i of: b with: c with: d using: tmp2 and: tmp3);
- tmp := (a copy leftRotateBy: 5)
- += (self hashFunction: i of: b with: c with: d);
+= e;
+= (w at: i);
+= (self constantForStep: i).
+ t := e.
e := d.
d := c.
c := b leftRotateBy: 30.
b := a.
+ a := tmp.
+ tmp := t ].
- a := tmp].
"add a through e into total accumulators"
totalA += a.
totalB += b.
totalC += c.
totalD += d.
totalE += e.
!
Levente Uzonyi uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ul.774.mcz
==================== Summary ====================
Name: System-ul.774
Author: ul
Time: 27 October 2015, 1:44:16.212 am
UUID: 5c00c594-7a1a-4148-9b3b-bfe6ae6486e1
Ancestors: System-ul.773
Reverted some of the less efficient optimizations.
=============== Diff against System-mt.772 ===============
Item was changed:
Object subclass: #SecureHashAlgorithm
instanceVariableNames: 'totalA totalB totalC totalD totalE totals'
+ classVariableNames: 'K1 K2 K3 K4 TA TB TC TD TE TI'
- classVariableNames: 'K1 K2 K3 K4'
poolDictionaries: ''
category: 'System-Digital Signatures'!
!SecureHashAlgorithm commentStamp: '<historical>' prior: 0!
This class implements the Secure Hash Algorithm (SHA) described in the U.S. government's Secure Hash Standard (SHS). This standard is described in FIPS PUB 180-1, "SECURE HASH STANDARD", April 17, 1995.
The Secure Hash Algorithm is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996.
See the comment in class DigitalSignatureAlgorithm for details on its use.
Implementation notes:
The secure hash standard was created with 32-bit hardware in mind. All arithmetic in the hash computation must be done modulo 2^32. This implementation uses ThirtyTwoBitRegister objects to simulate hardware registers; this implementation is about six times faster than using LargePositiveIntegers (measured on a Macintosh G3 Powerbook). Implementing a primitive to process each 64-byte buffer would probably speed up the computation by a factor of 20 or more.
!
Item was changed:
----- Method: SecureHashAlgorithm class>>initialize (in category 'class initialization') -----
initialize
"SecureHashAlgorithm initialize"
"For the curious, here's where these constants come from:
#(2 3 5 10) collect: [:x | ((x sqrt / 4.0) * (2.0 raisedTo: 32)) truncated hex]"
K1 := ThirtyTwoBitRegister fromInteger: 16r5A827999.
K2 := ThirtyTwoBitRegister fromInteger: 16r6ED9EBA1.
K3 := ThirtyTwoBitRegister fromInteger: 16r8F1BBCDC.
K4 := ThirtyTwoBitRegister fromInteger: 16rCA62C1D6.
+
+ TA := ThirtyTwoBitRegister fromInteger: 16r67452301.
+ TB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
+ TC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
+ TD := ThirtyTwoBitRegister fromInteger: 16r10325476.
+ TE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
+ (TI := Bitmap new: 5)
+ at: 1 put: 16r67452301;
+ at: 2 put: 16rEFCDAB89;
+ at: 3 put: 16r98BADCFE;
+ at: 4 put: 16r10325476;
+ at: 5 put: 16rC3D2E1F0!
- !
Item was changed:
----- Method: SecureHashAlgorithm>>expandedBlock: (in category 'private') -----
expandedBlock: aByteArray
+ "Convert the given 64 byte buffer into 80 32-bit registers and answer the result."
+
+ | out src |
- "Convert the given 64 byte buffer into 80 32-bit registers and answer the result."
- | out src v |
out := Array new: 80.
src := 1.
1 to: 16 do: [:i |
out at: i put: (ThirtyTwoBitRegister fromByteArray: aByteArray at: src).
src := src + 4].
17 to: 80 do: [:i |
+ out at: i put: (
+ (out at: i - 3) copy
+ bitXor: (out at: i - 8);
+ bitXor: (out at: i - 14);
+ bitXor: (out at: i - 16);
+ leftRotateBy: 1) ].
- v := (out at: i - 3) copy.
- v bitXor: (out at: i - 8);
- bitXor: (out at: i - 14);
- bitXor: (out at: i - 16);
- leftRotateBy: 1.
- out at: i put: v].
^ out
!
Item was changed:
----- Method: SecureHashAlgorithm>>finalHash (in category 'private') -----
finalHash
"Concatenate the final totals to build the 160-bit integer result."
"Details: If the primitives are supported, the results are in the totals array. Otherwise, they are in the instance variables totalA through totalE."
+ | result |
+ result := ByteArray new: 20.
+ totals
+ ifNil: [ "compute final hash when not using primitives"
+ result
+ unsignedShortAt: 1 put: totalE low bigEndian: false;
+ unsignedShortAt: 3 put: totalE hi bigEndian: false;
+ unsignedShortAt: 5 put: totalD low bigEndian: false;
+ unsignedShortAt: 7 put: totalD hi bigEndian: false;
+ unsignedShortAt: 9 put: totalC low bigEndian: false;
+ unsignedShortAt: 11 put: totalC hi bigEndian: false;
+ unsignedShortAt: 13 put: totalB low bigEndian: false;
+ unsignedShortAt: 15 put: totalB hi bigEndian: false;
+ unsignedShortAt: 17 put: totalA low bigEndian: false;
+ unsignedShortAt: 19 put: totalA hi bigEndian: false ]
+ ifNotNil: [ "compute final hash when using primitives"
+ result
+ unsignedLongAt: 1 put: (totals at: 5) bigEndian: false;
+ unsignedLongAt: 5 put: (totals at: 4) bigEndian: false;
+ unsignedLongAt: 9 put: (totals at: 3) bigEndian: false;
+ unsignedLongAt: 13 put: (totals at: 2) bigEndian: false;
+ unsignedLongAt: 17 put: (totals at: 1) bigEndian: false ].
+ ^(LargePositiveInteger new: result size)
+ replaceFrom: 1
+ to: result size
+ with: result
+ startingAt: 1;
+ normalize!
- | r |
- totals ifNil: [ "compute final hash when not using primitives"
- ^ (totalA asInteger bitShift: 128) +
- (totalB asInteger bitShift: 96) +
- (totalC asInteger bitShift: 64) +
- (totalD asInteger bitShift: 32) +
- (totalE asInteger)].
-
- "compute final hash when using primitives"
- r := 0.
- 1 to: 5 do: [:i |
- r := r bitOr: ((totals at: i) bitShift: (32 * (5 - i)))].
- ^ r
- !
Item was removed:
- ----- Method: SecureHashAlgorithm>>hashFunction:of:with:with: (in category 'private') -----
- hashFunction: i of: x with: y with: z
- "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
- "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
-
- i <= 20 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitInvert; bitAnd: z)].
- i <= 40 ifTrue: [^ x copy bitXor: y; bitXor: z].
- i <= 60 ifTrue: [^ x copy bitAnd: y; bitOr: (x copy bitAnd: z); bitOr: (y copy bitAnd: z)].
- ^ x copy bitXor: y; bitXor: z
- !
Item was added:
+ ----- Method: SecureHashAlgorithm>>hashFunction:of:with:with:using:and: (in category 'private') -----
+ hashFunction: i of: x with: y with: z using: t1 and: t2
+ "Compute the hash function for the i-th step of the block hash loop. We number our steps 1-80, versus the 0-79 of the standard."
+ "Details: There are four functions, one for each 20 iterations. The second and fourth are the same."
+
+ t1 loadFrom: x.
+ i <= 20 ifTrue: [
+ t2
+ loadFrom: x;
+ bitInvert;
+ bitAnd: z.
+ ^t1
+ bitAnd: y;
+ bitOr: t2 ].
+ i <= 40 ifTrue: [
+ ^t1
+ bitXor: y;
+ bitXor: z ].
+ i <= 60 ifTrue: [
+ t2
+ loadFrom: x;
+ bitOr: y;
+ bitAnd: z.
+ ^t1
+ bitAnd: y;
+ bitOr: t2 ].
+ ^t1
+ bitXor: y;
+ bitXor: z
+ !
Item was changed:
----- Method: SecureHashAlgorithm>>hashInteger:seed: (in category 'public') -----
hashInteger: aPositiveInteger seed: seedInteger
"Hash the given positive integer. The integer to be hashed should have 512 or fewer bits. This entry point is used in the production of random numbers"
| buffer dstIndex |
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ totalA := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
+ totalB := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
+ totalC := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
+ totalD := ThirtyTwoBitRegister
+ fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
+ totalE := ThirtyTwoBitRegister
+ fromInteger: (seedInteger bitAnd: 16rFFFFFFFF) ]
+ ifNotNil: [
+ totals
+ at: 1 put: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF);
+ at: 2 put: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF);
+ at: 3 put: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF);
+ at: 4 put: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF);
+ at: 5 put: (seedInteger bitAnd: 16rFFFFFFFF) ].
- totalA := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -128) bitAnd: 16rFFFFFFFF).
- totalB := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -96) bitAnd: 16rFFFFFFFF).
- totalC := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -64) bitAnd: 16rFFFFFFFF).
- totalD := ThirtyTwoBitRegister
- fromInteger: ((seedInteger bitShift: -32) bitAnd: 16rFFFFFFFF).
- totalE := ThirtyTwoBitRegister
- fromInteger: (seedInteger bitAnd: 16rFFFFFFFF).
- self initializeTotalsArray.
-
"pad integer with zeros"
buffer := ByteArray new: 64.
dstIndex := 0.
aPositiveInteger digitLength to: 1 by: -1 do: [:i |
buffer at: (dstIndex := dstIndex + 1) put: (aPositiveInteger digitAt: i)].
"process that one block"
self processBuffer: buffer.
^ self finalHash
!
Item was changed:
----- Method: SecureHashAlgorithm>>hashStream: (in category 'public') -----
hashStream: aPositionableStream
"Hash the contents of the given stream from the current position to the end using the Secure Hash Algorithm. The SHA algorithm is defined in FIPS PUB 180-1. It is also described on p. 442 of 'Applied Cryptography: Protocols, Algorithms, and Source Code in C' by Bruce Scheier, Wiley, 1996."
"SecureHashAlgorithm new hashStream: (ReadStream on: 'foo')"
| startPosition buf bitLength |
self initializeTotals.
"(SecureHashAlgorithm new hashMessage: '') radix: 16
=> 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'"
+ aPositionableStream atEnd ifTrue: [self processFinalBuffer: #[] bitLength: 0].
- aPositionableStream atEnd ifTrue: [self processFinalBuffer: #() bitLength: 0].
startPosition := aPositionableStream position.
+ buf := ByteArray new: 64.
[aPositionableStream atEnd] whileFalse: [
+ buf := aPositionableStream next: 64 into: buf startingAt: 1.
- buf := aPositionableStream next: 64.
(aPositionableStream atEnd not and: [buf size = 64])
ifTrue: [self processBuffer: buf]
ifFalse: [
bitLength := (aPositionableStream position - startPosition) * 8.
self processFinalBuffer: buf bitLength: bitLength]].
^ self finalHash
!
Item was added:
+ ----- Method: SecureHashAlgorithm>>initialize (in category 'initialize-release') -----
+ initialize
+
+ self primHasSecureHashPrimitive
+ ifTrue: [ totals := Bitmap new: 5 ]
+ ifFalse: [
+ totalA := ThirtyTwoBitRegister new.
+ totalB := ThirtyTwoBitRegister new.
+ totalC := ThirtyTwoBitRegister new.
+ totalD := ThirtyTwoBitRegister new.
+ totalE := ThirtyTwoBitRegister new ]!
Item was changed:
----- Method: SecureHashAlgorithm>>initializeTotals (in category 'private') -----
initializeTotals
"Initialize totalA through totalE to their seed values."
+ totals
+ ifNil: [
+ "total registers for use when primitives are absent"
+ totalA loadFrom: TA.
+ totalB loadFrom: TB.
+ totalC loadFrom: TC.
+ totalD loadFrom: TD.
+ totalE loadFrom: TE ]
+ ifNotNil: [
+ totals
+ replaceFrom: 1
+ to: totals size
+ with: TI
+ startingAt: 1 ]!
- "total registers for use when primitives are absent"
- totalA := ThirtyTwoBitRegister fromInteger: 16r67452301.
- totalB := ThirtyTwoBitRegister fromInteger: 16rEFCDAB89.
- totalC := ThirtyTwoBitRegister fromInteger: 16r98BADCFE.
- totalD := ThirtyTwoBitRegister fromInteger: 16r10325476.
- totalE := ThirtyTwoBitRegister fromInteger: 16rC3D2E1F0.
- self initializeTotalsArray.
- !
Item was removed:
- ----- Method: SecureHashAlgorithm>>initializeTotalsArray (in category 'private') -----
- initializeTotalsArray
- "Initialize the totals array from the registers for use with the primitives."
-
- totals := Bitmap new: 5.
- totals at: 1 put: totalA asInteger.
- totals at: 2 put: totalB asInteger.
- totals at: 3 put: totalC asInteger.
- totals at: 4 put: totalD asInteger.
- totals at: 5 put: totalE asInteger.
- !
Item was changed:
----- Method: SecureHashAlgorithm>>processBuffer: (in category 'private') -----
processBuffer: aByteArray
"Process given 64-byte buffer, accumulating the results in totalA through totalE."
+ | a b c d e t tmp w tmp2 tmp3 |
+ totals ifNotNil: [ ^self processBufferUsingPrimitives: aByteArray ].
- | a b c d e w tmp |
- self primHasSecureHashPrimitive
- ifTrue: [^ self processBufferUsingPrimitives: aByteArray]
- ifFalse: [totals := nil].
"initialize registers a through e from the current totals"
a := totalA copy.
b := totalB copy.
c := totalC copy.
d := totalD copy.
e := totalE copy.
"expand and process the buffer"
w := self expandedBlock: aByteArray.
+ tmp := ThirtyTwoBitRegister new.
+ tmp2 := ThirtyTwoBitRegister new.
+ tmp3 := ThirtyTwoBitRegister new.
1 to: 80 do: [:i |
+ tmp
+ loadFrom: a;
+ leftRotateBy: 5;
+ += (self hashFunction: i of: b with: c with: d using: tmp2 and: tmp3);
- tmp := (a copy leftRotateBy: 5)
- += (self hashFunction: i of: b with: c with: d);
+= e;
+= (w at: i);
+= (self constantForStep: i).
+ t := e.
e := d.
d := c.
c := b leftRotateBy: 30.
b := a.
+ a := tmp.
+ tmp := t ].
- a := tmp].
"add a through e into total accumulators"
totalA += a.
totalB += b.
totalC += c.
totalD += d.
totalE += e.
!
David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk:
http://source.squeak.org/trunk/MonticelloConfigurations-dtl.142.mcz
==================== Summary ====================
Name: MonticelloConfigurations-dtl.142
Author: dtl
Time: 25 October 2015, 6:08:54.084 pm
UUID: c87d888b-1820-43f0-bc7b-9c4988d3d263
Ancestors: MonticelloConfigurations-dtl.141
On completion, an interactive system update blocks the UI with a notifier. Allow the notifier to be bypassed for scripted updates, and write a message to the transcript in either case.
=============== Diff against MonticelloConfigurations-dtl.141 ===============
Item was changed:
----- Method: MCMcmUpdater>>doUpdate (in category 'updating') -----
doUpdate
"Update the image by loading all pending updates from the server. If this is
+ the default updater for the system, update the system version when complete.
+ Flush all caches. If a previous download failed this is often helpful"
+
+ ^self doUpdate: true
+ !
- the default updater for the system, update the system version when complete."
- | config |
- "Flush all caches. If a previous download failed this is often helpful"
- MCFileBasedRepository flushAllCaches.
- config := self updateFromRepositories: { self repository }.
- config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated].
- MCMcmUpdater default == self
- ifTrue: [ config setSystemVersion.
- self inform: ('Update completed.
- Current update number: ' translated, SystemVersion current highestUpdate).]
- ifFalse: [self inform: 'Update completed.']
- !
Item was added:
+ ----- Method: MCMcmUpdater>>doUpdate: (in category 'updating') -----
+ doUpdate: interactive
+ "Update the image by loading all pending updates from the server. If this is
+ the default updater for the system, update the system version when complete.
+ If interteractive use a modal notifier, otherwise only update the transcript.
+ Flush all caches. If a previous download failed this is often helpful"
+
+ | config |
+ MCFileBasedRepository flushAllCaches.
+ config := self updateFromRepositories: { self repository }.
+ config ifNil: [
+ interactive ifTrue: [ ^self inform: 'Unable to retrieve updates from remote repository.' translated ].
+ Transcript cr; show: '========== Unable to retrieve updates from remote repository. ==========' translated; cr.
+ ^ self ].
+ MCMcmUpdater default == self
+ ifTrue: [ config setSystemVersion.
+ interactive ifTrue: [ self inform: ('Update completed.
+ Current update number: ' translated, SystemVersion current highestUpdate) ].
+ Transcript cr;
+ show: '========== Update completed. Current update number ' translated;
+ show: SystemVersion current highestUpdate;
+ show: ' =========='; cr ]
+ ifFalse: [
+ interactive
+ ifTrue: [ self inform: 'Update completed.' ].
+ Transcript cr; show: '========== Update completed. ==========' translated; cr ]
+ !
David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk:
http://source.squeak.org/trunk/MonticelloConfigurations-dtl.142.mcz
==================== Summary ====================
Name: MonticelloConfigurations-dtl.142
Author: dtl
Time: 25 October 2015, 6:08:54.084 pm
UUID: c87d888b-1820-43f0-bc7b-9c4988d3d263
Ancestors: MonticelloConfigurations-dtl.141
On completion, an interactive system update blocks the UI with a notifier. Allow the notifier to be bypassed for scripted updates, and write a message to the transcript in either case.
=============== Diff against MonticelloConfigurations-dtl.141 ===============
Item was changed:
----- Method: MCMcmUpdater>>doUpdate (in category 'updating') -----
doUpdate
"Update the image by loading all pending updates from the server. If this is
+ the default updater for the system, update the system version when complete.
+ Flush all caches. If a previous download failed this is often helpful"
+
+ ^self doUpdate: true
+ !
- the default updater for the system, update the system version when complete."
- | config |
- "Flush all caches. If a previous download failed this is often helpful"
- MCFileBasedRepository flushAllCaches.
- config := self updateFromRepositories: { self repository }.
- config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated].
- MCMcmUpdater default == self
- ifTrue: [ config setSystemVersion.
- self inform: ('Update completed.
- Current update number: ' translated, SystemVersion current highestUpdate).]
- ifFalse: [self inform: 'Update completed.']
- !
Item was added:
+ ----- Method: MCMcmUpdater>>doUpdate: (in category 'updating') -----
+ doUpdate: interactive
+ "Update the image by loading all pending updates from the server. If this is
+ the default updater for the system, update the system version when complete.
+ If interteractive use a modal notifier, otherwise only update the transcript.
+ Flush all caches. If a previous download failed this is often helpful"
+
+ | config |
+ MCFileBasedRepository flushAllCaches.
+ config := self updateFromRepositories: { self repository }.
+ config ifNil: [
+ interactive ifTrue: [ ^self inform: 'Unable to retrieve updates from remote repository.' translated ].
+ Transcript cr; show: '========== Unable to retrieve updates from remote repository. ==========' translated; cr.
+ ^ self ].
+ MCMcmUpdater default == self
+ ifTrue: [ config setSystemVersion.
+ interactive ifTrue: [ self inform: ('Update completed.
+ Current update number: ' translated, SystemVersion current highestUpdate) ].
+ Transcript cr;
+ show: '========== Update completed. Current update number ' translated;
+ show: SystemVersion current highestUpdate;
+ show: ' =========='; cr ]
+ ifFalse: [
+ interactive
+ ifTrue: [ self inform: 'Update completed.' ].
+ Transcript cr; show: '========== Update completed. ==========' translated; cr ]
+ !