'From Squeak3.8 of ''5 May 2005'' [latest update: #6665] on 9 December 2005 at 5:02:37 am'! "Change Set: msh-crypto Date: 30 November 2005 Author: Matthew S. Hamrick License and Copyright Copyright (c) 2003-2005, Matthew S. Hamrick All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Revejo.Org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. About This Changeset This is the msh-crypto package. It contains a series of crypto primitives for smalltalk. Up to date information about this package may be found at http://www.cryptonomicon.net/msh/msh-crypto.html. Related changesets include the msh-crypto-app changeset that includes higher level 'applications' of the crypto primitives like 'password based encryptors', object encryptors, base64 encoding as well as encrypted, digested, signed, or authenticated streams. The msh-crypto-test changeset includes SUnit tests for classes in these packages. Feedback I'm always interested in hearing from Smalltalkers in general, and people who use my code in particular. I get a HUGE amount of SPAM these days, but I invite you to email me at mhamrick [at] cryptonomicon [dot] com; put msh-crypto in the subject line so I know what it's about. " "Initialize the msh-crypto classes" #( MessageDigest SymmetricStreamCipher ) do: [ :c | c initialize ]. ! Object subclass: #MessageDigest instanceVariableNames: '' classVariableNames: 'Padding' poolDictionaries: '' category: 'Crypto-Base'! !MessageDigest commentStamp: 'msh 5/4/2005 15:10' prior: 0! MessageDigest is the abstract superclass for the concrete message digest implementations. Message Digest Codes (aka Cryptographic Hash Functions) compute a seemingly unpredictable, fixed length "hash" from arbitrary input. They're used as building blocks for other algorithms including digital signature, message authentication code (MAC), Pseudo Random Number Generators (PRNG) and password based encryption algorithms. Message Digest Codes are also used to "hash passwords" and as part of the ubiquitous SSL/TLS protocol suite. They're sort of like the "sonic screwdriver" of the crypto world. Note that this class simply computes hashes based on strings of input bytes. That is, we take a fixed array of values that we assume are bytes (i.e. - integral values between 0 and 255 inclusive) and operate directly on them. Keep this in mind as you start playing with Unicode and any other representation that can use more than one byte for a single character. The tests in the Crypto-Test SUnit test suite are useful in understanding how these classes work. But since I tend to cringe anytime anyone else says their code is "self documenting," I should probably put my money where my mouth is and say a few things about using these classes. Message Digest Functions Cryptographic Hash Functions are implemented as subclasses of the MessageDigest class. This class encapsulates some common behavior inherited by all it's subclasses. There are four protocols used by the MessageDigest subclasses: digesting, output size, private, and sensitive data. (Actually, the sensitive data protocol is implemented by the MessageDigest class, but as it's an abstract super class, it depends on subclasses to actually express the protocol's behavior.) instance creation If you want to produce a cryptographic hash, then the first step is to create an instance of a message digest object. For example, let's see how we would create an instance of a SHA1 message digest object. | a | a _ SHA1 new. digesting protocol Now that we have a SHA1 instance, let's start digesting something. We do this with the update: message. We can call the update: function as many times as needed. Note that the MessageDigest subclasses are designed to take ByteArray's. a update: ('this is a test' asByteArray). a update: ('here is some more text to be hashed' asByteArray). To produce a message digest, use the digest message. The digest message returns a ByteArray containing the message digest. | b | b _ a digest. If you have an existing array, you can tell a MessageDigest object to put a digest into it with the digest: at: message. The first parameter to this message is an existing array, while the second parameter is an index into the array where you want the digest to go. The following example puts a message digest in elements 12 through 32 in the byte array b. | b | b _ ByteArray new: 50. a digest: b at: 12. After creating a message digest, you may want to create another digest for another data stream. You can do this using the same MessageDigest object, but you must call the reinitialize message first. a reinitialize. output size protocol Not all hash functions produce the same sized output. If you want to know how large the output a particular function will produce, you can use the outputSize message. It responds with an integer that is the size a buffer would have to be to hold it's output. The digest message uses this function to create a byte array to hold the digest it returns: |rv| rv _ ByteArray new: (a outputSize). Code archeologists will note that there is an outputSize message that takes an integer as a parameter. This is designed mostly for encipherment algorithms where the output size is not fixed. For consistency, the message is replicated in the MessageDigest classes and does pretty much the same thing as the plain ol' outputSize message. sensitive data protocol One way that attackers can recover sensitive information is by looking at swap files, or live memory heaps. In an ideal world they wouldn't be able to get any information from looking at these sorts of things, but in the real world we have to worry about these corner cases. The clearSensitiveData protocol zeroizes any sensitive information stored in the class' instance variables. You should do this after using a message digest object and before the object falls out of scope. a clearSensitiveData private protocol The private protocol is.. uh... private. You are, of course, allowed and encouraged to examine how we actually produce our message digests, but we should warn you that there's still some refactoring left to be done on the MessageDigest subclasses, so don't say we didn't warn you!!! MessageDigest subclass: #MD2 instanceVariableNames: 'checksum count state' classVariableNames: 'MD2Padding Sbox' poolDictionaries: '' category: 'Crypto-Base'! !MD2 commentStamp: 'msh 6/13/2003 01:01' prior: 0! This class is provided for reverse compatibility. Do not use MD2 in new applications. MD2 is a message digest code invented by Ron Rivest of MIT and RSA Data Security fame. This implementation is taken from the description of the algorithm provided in RFC 1319 (available at the IETF web page at http://www.ietf.org/rfc/rfc1319.txt). MD2 is not recommended for use with new projects. It is included here only to support an old Verisign Certificate that uses MD2 with RSA for digital signature production. New implementations should use SHA1 or SHA256. This class implements three implementation variables and two class variables. * Sbox (class variable) -- This is the substitution table used to create the digest. * MD2Padding (class variable) -- The last 16 byte block of a message is padded to include n bytes of value n. This is an array of arrays that contain those n n bytes. * checksum -- as part of the creation of the message digest, a "checksum" is generated. This variable contains the checksum for all bytes hashed at any given point. * count -- this integer contains the number of bytes input into the hash algorithm modulo 16. * state -- this 48 byte buffer is loaded with 16 bytes at a time, then "transformed" using the algorithm defined in RFC 1319. ! MessageDigest subclass: #MD4 instanceVariableNames: 'bitCount byteBuffer byteCount state savedState wordBuffer' classVariableNames: '' poolDictionaries: '' category: 'Crypto-Base'! !MD4 commentStamp: 'msh 5/4/2005 14:47' prior: 0! This class is provided for reverse compatibility reasons only. Do not use MD4 for new applications. MD4 is one of a series of hash functions invented by Ron Rivest of MIT. The algorithm has been published widely; this implementation comes from IETF RFC 1320 ( available at http://www.ietf.org/rfc/rfc1320.txt .) RSA Labs ( the research arm of the commercial venture launched by Dr. Rivest ) has a nice FAQ entry in their RSA Labs FAQ at http://www.rsasecurity.com/rsalabs/node.asp?id=2253 . From this, we learn that attacks on MD4 were developed in the early and mid 90's. The most important line from this page is probably, "Clearly, MD4 should now be considered broken." ! MessageDigest subclass: #MD5 instanceVariableNames: 'bitCount byteBuffer byteCount state savedState wordBuffer' classVariableNames: 'T' poolDictionaries: '' category: 'Crypto-Base'! !MD5 commentStamp: 'msh 5/4/2005 14:48' prior: 0! This implementation is provided for reverse compatibility reasons only. Do not use MD5 for new applications.! MessageDigest subclass: #SHA1 instanceVariableNames: 'bitCount byteBuffer byteCount state savedState wordBuffer workBuffer' classVariableNames: 'K' poolDictionaries: '' category: 'Crypto-Base'! MessageDigest subclass: #SHA256 instanceVariableNames: 'bitCount byteBuffer byteCount state savedState wordBuffer workBuffer' classVariableNames: 'K' poolDictionaries: '' category: 'Crypto-Base'! SHA256 subclass: #SHA224 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Crypto-Base'! SHA1 subclass: #SHA512 instanceVariableNames: '' classVariableNames: 'K512' poolDictionaries: '' category: 'Crypto-Base'! SHA512 subclass: #SHA384 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Crypto-Base'! Object subclass: #SymmetricStreamCipher instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Crypto-Base'! SymmetricStreamCipher subclass: #ARC4 instanceVariableNames: 'i j sbox' classVariableNames: '' poolDictionaries: '' category: 'Crypto-Base'! !ARC4 commentStamp: 'msh 5/11/2005 17:42' prior: 0! This class represents an "Alleged RC4" instance. RC4 (tm) is a trademarked symmetric stream cipher from RSA Data Security, Inc. Code for a "RC4 Compatible" cipher was eventually leaked to the internet which is where this implementation comes from. Before using ARC4, you should know that there are a number of terrible attacks against it. Shamir, Mantin, and Flurher documented several weaknesses in the cipher that, in my humble opinion, make it unsafe at any key length. So let's say you want to encrypt something with ARC4. The basic pattern is: initialize with the key, then call the encrypt (or decrypt) functions. ARC4 is a Vernam stream cipher, so we don't have to worry about block size or modes of encryption. Before using any Vernam cipher, however, you should know that it's considered unsafe to encrypt two different messages with the same key. There's more details in Schneier's Applied Crypto or Menezes, et al.'s Handbook of Applied Crypto about this. So, this class takes a key in a byte array, then encrypts plaintext in a byte array to produce a byte array of ciphertext. Here's an example | plaintext ciphertext ncryptor recovered | plaintext _ 'When in the course of human events.' asByteArray. ncryptor _ (ARC4 new). ciphertext _ ncryptor initialize: ('I am a very bad password' asByteArray); encrypt: plaintext. ncryptor clearSensitiveData. ncryptor _ (ARC4 new). recovered _ ncryptor initialize: ('I am a very bad password' asByteArray); encrypt: plaintext. ncryptor clearSensitiveData. At the end of this fragment, plaintext and recovered should both be ByteArray's containing the same data.! !MessageDigest methodsFor: 'output size' stamp: 'msh 6/16/2003 23:16'! outputSize: anInteger "Given in input block of size anInteger, return the size of the output (in bytes)." ^ self outputSize .! ! !MessageDigest methodsFor: 'sensitive data' stamp: 'msh 6/16/2003 23:18'! clearSensitiveData self reinitialize.! ! !MessageDigest methodsFor: 'digesting' stamp: 'msh 6/16/2003 23:20'! digest "return a digest, based on the content of the digesting context." | rv | rv _ ByteArray new: ( self outputSize ). self digest: rv at: 1. ^ rv .! ! !MessageDigest methodsFor: 'digesting' stamp: 'msh 6/16/2003 23:24'! update: aByteArray self update: aByteArray at: 1 count: (aByteArray size).! ! !MessageDigest methodsFor: 'private' stamp: 'msh 6/16/2003 23:22'! leftRotate: anInteger by: bits ^ (anInteger << bits) bitOr: (anInteger >> (32 - bits)) .! ! !MessageDigest methodsFor: 'private' stamp: 'msh 6/17/2003 02:11'! rightRotate: anInteger by: bits ^ (anInteger >> bits) bitOr: (anInteger << (32 - bits)) .! ! !MD2 methodsFor: 'private' stamp: 'msh 6/13/2003 01:14'! initialize "this method is evoked once by the new method. Do not call this method to initialize" "an instance of this class, call reinitialize instead." checksum _ ByteArray new: 16. count _ 1. state _ ByteArray new: 48.! ! !MD2 methodsFor: 'private' stamp: 'msh 6/13/2003 01:20'! transform "Apply the MD2 transform to the current state" | t | t _ checksum at: 16. 1 to: 16 do: [ :i | t _ (checksum at: i) bitXor: (Sbox at: (((state at: (16 +i)) bitXor: t) + 1) ). checksum at: i put: t. ]. t _ 0. 1 to: 18 do: [ :i | 1 to: 48 do: [ :j | t _ (state at: j) bitXor: (Sbox at: (1 + t) ). state at: j put: t. ]. t _ ( t + i - 1 ) bitAnd: 16rFF. ]. count _ 1.! ! !MD2 methodsFor: 'digesting' stamp: 'msh 6/13/2003 01:10'! digest: aByteArray at: anInteger "return a digest, based on the content of the digesting context." self update: (MD2Padding at: count). self update: checksum. 1 to: 16 do: [ :i | aByteArray at: (anInteger + i - 1) put: (state at: i). ].! ! !MD2 methodsFor: 'digesting' stamp: 'msh 6/13/2003 01:06'! reinitialize "This method reinitializes the state of the current MD2 context." 1 to: (checksum size) do: [ :i | checksum at: i put: 0.]. count _ 1. 1 to: (state size) do: [ :i | state at: i put: 0.].! ! !MD2 methodsFor: 'digesting' stamp: 'msh 6/13/2003 01:10'! update: aByteArray at: anIndex count: aCount "update the digesting context with the contents of aByteArray." anIndex to: (anIndex + aCount - 1) do: [ :i | state at: (16 + count) put: (aByteArray at: i). state at: (32 + count) put: ((state at: count) bitXor: (aByteArray at: i)). count _ count + 1. (count > 16) ifTrue: [ self transform. ]. ].! ! !MD2 methodsFor: 'output size' stamp: 'msh 6/13/2003 01:07'! outputSize ^16.! ! !MD4 methodsFor: 'output size' stamp: 'msh 6/13/2003 01:39'! outputSize ^16.! ! !MD4 methodsFor: 'digesting' stamp: 'msh 6/16/2003 18:20'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount _ bitCount. "append padding" ( byteCount < 56 ) ifTrue: [ self update: Padding at: 1 count: ( 56 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 121 - byteCount ). ]. "add bit count" mask _ 16rFF00000000000000. 1 to: 8 do: [ :i | byteBuffer at: ( 65 - i ) put: ( (currentBitCount bitAnd: mask) >> ( (8 - i) * 8 ) ). mask _ mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (3 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (7 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (4 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (11 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (8 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (15 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (12 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ).! ! !MD4 methodsFor: 'digesting' stamp: 'msh 6/16/2003 18:02'! reinitialize bitCount _ 0. 1 to: (byteBuffer size) do: [ :i | byteBuffer at: i put: 0 ]. byteCount _ 0. 1 to: (savedState size) do: [ :i | savedState at: i put: 0 ]. state at: 1 put: 16r67452301. state at: 2 put: 16rEFCDAB89. state at: 3 put: 16r98BADCFE. state at: 4 put: 16r10325476. 1 to: (wordBuffer size) do: [ :i | wordBuffer at: i put: 0 ].! ! !MD4 methodsFor: 'digesting' stamp: 'msh 6/16/2003 18:17'! update: aByteArray at: anIndex count: aCount "update the digesting context with the contents of aByteArray." anIndex to: (anIndex + aCount - 1) do: [ :i | byteCount _ byteCount + 1. bitCount _ bitCount + 8. ( byteCount > 64 ) ifTrue: [ byteCount _ 1. self transform. ]. byteBuffer at: byteCount put: (aByteArray at: i). ].! ! !MD4 methodsFor: 'private' stamp: 'msh 6/16/2003 18:10'! bufferConvert "Convert the contents of the byte array byteBuffer into the word array wordBuffer. " | j | 1 to: 16 do: [:i | j _ i - 1 * 4 + 1. wordBuffer at: i put: ((((byteBuffer at: j) bitOr: (byteBuffer at: 1 + j) << 8) bitOr: (byteBuffer at: 2 + j) << 16) bitOr: (byteBuffer at: 3 + j) << 24)]! ! !MD4 methodsFor: 'private' stamp: 'msh 6/16/2003 00:42'! ff: a with: b with: c with: d with: x with: s | t | t _ ( ( wordBuffer at: x ) + ( ( state at: a) + ( ( ( state at: b ) bitAnd: ( state at: c ) ) bitOr: ( ( ( state at: b ) bitInvert ) bitAnd: ( state at: d ) ) ) ) ). state at: a put: ( ( self leftRotate: ( t bitAnd: 16rFFFFFFFF ) by: s ) bitAnd: 16rFFFFFFFF ). t _ 0.! ! !MD4 methodsFor: 'private' stamp: 'msh 6/16/2003 00:42'! gg: a with: b with: c with: d with: x with: s | t | t _ ( 16r5A827999 + ( ( wordBuffer at: x ) + ( ( state at: a ) + ( ( ( state at: b ) bitAnd: ( state at: c ) ) bitOr: ( ( ( state at: b ) bitAnd: ( state at: d ) ) bitOr: ( ( state at: c ) bitAnd: ( state at: d ) ) ) ) ) ) ). state at: a put: ( ( self leftRotate: ( t bitAnd: 16rFFFFFFFF ) by: s ) bitAnd: 16rFFFFFFFF ). t _ 0. ! ! !MD4 methodsFor: 'private' stamp: 'msh 6/16/2003 00:44'! hh: a with: b with: c with: d with: x with: s |t| t _ ( 16r6ED9EBA1 + ( ( wordBuffer at: x ) + ( ( state at: a ) + ( ( state at: b ) bitXor: ( ( state at: c ) bitXor: ( state at: d ) ) ) ) ) ). state at: a put: ( ( self leftRotate: ( t bitAnd: 16rFFFFFFFF ) by: s ) bitAnd: 16rFFFFFFFF ). t _ 0.! ! !MD4 methodsFor: 'private' stamp: 'msh 11/7/2005 01:46'! initialize "this method is evoked once by the new method. Do not call this method to initialize" "an instance of this class, call reinitialize instead." bitCount _ 0. byteBuffer _ ByteArray new: 64. byteCount _ 0. savedState _ Array new: 4. state _ Array new: 4. state at: 1 put: 16r67452301. state at: 2 put: 16rEFCDAB89. state at: 3 put: 16r98BADCFE. state at: 4 put: 16r10325476. wordBuffer _ Array new: 16.! ! !MD4 methodsFor: 'private' stamp: 'msh 6/16/2003 18:20'! transform self bufferConvert. 1 to: 4 do: [ :i | savedState at: i put: (state at: i) ]. self ff: 1 with: 2 with: 3 with: 4 with: 1 with: 3. self ff: 4 with: 1 with: 2 with: 3 with: 2 with: 7. self ff: 3 with: 4 with: 1 with: 2 with: 3 with: 11. self ff: 2 with: 3 with: 4 with: 1 with: 4 with: 19. self ff: 1 with: 2 with: 3 with: 4 with: 5 with: 3. self ff: 4 with: 1 with: 2 with: 3 with: 6 with: 7. self ff: 3 with: 4 with: 1 with: 2 with: 7 with: 11. self ff: 2 with: 3 with: 4 with: 1 with: 8 with: 19. self ff: 1 with: 2 with: 3 with: 4 with: 9 with: 3. self ff: 4 with: 1 with: 2 with: 3 with: 10 with: 7. self ff: 3 with: 4 with: 1 with: 2 with: 11 with: 11. self ff: 2 with: 3 with: 4 with: 1 with: 12 with: 19. self ff: 1 with: 2 with: 3 with: 4 with: 13 with: 3. self ff: 4 with: 1 with: 2 with: 3 with: 14 with: 7. self ff: 3 with: 4 with: 1 with: 2 with: 15 with: 11. self ff: 2 with: 3 with: 4 with: 1 with: 16 with: 19. self gg: 1 with: 2 with: 3 with: 4 with: 1 with: 3. self gg: 4 with: 1 with: 2 with: 3 with: 5 with: 5. self gg: 3 with: 4 with: 1 with: 2 with: 9 with: 9. self gg: 2 with: 3 with: 4 with: 1 with: 13 with: 13. self gg: 1 with: 2 with: 3 with: 4 with: 2 with: 3. self gg: 4 with: 1 with: 2 with: 3 with: 6 with: 5. self gg: 3 with: 4 with: 1 with: 2 with: 10 with: 9. self gg: 2 with: 3 with: 4 with: 1 with: 14 with: 13. self gg: 1 with: 2 with: 3 with: 4 with: 3 with: 3. self gg: 4 with: 1 with: 2 with: 3 with: 7 with: 5. self gg: 3 with: 4 with: 1 with: 2 with: 11 with: 9. self gg: 2 with: 3 with: 4 with: 1 with: 15 with: 13. self gg: 1 with: 2 with: 3 with: 4 with: 4 with: 3. self gg: 4 with: 1 with: 2 with: 3 with: 8 with: 5. self gg: 3 with: 4 with: 1 with: 2 with: 12 with: 9. self gg: 2 with: 3 with: 4 with: 1 with: 16 with: 13. self hh: 1 with: 2 with: 3 with: 4 with: 1 with: 3. self hh: 4 with: 1 with: 2 with: 3 with: 9 with: 9. self hh: 3 with: 4 with: 1 with: 2 with: 5 with: 11. self hh: 2 with: 3 with: 4 with: 1 with: 13 with: 15. self hh: 1 with: 2 with: 3 with: 4 with: 3 with: 3. self hh: 4 with: 1 with: 2 with: 3 with: 11 with: 9. self hh: 3 with: 4 with: 1 with: 2 with: 7 with: 11. self hh: 2 with: 3 with: 4 with: 1 with: 15 with: 15. self hh: 1 with: 2 with: 3 with: 4 with: 2 with: 3. self hh: 4 with: 1 with: 2 with: 3 with: 10 with: 9. self hh: 3 with: 4 with: 1 with: 2 with: 6 with: 11. self hh: 2 with: 3 with: 4 with: 1 with: 14 with: 15. self hh: 1 with: 2 with: 3 with: 4 with: 4 with: 3. self hh: 4 with: 1 with: 2 with: 3 with: 12 with: 9. self hh: 3 with: 4 with: 1 with: 2 with: 8 with: 11. self hh: 2 with: 3 with: 4 with: 1 with: 16 with: 15. 1 to: 4 do: [ :i | state at: i put: ( ( ( state at: i ) +( savedState at: i ) ) bitAnd: 16rFFFFFFFF). savedState at: i put: 0. ].! ! !MD5 methodsFor: 'output size' stamp: 'msh 6/16/2003 08:46'! outputSize ^16.! ! !MD5 methodsFor: 'private' stamp: 'msh 6/16/2003 08:45'! bufferConvert "Convert the contents of the byte array byteBuffer into the word array wordBuffer. " | j | 1 to: 16 do: [:i | j _ i - 1 * 4 + 1. wordBuffer at: i put: ((((byteBuffer at: j) bitOr: (byteBuffer at: 1 + j) << 8) bitOr: (byteBuffer at: 2 + j) << 16) bitOr: (byteBuffer at: 3 + j) << 24)]! ! !MD5 methodsFor: 'private' stamp: 'msh 6/16/2003 11:05'! ff: a with: b with: c with: d with: x with: s with: ac | t | t _ ( T at: ac ) + (wordBuffer at: x) + (state at: a) + (((state at: b) bitAnd: (state at: c)) bitOr: ((state at: b) bitInvert bitAnd: (state at: d))). state at: a put: ((self leftRotate: (t bitAnd: 16rFFFFFFFF) by: s) bitAnd: 16rFFFFFFFF). t _ 0. state at: a put: ( ( (state at: a) + (state at: b) ) bitAnd: 16rFFFFFFFF ).! ! !MD5 methodsFor: 'private' stamp: 'msh 6/16/2003 11:05'! gg: a with: b with: c with: d with: x with: s with: ac | t | t _ ( T at: ac ) + (wordBuffer at: x) + (state at: a) + (((state at: b) bitAnd: (state at: d)) bitOr: ((state at: c) bitAnd: (state at: d) bitInvert)). state at: a put: ((self leftRotate: (t bitAnd: 16rFFFFFFFF) by: s) bitAnd: 16rFFFFFFFF). t _ 0. state at: a put: ( ( (state at: a) + (state at: b) ) bitAnd: 16rFFFFFFFF ).! ! !MD5 methodsFor: 'private' stamp: 'msh 6/16/2003 11:05'! hh: a with: b with: c with: d with: x with: s with: ac | t | t _ ( T at: ac ) + (wordBuffer at: x) + (state at: a) + (((state at: b) bitXor: (state at: c)) bitXor: (state at: d)). state at: a put: ((self leftRotate: (t bitAnd: 16rFFFFFFFF) by: s) bitAnd: 16rFFFFFFFF). t _ 0. state at: a put: ( ( (state at: a) + (state at: b) ) bitAnd: 16rFFFFFFFF ).! ! !MD5 methodsFor: 'private' stamp: 'msh 6/16/2003 11:05'! ii: a with: b with: c with: d with: x with: s with: ac | t | t _ ( T at: ac ) + (wordBuffer at: x) + (state at: a) + ((state at: c) bitXor: ((state at: b) bitOr: (state at: d) bitInvert)). state at: a put: ((self leftRotate: (t bitAnd: 16rFFFFFFFF) by: s) bitAnd: 16rFFFFFFFF). t _ 0. state at: a put: ( ( (state at: a) + (state at: b) ) bitAnd: 16rFFFFFFFF ).! ! !MD5 methodsFor: 'private' stamp: 'msh 11/7/2005 01:46'! initialize "this method is evoked once by the new method. Do not call this method to initialize" "an instance of this class, call reinitialize instead." bitCount _ 0. byteBuffer _ ByteArray new: 64. byteCount _ 0. savedState _ Array new: 4. state _ Array new: 4. state at: 1 put: 16r67452301. state at: 2 put: 16rEFCDAB89. state at: 3 put: 16r98BADCFE. state at: 4 put: 16r10325476. wordBuffer _ Array new: 16.! ! !MD5 methodsFor: 'private' stamp: 'msh 6/16/2003 17:15'! transform self bufferConvert. 1 to: 4 do: [ :i | savedState at: i put: ( state at: i ). ]. self ff: 1 with: 2 with: 3 with: 4 with: 1 with: 7 with: 1. self ff: 4 with: 1 with: 2 with: 3 with: 2 with: 12 with: 2. self ff: 3 with: 4 with: 1 with: 2 with: 3 with: 17 with: 3. self ff: 2 with: 3 with: 4 with: 1 with: 4 with: 22 with: 4. self ff: 1 with: 2 with: 3 with: 4 with: 5 with: 7 with: 5. self ff: 4 with: 1 with: 2 with: 3 with: 6 with: 12 with: 6. self ff: 3 with: 4 with: 1 with: 2 with: 7 with: 17 with: 7. self ff: 2 with: 3 with: 4 with: 1 with: 8 with: 22 with: 8. self ff: 1 with: 2 with: 3 with: 4 with: 9 with: 7 with: 9. self ff: 4 with: 1 with: 2 with: 3 with: 10 with: 12 with: 10. self ff: 3 with: 4 with: 1 with: 2 with: 11 with: 17 with: 11. self ff: 2 with: 3 with: 4 with: 1 with: 12 with: 22 with: 12. self ff: 1 with: 2 with: 3 with: 4 with: 13 with: 7 with: 13. self ff: 4 with: 1 with: 2 with: 3 with: 14 with: 12 with: 14. self ff: 3 with: 4 with: 1 with: 2 with: 15 with: 17 with: 15. self ff: 2 with: 3 with: 4 with: 1 with: 16 with: 22 with: 16. self gg: 1 with: 2 with: 3 with: 4 with: 2 with: 5 with: 17. self gg: 4 with: 1 with: 2 with: 3 with: 7 with: 9 with: 18. self gg: 3 with: 4 with: 1 with: 2 with: 12 with: 14 with: 19. self gg: 2 with: 3 with: 4 with: 1 with: 1 with: 20 with: 20. self gg: 1 with: 2 with: 3 with: 4 with: 6 with: 5 with: 21. self gg: 4 with: 1 with: 2 with: 3 with: 11 with: 9 with: 22. self gg: 3 with: 4 with: 1 with: 2 with: 16 with: 14 with: 23. self gg: 2 with: 3 with: 4 with: 1 with: 5 with: 20 with: 24. self gg: 1 with: 2 with: 3 with: 4 with: 10 with: 5 with: 25. self gg: 4 with: 1 with: 2 with: 3 with: 15 with: 9 with: 26. self gg: 3 with: 4 with: 1 with: 2 with: 4 with: 14 with: 27. self gg: 2 with: 3 with: 4 with: 1 with: 9 with: 20 with: 28. self gg: 1 with: 2 with: 3 with: 4 with: 14 with: 5 with: 29. self gg: 4 with: 1 with: 2 with: 3 with: 3 with: 9 with: 30. self gg: 3 with: 4 with: 1 with: 2 with: 8 with: 14 with: 31. self gg: 2 with: 3 with: 4 with: 1 with: 13 with: 20 with: 32. self hh: 1 with: 2 with: 3 with: 4 with: 6 with: 4 with: 33. self hh: 4 with: 1 with: 2 with: 3 with: 9 with: 11 with: 34. self hh: 3 with: 4 with: 1 with: 2 with: 12 with: 16 with: 35. self hh: 2 with: 3 with: 4 with: 1 with: 15 with: 23 with: 36. self hh: 1 with: 2 with: 3 with: 4 with: 2 with: 4 with: 37. self hh: 4 with: 1 with: 2 with: 3 with: 5 with: 11 with: 38. self hh: 3 with: 4 with: 1 with: 2 with: 8 with: 16 with: 39. self hh: 2 with: 3 with: 4 with: 1 with: 11 with: 23 with: 40. self hh: 1 with: 2 with: 3 with: 4 with: 14 with: 4 with: 41. self hh: 4 with: 1 with: 2 with: 3 with: 1 with: 11 with: 42. self hh: 3 with: 4 with: 1 with: 2 with: 4 with: 16 with: 43. self hh: 2 with: 3 with: 4 with: 1 with: 7 with: 23 with: 44. self hh: 1 with: 2 with: 3 with: 4 with: 10 with: 4 with: 45. self hh: 4 with: 1 with: 2 with: 3 with: 13 with: 11 with: 46. self hh: 3 with: 4 with: 1 with: 2 with: 16 with: 16 with: 47. self hh: 2 with: 3 with: 4 with: 1 with: 3 with: 23 with: 48. self ii: 1 with: 2 with: 3 with: 4 with: 1 with: 6 with: 49. self ii: 4 with: 1 with: 2 with: 3 with: 8 with: 10 with: 50. self ii: 3 with: 4 with: 1 with: 2 with: 15 with: 15 with: 51. self ii: 2 with: 3 with: 4 with: 1 with: 6 with: 21 with: 52. self ii: 1 with: 2 with: 3 with: 4 with: 13 with: 6 with: 53. self ii: 4 with: 1 with: 2 with: 3 with: 4 with: 10 with: 54. self ii: 3 with: 4 with: 1 with: 2 with: 11 with: 15 with: 55. self ii: 2 with: 3 with: 4 with: 1 with: 2 with: 21 with: 56. self ii: 1 with: 2 with: 3 with: 4 with: 9 with: 6 with: 57. self ii: 4 with: 1 with: 2 with: 3 with: 16 with: 10 with: 58. self ii: 3 with: 4 with: 1 with: 2 with: 7 with: 15 with: 59. self ii: 2 with: 3 with: 4 with: 1 with: 14 with: 21 with: 60. self ii: 1 with: 2 with: 3 with: 4 with: 5 with: 6 with: 61. self ii: 4 with: 1 with: 2 with: 3 with: 12 with: 10 with: 62. self ii: 3 with: 4 with: 1 with: 2 with: 3 with: 15 with: 63. self ii: 2 with: 3 with: 4 with: 1 with: 10 with: 21 with: 64. 1 to: 4 do: [ :i | state at: i put: (((state at: i) + (savedState at: i)) bitAnd: 16rFFFFFFFF). savedState at: i put: 0. ].! ! !MD5 methodsFor: 'digesting' stamp: 'msh 6/16/2003 13:54'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount _ bitCount. "append padding" ( byteCount < 56 ) ifTrue: [ self update: Padding at: 1 count: ( 56 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 121 - byteCount ). ]. "add bit count" mask _ 16rFF00000000000000. 1 to: 8 do: [ :i | byteBuffer at: ( 65 - i ) put: ( (currentBitCount bitAnd: mask) >> ( (8 - i) * 8 ) ). mask _ mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (3 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (7 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (4 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (11 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (8 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (15 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (12 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ).! ! !MD5 methodsFor: 'digesting' stamp: 'msh 6/16/2003 09:24'! reinitialize bitCount _ 0. 1 to: (byteBuffer size) do: [ :i | byteBuffer at: i put: 0 ]. byteCount _ 0. 1 to: (savedState size) do: [ :i | savedState at: i put: 0 ]. state at: 1 put: 16r67452301. state at: 2 put: 16rEFCDAB89. state at: 3 put: 16r98BADCFE. state at: 4 put: 16r10325476. 1 to: (wordBuffer size) do: [ :i | wordBuffer at: i put: 0 ].! ! !MD5 methodsFor: 'digesting' stamp: 'msh 6/16/2003 17:15'! update: aByteArray at: anIndex count: aCount anIndex to: (anIndex + aCount - 1) do: [ :i | byteCount _ byteCount + 1. bitCount _ bitCount + 8. ( byteCount > 64 ) ifTrue: [ byteCount _ 1. self transform. ]. byteBuffer at: byteCount put: ( aByteArray at: i ). ].! ! !MessageDigest class methodsFor: 'class initialization' stamp: 'msh 12/9/2005 04:05'! initialize "Initialize Self" Padding := #(128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) . "Initialize Subclasses" self subclasses do: [ :c | ( c class includesSelector: #initialize ) ifTrue: [ c perform: #initialize ] ]! ! !MD2 class methodsFor: 'class initialization' stamp: 'msh 6/16/2003 23:40'! initialize "Initialize the Sbox and MD2Padding class variables." Sbox _ #( 16r29 16r2E 16r43 16rC9 16rA2 16rD8 16r7C 16r01 16r3D 16r36 16r54 16rA1 16rEC 16rF0 16r06 16r13 16r62 16rA7 16r05 16rF3 16rC0 16rC7 16r73 16r8C 16r98 16r93 16r2B 16rD9 16rBC 16r4C 16r82 16rCA 16r1E 16r9B 16r57 16r3C 16rFD 16rD4 16rE0 16r16 16r67 16r42 16r6F 16r18 16r8A 16r17 16rE5 16r12 16rBE 16r4E 16rC4 16rD6 16rDA 16r9E 16rDE 16r49 16rA0 16rFB 16rF5 16r8E 16rBB 16r2F 16rEE 16r7A 16rA9 16r68 16r79 16r91 16r15 16rB2 16r07 16r3F 16r94 16rC2 16r10 16r89 16r0B 16r22 16r5F 16r21 16r80 16r7F 16r5D 16r9A 16r5A 16r90 16r32 16r27 16r35 16r3E 16rCC 16rE7 16rBF 16rF7 16r97 16r03 16rFF 16r19 16r30 16rB3 16r48 16rA5 16rB5 16rD1 16rD7 16r5E 16r92 16r2A 16rAC 16r56 16rAA 16rC6 16r4F 16rB8 16r38 16rD2 16r96 16rA4 16r7D 16rB6 16r76 16rFC 16r6B 16rE2 16r9C 16r74 16r04 16rF1 16r45 16r9D 16r70 16r59 16r64 16r71 16r87 16r20 16r86 16r5B 16rCF 16r65 16rE6 16r2D 16rA8 16r02 16r1B 16r60 16r25 16rAD 16rAE 16rB0 16rB9 16rF6 16r1C 16r46 16r61 16r69 16r34 16r40 16r7E 16r0F 16r55 16r47 16rA3 16r23 16rDD 16r51 16rAF 16r3A 16rC3 16r5C 16rF9 16rCE 16rBA 16rC5 16rEA 16r26 16r2C 16r53 16r0D 16r6E 16r85 16r28 16r84 16r09 16rD3 16rDF 16rCD 16rF4 16r41 16r81 16r4D 16r52 16r6A 16rDC 16r37 16rC8 16r6C 16rC1 16rAB 16rFA 16r24 16rE1 16r7B 16r08 16r0C 16rBD 16rB1 16r4A 16r78 16r88 16r95 16r8B 16rE3 16r63 16rE8 16r6D 16rE9 16rCB 16rD5 16rFE 16r3B 16r00 16r1D 16r39 16rF2 16rEF 16rB7 16r0E 16r66 16r58 16rD0 16rE4 16rA6 16r77 16r72 16rF8 16rEB 16r75 16r4B 16r0A 16r31 16r44 16r50 16rB4 16r8F 16rED 16r1F 16r1A 16rDB 16r99 16r8D 16r33 16r9F 16r11 16r83 16r14 ). MD2Padding _ #( #( 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 ) #( 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ) #( 14 14 14 14 14 14 14 14 14 14 14 14 14 14 ) #( 13 13 13 13 13 13 13 13 13 13 13 13 13 ) #( 12 12 12 12 12 12 12 12 12 12 12 12 ) #( 11 11 11 11 11 11 11 11 11 11 11 ) #( 10 10 10 10 10 10 10 10 10 10 ) #( 9 9 9 9 9 9 9 9 9 ) #( 8 8 8 8 8 8 8 8 ) #( 7 7 7 7 7 7 7 ) #( 6 6 6 6 6 6 ) #( 5 5 5 5 5 ) #( 4 4 4 4 ) #( 3 3 3 ) #( 2 2 ) #( 1 ) ). ! ! !MD2 class methodsFor: 'instance creation' stamp: 'msh 6/13/2003 01:02'! new ^super new initialize.! ! !MD4 class methodsFor: 'instance creation' stamp: 'msh 6/13/2003 01:23'! new ^super new initialize.! ! !MD5 class methodsFor: 'instance creation' stamp: 'msh 6/16/2003 08:37'! new ^super new initialize.! ! !MD5 class methodsFor: 'class initialization' stamp: 'msh 11/30/2005 23:17'! initialize T := #( 16rD76AA478 16rE8C7B756 16r242070DB 16rC1BDCEEE 16rF57C0FAF 16r4787C62A 16rA8304613 16rFD469501 16r698098D8 16r8B44F7AF 16rFFFF5BB1 16r895CD7BE 16r6B901122 16rFD987193 16rA679438E 16r49B40821 16rF61E2562 16rC040B340 16r265E5A51 16rE9B6C7AA 16rD62F105D 16r2441453 16rD8A1E681 16rE7D3FBC8 16r21E1CDE6 16rC33707D6 16rF4D50D87 16r455A14ED 16rA9E3E905 16rFCEFA3F8 16r676F02D9 16r8D2A4C8A 16rFFFA3942 16r8771F681 16r6D9D6122 16rFDE5380C 16rA4BEEA44 16r4BDECFA9 16rF6BB4B60 16rBEBFBC70 16r289B7EC6 16rEAA127FA 16rD4EF3085 16r4881D05 16rD9D4D039 16rE6DB99E5 16r1FA27CF8 16rC4AC5665 16rF4292244 16r432AFF97 16rAB9423A7 16rFC93A039 16r655B59C3 16r8F0CCC92 16rFFEFF47D 16r85845DD1 16r6FA87E4F 16rFE2CE6E0 16rA3014314 16r4E0811A1 16rF7537E82 16rBD3AF235 16r2AD7D2BB 16rEB86D391 ). ! ! !SHA1 methodsFor: 'private' stamp: 'msh 6/17/2003 01:18'! bufferConvert "Convert the contents of the byte array byteBuffer into the word array wordBuffer. " | j | 1 to: 16 do: [:i | j _ i - 1 * 4 + 1. wordBuffer at: i put: ((((byteBuffer at: (3 +j) ) bitOr: (byteBuffer at: 2 + j) << 8) bitOr: (byteBuffer at: 1 + j) << 16) bitOr: (byteBuffer at: j) << 24)]! ! !SHA1 methodsFor: 'private' stamp: 'msh 6/17/2003 00:52'! ch ^ (((state at: 2) bitAnd: (state at: 3)) bitXor: (((state at: 2) bitInvert ) bitAnd: (state at: 4))) .! ! !SHA1 methodsFor: 'private' stamp: 'msh 11/7/2005 01:47'! initialize bitCount _ 0. byteBuffer _ ByteArray new: 64. byteCount _ 0. savedState _ Array new: 5. state _ Array new: 5. state at: 1 put: 16r67452301. state at: 2 put: 16rEFCDAB89. state at: 3 put: 16r98BADCFE. state at: 4 put: 16r10325476. state at: 5 put: 16rC3D2E1F0. wordBuffer _ Array new: 16. workBuffer _ Array new: 80.! ! !SHA1 methodsFor: 'private' stamp: 'msh 6/17/2003 00:55'! maj ^ ( ( ( ( state at: 2 ) bitAnd: ( state at: 3 ) ) bitXor: ( ( state at: 2 ) bitAnd: ( state at: 4 ) ) ) bitXor: ( ( state at: 3 ) bitAnd: ( state at: 4 ) ) ).! ! !SHA1 methodsFor: 'private' stamp: 'msh 6/17/2003 00:53'! parity ^ ( ( ( state at: 2 ) bitXor: ( state at: 3 ) ) bitXor: ( state at: 4 ) ).! ! !SHA1 methodsFor: 'private' stamp: 'msh 6/17/2003 01:31'! transform | t | self bufferConvert. 1 to: 16 do: [ :i | workBuffer at: i put: ( wordBuffer at: i ). ]. 17 to: 80 do: [ :i | workBuffer at: i put: ( ( self leftRotate: ( ( ( ( ( workBuffer at: ( i - 3 ) ) bitXor: ( workBuffer at: ( i - 8 ) ) ) bitXor: ( workBuffer at: ( i - 14) ) ) bitXor: ( workBuffer at: ( i - 16) ) ) ) by: 1 ) bitAnd: 16rFFFFFFFF ). ]. 1 to: 5 do: [ :i | savedState at: i put: ( state at: i ). ]. 1 to: 80 do: [ :i | t _ ( (self leftRotate: (state at: 1) by: 5 ) + (state at: 5) + (K at: i) + (workBuffer at: i) ) bitAnd: 16rFFFFFFFF. ( i between: 1 and: 20 ) ifTrue: [ t _ ( t + ( self ch ) ) bitAnd: 16rFFFFFFFF. ]. ( i between: 21 and: 40 ) ifTrue: [ t _ ( t + ( self parity ) ) bitAnd: 16rFFFFFFFF. ]. ( i between: 41 and: 60 ) ifTrue: [ t _ ( t + ( self maj ) ) bitAnd: 16rFFFFFFFF. ]. ( i between: 61 and: 80 ) ifTrue: [ t _ ( t + ( self parity ) ) bitAnd: 16rFFFFFFFF. ]. state at: 5 put: ( state at: 4 ). state at: 4 put: ( state at: 3 ). state at: 3 put: ( ( self leftRotate: (state at: 2) by: 30 ) bitAnd: 16rFFFFFFFF ). state at: 2 put: ( state at: 1 ). state at: 1 put: t. ]. 1 to: 5 do: [ :i | state at: i put: ( ( ( state at: i ) + ( savedState at: i ) ) bitAnd: 16rFFFFFFFF ). ].! ! !SHA1 methodsFor: 'output size' stamp: 'msh 6/17/2003 00:09'! outputSize ^20.! ! !SHA1 methodsFor: 'digesting' stamp: 'msh 6/17/2003 01:31'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount _ bitCount. "append padding" ( byteCount < 56 ) ifTrue: [ self update: Padding at: 1 count: ( 56 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 121 - byteCount ). ]. "add bit count" mask _ 16rFF00000000000000. 1 to: 8 do: [ :i | byteBuffer at: ( 56 + i ) put: ( (currentBitCount bitAnd: mask) >> ( (8 - i) * 8 ) ). mask _ mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (3 + anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (4 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (7 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (8 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (11 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (12 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (15 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ). aByteArray at: (16 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (17 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (18 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (19 + anIndex) put: ( ( state at: 5 ) bitAnd: 16rFF ).! ! !SHA1 methodsFor: 'digesting' stamp: 'msh 6/17/2003 00:10'! reinitialize bitCount _ 0. 1 to: (byteBuffer size) do: [ :i | byteBuffer at: i put: 0 ]. byteCount _ 0. 1 to: (savedState size) do: [ :i | savedState at: i put: 0 ]. state at: 1 put: 16r67452301. state at: 2 put: 16rEFCDAB89. state at: 3 put: 16r98BADCFE. state at: 4 put: 16r10325476. state at: 5 put: 16rC3D2E1F0. 1 to: (wordBuffer size) do: [ :i | wordBuffer at: i put: 0 ].! ! !SHA1 methodsFor: 'digesting' stamp: 'msh 6/17/2003 00:10'! update: aByteArray at: anIndex count: aCount anIndex to: (anIndex + aCount - 1) do: [ :i | byteCount _ byteCount + 1. bitCount _ bitCount + 8. ( byteCount > 64 ) ifTrue: [ byteCount _ 1. self transform. ]. byteBuffer at: byteCount put: ( aByteArray at: i ). ].! ! !SHA1 class methodsFor: 'instance creation' stamp: 'msh 6/17/2003 00:02'! new ^super new initialize.! ! !SHA1 class methodsFor: 'class initialization' stamp: 'msh 6/17/2003 00:34'! initialize K _ #( 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r5A827999 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r6ED9EBA1 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16r8F1BBCDC 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 16rCA62C1D6 ).! ! !SHA256 methodsFor: 'output size' stamp: 'msh 6/17/2003 02:29'! outputSize ^32.! ! !SHA256 methodsFor: 'digesting' stamp: 'msh 6/17/2003 01:57'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount _ bitCount. "append padding" ( byteCount < 56 ) ifTrue: [ self update: Padding at: 1 count: ( 56 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 121 - byteCount ). ]. "add bit count" mask _ 16rFF00000000000000. 1 to: 8 do: [ :i | byteBuffer at: ( 56 + i ) put: ( (currentBitCount bitAnd: mask) >> ( (8 - i) * 8 ) ). mask _ mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (3 + anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (4 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (7 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (8 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (11 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (12 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (15 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ). aByteArray at: (16 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (17 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (18 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (19 + anIndex) put: ( ( state at: 5 ) bitAnd: 16rFF ). aByteArray at: (20 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (21 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (22 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (23 + anIndex) put: ( ( state at: 6 ) bitAnd: 16rFF ). aByteArray at: (24 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (25 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (26 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (27 + anIndex) put: ( ( state at: 7 ) bitAnd: 16rFF ). aByteArray at: (28 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (29 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (30 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (31 + anIndex) put: ( ( state at: 8 ) bitAnd: 16rFF ).! ! !SHA256 methodsFor: 'digesting' stamp: 'msh 6/17/2003 02:27'! reinitialize bitCount _ 0. 1 to: (byteBuffer size) do: [ :i | byteBuffer at: i put: 0 ]. byteCount _ 0. 1 to: (savedState size) do: [ :i | savedState at: i put: 0 ]. state at: 1 put: 16r6A09E667. state at: 2 put: 16rBB67AE85. state at: 3 put: 16r3C6EF372. state at: 4 put: 16rA54FF53A. state at: 5 put: 16r510E527F. state at: 6 put: 16r9B05688C. state at: 7 put: 16r1F83D9AB. state at: 8 put: 16r5BE0CD19. 1 to: (wordBuffer size) do: [ :i | wordBuffer at: i put: 0 ].! ! !SHA256 methodsFor: 'digesting' stamp: 'msh 6/17/2003 02:01'! update: aByteArray at: anIndex count: aCount anIndex to: (anIndex + aCount - 1) do: [ :i | byteCount _ byteCount + 1. bitCount _ bitCount + 8. ( byteCount > 64 ) ifTrue: [ byteCount _ 1. self transform. ]. byteBuffer at: byteCount put: ( aByteArray at: i ). ].! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:02'! bufferConvert "Convert the contents of the byte array byteBuffer into the word array wordBuffer. " | j | 1 to: 16 do: [:i | j _ i - 1 * 4 + 1. wordBuffer at: i put: ((((byteBuffer at: (3 +j) ) bitOr: (byteBuffer at: 2 + j) << 8) bitOr: (byteBuffer at: 1 + j) << 16) bitOr: (byteBuffer at: j) << 24)]! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:08'! ch ^ (((state at: 5) bitAnd: (state at: 6)) bitXor: (((state at: 5) bitInvert ) bitAnd: (state at: 7))) .! ! !SHA256 methodsFor: 'private' stamp: 'msh 11/7/2005 01:47'! initialize bitCount _ 0. byteBuffer _ ByteArray new: 64. byteCount _ 0. savedState _ Array new: 8. state _ Array new: 8. state at: 1 put: 16r6A09E667. state at: 2 put: 16rBB67AE85. state at: 3 put: 16r3C6EF372. state at: 4 put: 16rA54FF53A. state at: 5 put: 16r510E527F. state at: 6 put: 16r9B05688C. state at: 7 put: 16r1F83D9AB. state at: 8 put: 16r5BE0CD19. wordBuffer _ Array new: 16. workBuffer _ Array new: 64.! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:09'! maj ^ ( ( ( ( state at: 1 ) bitAnd: ( state at: 2 ) ) bitXor: ( ( state at: 1 ) bitAnd: ( state at: 3 ) ) ) bitXor: ( ( state at: 2 ) bitAnd: ( state at: 3 ) ) ).! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:14'! s0: anInteger ^ ((((self rightRotate: anInteger by: 7) bitXor: (self rightRotate: anInteger by: 18)) bitXor: (anInteger >> 3)) bitAnd: 16rFFFFFFFF).! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:14'! s1: anInteger ^ ((((self rightRotate: anInteger by: 17) bitXor: (self rightRotate: anInteger by: 19)) bitXor: (anInteger >> 10)) bitAnd: 16rFFFFFFFF).! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:13'! sum0: anInteger ^ ((((self rightRotate: anInteger by: 2) bitXor: (self rightRotate: anInteger by: 13)) bitXor: (self rightRotate: anInteger by: 22)) bitAnd: 16rFFFFFFFF).! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:13'! sum1: anInteger ^ ((((self rightRotate: anInteger by: 6) bitXor: (self rightRotate: anInteger by: 11)) bitXor: (self rightRotate: anInteger by: 25)) bitAnd: 16rFFFFFFFF).! ! !SHA256 methodsFor: 'private' stamp: 'msh 6/17/2003 02:25'! transform | t1 t2 | self bufferConvert. 1 to: 16 do: [ :i | workBuffer at: i put: ( wordBuffer at: i ). ]. 17 to: 64 do: [ :i | workBuffer at: i put: ( ((self s1:(workBuffer at: (i-2))) + (workBuffer at: (i-7)) + (self s0:(workBuffer at: (i-15))) + (workBuffer at: (i-16))) bitAnd: 16rFFFFFFFF ). ]. 1 to: 8 do: [ :i | savedState at: i put: ( state at: i ). ]. 1 to: 64 do: [ :i | t1 _ ((state at: 8) + (self sum1:(state at: 5)) + (self ch) + (K at: i) + (workBuffer at: i)) bitAnd: 16rFFFFFFFF. t2 _ ((self sum0: (state at: 1)) + (self maj)) bitAnd: 16rFFFFFFFF. state at: 8 put: (state at: 7). state at: 7 put: (state at: 6). state at: 6 put: (state at: 5). state at: 5 put: (((state at: 4) + t1) bitAnd: 16rFFFFFFFF). state at: 4 put: (state at: 3). state at: 3 put: (state at: 2). state at: 2 put: (state at: 1). state at: 1 put: ((t1 + t2) bitAnd: 16rFFFFFFFF). ]. 1 to: 8 do: [ :i | state at: i put: ( ( ( state at: i ) + ( savedState at: i ) ) bitAnd: 16rFFFFFFFF ). ].! ! !SHA224 methodsFor: 'private' stamp: 'msh 12/9/2005 01:19'! initialize super initialize. state at: 1 put: 16rC1059ED8. state at: 2 put: 16r367CD507. state at: 3 put: 16r3070DD17. state at: 4 put: 16rF70E5939. state at: 5 put: 16rFFC00B31. state at: 6 put: 16r68581511. state at: 7 put: 16r64F98FA7. state at: 8 put: 16rBEFA4FA4.! ! !SHA224 methodsFor: 'digesting' stamp: 'msh 12/9/2005 01:22'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount := bitCount. "append padding" ( byteCount < 56 ) ifTrue: [ self update: Padding at: 1 count: ( 56 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 121 - byteCount ). ]. "add bit count" mask := 16rFF00000000000000. 1 to: 8 do: [ :i | byteBuffer at: ( 56 + i ) put: ( (currentBitCount bitAnd: mask) >> ( (8 - i) * 8 ) ). mask := mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (3 + anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (4 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (7 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (8 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (11 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (12 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (15 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ). aByteArray at: (16 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (17 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (18 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (19 + anIndex) put: ( ( state at: 5 ) bitAnd: 16rFF ). aByteArray at: (20 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (21 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (22 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (23 + anIndex) put: ( ( state at: 6 ) bitAnd: 16rFF ). aByteArray at: (24 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (25 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (26 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (27 + anIndex) put: ( ( state at: 7 ) bitAnd: 16rFF ). ! ! !SHA224 methodsFor: 'digesting' stamp: 'msh 12/9/2005 01:18'! reinitialize super reinitialize. state at: 1 put: 16rC1059ED8. state at: 2 put: 16r367CD507. state at: 3 put: 16r3070DD17. state at: 4 put: 16rF70E5939. state at: 5 put: 16rFFC00B31. state at: 6 put: 16r68581511. state at: 7 put: 16r64F98FA7. state at: 8 put: 16rBEFA4FA4.! ! !SHA224 methodsFor: 'output size' stamp: 'msh 12/9/2005 01:14'! outputSize ^ 28 .! ! !SHA256 class methodsFor: 'instance creation' stamp: 'msh 6/17/2003 01:53'! new ^super new initialize.! ! !SHA256 class methodsFor: 'class initialization' stamp: 'msh 6/17/2003 01:55'! initialize K _ #( 16r428A2F98 16r71374491 16rB5C0FBCF 16rE9B5DBA5 16r3956C25B 16r59F111F1 16r923F82A4 16rAB1C5ED5 16rD807AA98 16r12835B01 16r243185BE 16r550C7DC3 16r72BE5D74 16r80DEB1FE 16r9BDC06A7 16rC19BF174 16rE49B69C1 16rEFBE4786 16r0FC19DC6 16r240CA1CC 16r2DE92C6F 16r4A7484AA 16r5CB0A9DC 16r76F988DA 16r983E5152 16rA831C66D 16rB00327C8 16rBF597FC7 16rC6E00BF3 16rD5A79147 16r06CA6351 16r14292967 16r27B70A85 16r2E1B2138 16r4D2C6DFC 16r53380D13 16r650A7354 16r766A0ABB 16r81C2C92E 16r92722C85 16rA2BFE8A1 16rA81A664B 16rC24B8B70 16rC76C51A3 16rD192E819 16rD6990624 16rF40E3585 16r106AA070 16r19A4C116 16r1E376C08 16r2748774C 16r34B0BCB5 16r391C0CB3 16r4ED8AA4A 16r5B9CCA4F 16r682E6FF3 16r748F82EE 16r78A5636F 16r84C87814 16r8CC70208 16r90BEFFFA 16rA4506CEB 16rBEF9A3F7 16rC67178F2 ).! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 03:27'! bufferConvert "Convert the contents of the byte array byteBuffer into the word array wordBuffer. " | j | 1 to: 16 do: [:i | j := i - 1 * 8 + 1. wordBuffer at: i put: ((((((((byteBuffer at: (7 +j) ) bitOr: (byteBuffer at: 6 + j) << 8) bitOr: (byteBuffer at: 5 + j) << 16) bitOr: (byteBuffer at: 4 +j) << 24) bitOr: (byteBuffer at: 3 + j) << 32) bitOr: (byteBuffer at: 2 + j) << 40) bitOr: (byteBuffer at: 1 +j) << 48) bitOr: (byteBuffer at: j) << 56)]! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 03:33'! ch ^ (((state at: 5) bitAnd: (state at: 6)) bitXor: (((state at: 5) bitInvert ) bitAnd: (state at: 7))) .! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 03:35'! initialize bitCount := 0. byteBuffer := ByteArray new: 128. byteCount := 0. savedState := Array new: 8. state := Array new: 8. state at: 1 put: 16r6A09E667F3BCC908. state at: 2 put: 16rBB67AE8584CAA73B. state at: 3 put: 16r3C6EF372FE94F82B. state at: 4 put: 16rA54FF53A5F1D36F1. state at: 5 put: 16r510E527FADE682D1. state at: 6 put: 16r9B05688C2B3E6C1F. state at: 7 put: 16r1F83D9ABFB41BD6B. state at: 8 put: 16r5BE0CD19137E2179. wordBuffer := Array new: 16. workBuffer := Array new: 80.! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 03:34'! maj ^ ( ( ( ( state at: 1 ) bitAnd: ( state at: 2 ) ) bitXor: ( ( state at: 1 ) bitAnd: ( state at: 3 ) ) ) bitXor: ( ( state at: 2 ) bitAnd: ( state at: 3 ) ) ).! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 01:55'! s0: anInteger ^ ((((self rightRotate: anInteger by: 1) bitXor: (self rightRotate: anInteger by: 8)) bitXor: (anInteger >> 7)) bitAnd: 16rFFFFFFFFFFFFFFFF).! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 01:55'! s1: anInteger ^ ((((self rightRotate: anInteger by: 19) bitXor: (self rightRotate: anInteger by: 61)) bitXor: (anInteger >> 6)) bitAnd: 16rFFFFFFFFFFFFFFFF).! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 01:56'! sum0: anInteger ^ ((((self rightRotate: anInteger by: 28) bitXor: (self rightRotate: anInteger by: 34)) bitXor: (self rightRotate: anInteger by: 39)) bitAnd: 16rFFFFFFFFFFFFFFFF).! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 01:57'! sum1: anInteger ^ ((((self rightRotate: anInteger by: 14) bitXor: (self rightRotate: anInteger by: 18)) bitXor: (self rightRotate: anInteger by: 41)) bitAnd: 16rFFFFFFFFFFFFFFFF).! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 04:07'! transform | t1 t2 | self bufferConvert. 1 to: 16 do: [ :i | workBuffer at: i put: ( wordBuffer at: i ). ]. 17 to: 80 do: [ :i | workBuffer at: i put: ( ((self s1:(workBuffer at: (i-2))) + (workBuffer at: (i-7)) + (self s0:(workBuffer at: (i-15))) + (workBuffer at: (i-16))) bitAnd: 16rFFFFFFFFFFFFFFFF ). ]. 1 to: 8 do: [ :i | savedState at: i put: ( state at: i ). ]. 1 to: 80 do: [ :i | t1 := ((state at: 8) + (self sum1:(state at: 5)) + (self ch) + (K512 at: i) + (workBuffer at: i)) bitAnd: 16rFFFFFFFFFFFFFFFF. t2 := ((self sum0: (state at: 1)) + (self maj)) bitAnd: 16rFFFFFFFFFFFFFFFF. state at: 8 put: (state at: 7). state at: 7 put: (state at: 6). state at: 6 put: (state at: 5). state at: 5 put: (((state at: 4) + t1) bitAnd: 16rFFFFFFFFFFFFFFFF). state at: 4 put: (state at: 3). state at: 3 put: (state at: 2). state at: 2 put: (state at: 1). state at: 1 put: ((t1 + t2) bitAnd: 16rFFFFFFFFFFFFFFFF). ]. 1 to: 8 do: [ :i | state at: i put: ( ( ( state at: i ) + ( savedState at: i ) ) bitAnd: 16rFFFFFFFFFFFFFFFF ). ].! ! !SHA512 methodsFor: 'private' stamp: 'msh 12/9/2005 03:07'! update: aByteArray at: anIndex count: aCount anIndex to: (anIndex + aCount - 1) do: [ :i | byteCount := byteCount + 1. bitCount := bitCount + 8. ( byteCount > 128 ) ifTrue: [ byteCount := 1. self transform. ]. byteBuffer at: byteCount put: ( aByteArray at: i ). ].! ! !SHA512 methodsFor: 'output size' stamp: 'msh 12/9/2005 01:43'! outputSize ^64.! ! !SHA512 methodsFor: 'digesting' stamp: 'msh 12/9/2005 04:00'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount := bitCount. "append padding" ( byteCount < 112 ) ifTrue: [ self update: Padding at: 1 count: ( 112 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 121 - byteCount ). ]. "add bit count" mask := 16rFF000000000000000000000000000000. 1 to: 16 do: [ :i | byteBuffer at: ( 112 + i ) put: ( (currentBitCount bitAnd: mask) >> ( (16 - i) * 8 ) ). mask := mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (3 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (4 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (7 + anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (8 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (11 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (12 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (15 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (16 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (17 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (18 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (19 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (20 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (21 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (22 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (23 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (24 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (25 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (26 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (27 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (28 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (29 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (30 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (31 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ). aByteArray at: (32 +anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (33 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (34 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (35 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (36 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (37 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (38 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (39 + anIndex) put: ( ( state at: 5 ) bitAnd: 16rFF ). aByteArray at: (40 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (41 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (42 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (43 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (44 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (45 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (46 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (47 + anIndex) put: ( ( state at: 6 ) bitAnd: 16rFF ). aByteArray at: (48 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (49 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (50 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (51 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (52 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (53 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (54 + anIndex) put: ( ( ( state at: 7 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (55 + anIndex) put: ( ( state at: 7 ) bitAnd: 16rFF ). aByteArray at: (56 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (57 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (58 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (59 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (60 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (61 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (62 + anIndex) put: ( ( ( state at: 8 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (63 + anIndex) put: ( ( state at: 8 ) bitAnd: 16rFF ).! ! !SHA512 methodsFor: 'digesting' stamp: 'msh 12/9/2005 02:41'! leftRotate: anInteger by: bits ^ (anInteger << bits) bitOr: (anInteger >> (64 - bits)) .! ! !SHA512 methodsFor: 'digesting' stamp: 'msh 12/9/2005 04:08'! reinitialize bitCount := 0. 1 to: (byteBuffer size) do: [ :i | byteBuffer at: i put: 0 ]. byteCount := 0. 1 to: (savedState size) do: [ :i | savedState at: i put: 0 ]. state at: 1 put: 16r6A09E667F3BCC908. state at: 2 put: 16rBB67AE8584CAA73B. state at: 3 put: 16r3C6EF372FE94F82B. state at: 4 put: 16rA54FF53A5F1D36F1. state at: 5 put: 16r510E527FADE682D1. state at: 6 put: 16r9B05688C2B3E6C1F. state at: 7 put: 16r1F83D9ABFB41BD6B. state at: 8 put: 16r5BE0CD19137E2179. 1 to: (wordBuffer size) do: [ :i | wordBuffer at: i put: 0 ].! ! !SHA512 methodsFor: 'digesting' stamp: 'msh 12/9/2005 02:41'! rightRotate: anInteger by: bits ^ (anInteger >> bits) bitOr: (anInteger << (64 - bits)) .! ! !SHA384 methodsFor: 'output size' stamp: 'msh 12/9/2005 04:19'! outputSize ^48.! ! !SHA384 methodsFor: 'digesting' stamp: 'msh 12/9/2005 04:22'! digest: aByteArray at: anIndex | currentBitCount mask | currentBitCount := bitCount. "append padding" ( byteCount < 112 ) ifTrue: [ self update: Padding at: 1 count: ( 112 - byteCount ). ] ifFalse: [ self update: Padding at: 1 count: ( 241 - byteCount ). ]. "add bit count" mask := 16rFF000000000000000000000000000000. 1 to: 16 do: [ :i | byteBuffer at: ( 112 + i ) put: ( (currentBitCount bitAnd: mask) >> ( (16 - i) * 8 ) ). mask := mask >> 8. ]. "transform the final buffer" self transform. "write state to output" aByteArray at: (anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (1 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (2 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (3 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (4 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (5 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (6 + anIndex) put: ( ( ( state at: 1 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (7 + anIndex) put: ( ( state at: 1 ) bitAnd: 16rFF ). aByteArray at: (8 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (9 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (10 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (11 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (12 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (13 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (14 + anIndex) put: ( ( ( state at: 2 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (15 + anIndex) put: ( ( state at: 2 ) bitAnd: 16rFF ). aByteArray at: (16 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (17 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (18 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (19 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (20 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (21 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (22 + anIndex) put: ( ( ( state at: 3 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (23 + anIndex) put: ( ( state at: 3 ) bitAnd: 16rFF ). aByteArray at: (24 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (25 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (26 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (27 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (28 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (29 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (30 + anIndex) put: ( ( ( state at: 4 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (31 + anIndex) put: ( ( state at: 4 ) bitAnd: 16rFF ). aByteArray at: (32 +anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (33 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (34 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (35 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (36 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (37 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (38 + anIndex) put: ( ( ( state at: 5 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (39 + anIndex) put: ( ( state at: 5 ) bitAnd: 16rFF ). aByteArray at: (40 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00000000000000 ) >> 56 ). aByteArray at: (41 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF000000000000 ) >> 48 ). aByteArray at: (42 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF0000000000 ) >> 40 ). aByteArray at: (43 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00000000 ) >> 32 ). aByteArray at: (44 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF000000 ) >> 24 ). aByteArray at: (45 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF0000 ) >> 16 ). aByteArray at: (46 + anIndex) put: ( ( ( state at: 6 ) bitAnd: 16rFF00 ) >> 8 ). aByteArray at: (47 + anIndex) put: ( ( state at: 6 ) bitAnd: 16rFF ). ! ! !SHA384 methodsFor: 'digesting' stamp: 'msh 12/9/2005 04:17'! reinitialize bitCount := 0. 1 to: (byteBuffer size) do: [ :i | byteBuffer at: i put: 0 ]. byteCount := 0. 1 to: (savedState size) do: [ :i | savedState at: i put: 0 ]. state at: 1 put: 16rCBBB9D5DC1059ED8. state at: 2 put: 16r629A292A367CD507. state at: 3 put: 16r9159015A3070DD17. state at: 4 put: 16r152FECD8F70E5939. state at: 5 put: 16r67332667FFC00B31. state at: 6 put: 16r8EB44A8768581511. state at: 7 put: 16rDB0C2E0D64F98FA7. state at: 8 put: 16r47B5481DBEFA4FA4. 1 to: (wordBuffer size) do: [ :i | wordBuffer at: i put: 0 ].! ! !SHA384 methodsFor: 'private' stamp: 'msh 12/9/2005 04:16'! initialize bitCount := 0. byteBuffer := ByteArray new: 128. byteCount := 0. savedState := Array new: 8. state := Array new: 8. state at: 1 put: 16rCBBB9D5DC1059ED8. state at: 2 put: 16r629A292A367CD507. state at: 3 put: 16r9159015A3070DD17. state at: 4 put: 16r152FECD8F70E5939. state at: 5 put: 16r67332667FFC00B31. state at: 6 put: 16r8EB44A8768581511. state at: 7 put: 16rDB0C2E0D64F98FA7. state at: 8 put: 16r47B5481DBEFA4FA4. wordBuffer := Array new: 16. workBuffer := Array new: 80.! ! !SHA512 class methodsFor: 'class initialization' stamp: 'msh 12/9/2005 01:42'! initialize K512 _ #( 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 ).! ! !SymmetricStreamCipher methodsFor: 'output size' stamp: 'msh 5/11/2005 14:40'! outputSize: anIndex ^ anIndex .! ! !SymmetricStreamCipher methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:40'! decrypt: cleartext ^ self encrypt: cleartext .! ! !SymmetricStreamCipher methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:40'! decrypt: cleartext into: ciphertext self encrypt: cleartext into: ciphertext .! ! !SymmetricStreamCipher methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:41'! decrypt: cleartext into: ciphertext withOffset: anOffset self encrypt: cleartext into: ciphertext withOffset: anOffset.! ! !SymmetricStreamCipher methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:39'! encrypt: cleartext | rv | rv _ ByteArray new: ( self outputSize: ( cleartext size ) ). self encrypt: cleartext into: rv. ^ rv .! ! !SymmetricStreamCipher methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:38'! encrypt: cleartext into: ciphertext self encrypt: cleartext into: ciphertext withOffset: 0.! ! !SymmetricStreamCipher methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:38'! encrypt: cleartext into: ciphertext withOffset: anOffset | keystream | keystream _ self next: ( cleartext size ) . 1 to: ( keystream size ) do: [ :index | ciphertext at: ( index + anOffset ) put: ( ( cleartext at: index ) bitXor: ( keystream at: index ) ) . ]. 1 to: ( keystream size ) do: [ :index | keystream at: index put: 0. ]! ! !ARC4 methodsFor: 'sensitive data' stamp: 'msh 5/11/2005 14:42'! clearSensitiveData i _ 0. j _ 0. 1 to: 256 do: [ :index | sbox at: index put: 0. ].! ! !ARC4 methodsFor: 'encryption' stamp: 'msh 5/11/2005 15:09'! initialize: aKey | ell jay temp | i _ 0. j _ 0. sbox _ ByteArray new: 256. 1 to: 256 do: [ :index | sbox at: index put: ( index - 1 ). ]. ell _ aKey size. jay _ 0. 0 to: 255 do: [ :index | jay _ ( jay + ( sbox at: ( index + 1 ) ) + ( aKey at: ( ( index \\ ell ) + 1 ) ) ) \\ 256. temp _ sbox at: ( index + 1). sbox at: ( index + 1 ) put: ( sbox at: ( jay + 1 ) ). sbox at: ( jay + 1 ) put: temp. ]. temp _ 0. ell _ 0. jay _ 0. ! ! !ARC4 methodsFor: 'keystream' stamp: 'msh 5/11/2005 15:17'! next | rv temp | i _ ( i + 1 ) \\ 256. j _ ( j + ( sbox at: ( i + 1) ) ) \\ 256. temp _ sbox at: ( i + 1 ). sbox at: ( i + 1 ) put: ( sbox at: ( j + 1 ) ). sbox at: ( j + 1 ) put: temp . rv _ sbox at: ( ( ( sbox at: ( i + 1 ) ) + ( sbox at: ( j + 1 ) ) ) \\ 256 ). ^ rv .! ! !ARC4 methodsFor: 'keystream' stamp: 'msh 5/11/2005 15:20'! next: aCount | rv | rv _ ByteArray new: aCount. self next: aCount into: rv. ^ rv .! ! !ARC4 methodsFor: 'keystream' stamp: 'msh 5/11/2005 15:12'! next: aCount into: anArray 1 to: aCount do: [ :count | anArray at: count put: ( self next ). ].! ! !SymmetricStreamCipher class methodsFor: 'class initialization' stamp: 'msh 11/30/2005 23:19'! initialize "Initialize Subclasses" self subclasses do: [ :c | ( c class includesSelector: #initialize ) ifTrue: [ c perform: #initialize ] ]! ! SymmetricStreamCipher initialize! SHA512 initialize! !SHA512 class reorganize! ('class initialization' initialize) ('instance creation') ! SHA256 initialize! SHA1 initialize! MD5 initialize! MD2 initialize! MessageDigest initialize!