<?xml version="1.0"?>

<st-source>
<!-- 
Name: CiphersBase
Notice: Copyright © 2008 Cincom Systems, Inc.  All Rights Reserved.
Comment: This package defines basic APIs and implements generic components and extensions useful for various cipher implementations. Core abstract classes reflect common classification of basic cipher types symmetric ciphers, asymmetric ciphers, block ciphers, stream ciphers etc.

SymmetricCiphers are used for encryption. They are usually initialized with a "secret" sequence of bytes, called a key. An instance of SymmetricCipher can be either directly created using the #key: instance creation message, or an already existing instance can be initialized using the #setKey: message. Once initialized with a key, a cipher instance can serve any #encrypt*/#decrypt* requests.

There are two basic symmetric cipher categories defined by StreamCipher and BlockCipher hierarchies. StreamCiphers encrypt data byte by byte and provide fairly straightforward API. BlockCiphers encrypt data in blocks which results in slightly more complicated API involving different cipher modes and padding styles. The key abstract block cipher classes are BlockCipher, BlockCipherMode and BlockCipherPadding.

BlockCipher defines basic API of a block cipher (protocol 'services'). It expects an instance to be created, then intialized with the key using #setKey: method. Keys are usually arbitrary byte sequences of apropriate size. Once initialized with a key, a cipher instance can serve any #encrypt*/#decrypt* requests.

BlockCipherMode is a wrapper around a BlockCipher implementing an encryption mode. Subclasses are CipherBlockChaining(CBC), CipherFeedback(CFB), OutputFeedback(OFB), TripleEDE, TripleEDEInnerCBC and TripleEDEOuterCBC. Electronic Codebook Mode (ECB) is represented by a standalone BlockCipher instance so no mode wrapper is necessary. BlockCipherMode supports the same API as BlockCipher does so that they can be used interchangeably.

BlockCipherPadding is again a wrapper for either BlockCiphers or those BlockCipherModes that need padding (i.e ECB or any of the CBC modes). Concrete subclasses are BlockPadding that implements standard PKCS#5/RFC#1423 padding style (used by openssl) and CiphertextStealing that was taken from "Applied Cryptography" by Bruce Schneier. Look at the instance creation protocol of BlockCipher class to see various commonly used combinations of block ciphers, modes and paddings.

Asymmetric (public key ciphers) are gathered in the AsymmetricCipher hierarchy. Different ciphers have different capabilities. RSA is the most versatile cipher, supporting both encryption and signing. DSA is a signing only algorithm. DH (Diffie-Hellman) is a special algorithm which is only used for establishment of a shared secret value between two parties, it does't support neither encryption nor signing.

Asymmetric ciphers usually use a pair of keys, one for each of the complementary operations (encryption/decryption, signing/verification). The keys are usually also more complex and are therefore instantiated in the form of EncryptionKey objects. Valid keys have to be generated using special algorithms embedded in the KeyGenerator objects. Most of the key generation algorithms use prime numbers and therefore exploit various PrimalityTests apart from secure number generators.
DbIdentifier: bear73
DbTrace: 81595
DevelopmentPrerequisites: #(#(#package 'SecurityBase' '') #(#package 'SHA' '') #(#any 'DLLCC' ''))
PackageName: CiphersBase
Parcel: #('CiphersBase')
PrerequisiteParcels: #(#('SecurityBase' '') #('SHA' ''))
PrintStringCache: (751 0,mkobetic)
Version: 7.6
Date: 12:31:31 pm February 1, 2008
 -->
<time-stamp>From VisualWorks®, 7.6 of February 1, 2008 on February 1, 2008 at 12:31:31 pm</time-stamp>


<do-it>(Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned.  Choose terminate or close.']</do-it>

<class>
<name>DSSRandom</name>
<environment>Security</environment>
<super>Core.Random</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>q seedMask sha auxInput mutex </inst-vars>
<class-inst-vars>default seedWarning </class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.DSSRandom</class-id>
<body>This is an implementation of a secure pseudo-random number generator described in the Digital Signature Standard [DSS] from NIST (FIPS 186-2 with change notice 1 from October 5th, 2001, see http://csrc.nist.gov/encryption/tkrng.html). It is recommended by both DSS and the Diffie-Hellman Key Agreement RFC 2631. The algorithm is described in Appendix 3.1 of the DSS standard.

It generates pseudo-random large integers with specified upper bound q but no more than 320-bits long. The generator is seeded with a LargePositiveInteger or a ByteArray which is expected to be in the 160 to 512 bit range. The generator can employ auxiliary source of optional input, which is meant for optional user input. Any object returning positive integers in response to the #value message can be used for that.

While generators can be seeded automatically, it may not be an adequate seeding for specific security requirements. In these cases the generator has to be explicitly seeded with a trully random seed. The OS may be able to provide better seeding, for example some Unix systems provide access to an entropy gathering daemon via a special device file /dev/urandom:

	| file |
	file := '/dev/urandom' asFilename readStream binary.
	[	DSSRandom seed: (file next: 20)
	] ensure: [ file close ].

A common practice is to maintain a random seed file:

	| file |
	file := 'seed' asFilename readStream binary.
	[	DSSRandom seed: file contents
	] ensure: [ file close ]

A seed file can be created using an existing generator as follows.

	| file |
	file := 'seed' asFilename writeStream binary.
	[	file nextPutAll: (self default next changeClassTo: ByteArray)
	] ensure: [ file close ]

It is important that this is done before every image shut-down, otherwise the generator may get reverted to some previously saved state and repeat part of its sequence. Image startup/shutdown events can be used to manage the seed file. It's also good to update the seed file periodically, e.g. every 10 minutes, in case the image crashes. Note that the seed file should be kept secret and excluded from any backup mechanisms to make sure it's never reverted back to some previous value.

For heavy use of a generator it is also desirable to reseed it occassionally with a fresh truly random seed, if there's a danger that the period of the generator may get depleted

Instance Variables:
	q	&lt;LargePositiveInteger&gt; the upper bound, usually the parameter q in DSS or DH
	seedMask	&lt;LargePositiveInteger&gt; a mask reflecting the size of the secret seed
	sha	&lt;SHA&gt; a hash function instance
	auxInput	&lt;nil | Object | aBlock&gt; auxiliary provider of "optional user input", must understand #value
	mutex	&lt;Semaphore&gt; mutex for the core PRNG function to serialize concurrent use

Class Instance Variables:
	default	&lt;DSSRandom&gt; the default generator
	seedWarning	&lt;Boolean&gt; warn users about autogenerated seeding

</body>
</comment>

<class>
<name>SymmetricCipher</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.SymmetricCipher</class-id>
<body>This is the abstract superclass for all symmetric ciphers, defining the basic API that the ciphers are expected to support.

Subclasses must implement the following messages:
	initialization
		setKey:
	services
		decryptInPlace:from:to:
		encryptInPlace:from:to:

</body>
</comment>

<class>
<name>BlockCipher</name>
<environment>Security</environment>
<super>Security.SymmetricCipher</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>blockSize </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.BlockCipher</class-id>
<body>This is the abstract superclass for all block ciphers. It refines the basic cipher API for this type of ciphers. Also provides the basic instance creation templates for block ciphers in different modes using different padding styles.

Subclasses must implement:
	instance protocol:
		services
			decryptInPlace:at:
			encryptInPlace:at:
	class protocol:
		accessing
			blockSize

Instance Variables:
	blockSize	&lt;SmallInteger&gt;	caches the block size value for given block cipher

</body>
</comment>

<class>
<name>BlockCipherMode</name>
<environment>Security</environment>
<super>Security.BlockCipher</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cipher </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.BlockCipherMode</class-id>
<body>BlockCipherMode is a wrapper around a BlockCipher implementing an encryption mode. Subclasses are CipherBlockChaining(CBC), CipherFeedback(CFB), OutputFeedback(OFB), TripleEDE, TripleEDEInnerCBC and TripleEDEOuterCBC. Electronic Codebook Mode (ECB) is represented by a standalone BlockCipher instance so no mode wrapper is necessary. BlockCipherMode supports the same API as BlockCipher does so that they can be used interchangeably.

Instance Variables:
	cipher	&lt;BlockCipher&gt;	the cipher instance that is to be used in this mode.

</body>
</comment>

<class>
<name>OutputFeedback</name>
<environment>Security</environment>
<super>Security.BlockCipherMode</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>iv </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.OutputFeedback</class-id>
<body>This class implements Output Feedback Mode (OFB). The implemenation is based on "Applied Cryptography" by Bruce Schneier. Interesting features of this mode are that the ciphertext has the same size as the plaintext and the fault-tolerance properties. The mode requires an initialization vector, i.e. a block of data used to initialize the mode with.

Instance Variables:
	iv	&lt;ByteArray&gt;
</body>
</comment>

<class>
<name>PrimalityTest</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CiphersBase</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.PrimalityTest</class-id>
<body>This is an abstract superclass defining the common API of primality tests. The API is simple, primality tests are expected to understand message #value: which takes an integer as the argument and answers a Boolean indicating if the argument is a prime or not. Examples of implemented primality tests are PrimeSieve and MillerRabin.

Subclasses must implement the following messages:
	api
		value:

</body>
</comment>

<class>
<name>PrimeSieve</name>
<environment>Security</environment>
<super>Security.PrimalityTest</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>primes next </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CiphersBase</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.PrimeSieve</class-id>
<body>This is a preliminary prime sieve performing trial division by the primes up to a certain bound. The default set of primes is maintained in the Primes shared variable.
The sieve expects to be a part of a test "chain" and pass possible prime candidates further to the "next" test in the chain. The chain is formed by creating the sieve instance #on: the next test in the chain.

Instance Variables:
	primes	&lt;Array of: Integer&gt; the primes to sieve with
	next	&lt;PrimalityTest&gt; next test in the chain

</body>
</comment>

<class>
<name>KeyGenerator</name>
<environment>Security</environment>
<super>Core.EventManager</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>keySize random primalityTest </inst-vars>
<class-inst-vars>random </class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.KeyGenerator</class-id>
<body>This is an abstract superclass for generators of EncryptionKeys. It defines the basic APIs and common components of a generator. Generators create keys of specified bit-length. The keys are usually derived from very large random primes, that's what the random and primalityTest components are used for.

A generator is created using one of the variants of the #keySize:random:primalityTest: message. Make sure you understand the requirements that the message parameters must satisfy. Different ciphers have different requirements and the parameters directly affect the level of security of the generated keys. The keys are obtained with messages #privateKey and #publicKey sent  to a generator. The generator caches the keys, so subsequent messages will return the same key. To force the generator to regenerate new keys it has to be cleared using the #flush message.

Subclasses must implement:
	instance protocol:
		flush
		publicKey
		privateKey

Instance Variables:
	keySize	&lt;SmallInteger&gt; the desired bit-length of the generated keys
	random	&lt;Random&gt; a random seed generator producing large intergers
	primalityTest	&lt;PrimalityTest&gt; a probabilistic primality test, with very low error probability

Class Instance Variables:
	random	&lt;Random&gt; the default random generator

</body>
</comment>

<class>
<name>EuclidAlgorithm</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>a b u v gcd </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.EuclidAlgorithm</class-id>
<body>Euclid Algorithm is used to compute the greatest commond divisor (GCD) of two integers. For more details consult Knuth volume 2.

The Modular inverse problem is difficult to solve sometimes there is a solution and sometimes not. In general a**-1 = x (mod n) has a unique solution  is a and n are relatively prime. if a and n are not relatively prime, then the equation has no solution. If n is prime then every number 1 to n-1 is relatively prime to n and has exactly one inverse to the modulo n in that range.

This class also implements extended Euclid algorithm, solving as + bt = gcd(a,b). For any two integers a and b, there are numbers s and t such that as + bt = gcd(a,b). In other words, gcd(a,b) is a linear combination of a and b. gcd(a,b) is the least positive combination of the two integers. a and b themselves are expressed as trivial combinations: a = 1·a + 0·b and b = 0·a + 1·b. Starting with these two, an extension of Euclid's algorithm finds s and t whose existence was so far only established in a formal way. 

Write the two linear combinations in a column and apply one step of Euclid's algorithm to the left-hand side. Assuming a = bp + r. Multiply the second equation by p and subtract it from the first equation:

a = 1·a + 0·b
b = 0·a + 1·b
r = 1·a + (-p)·b

Apply the same procedure to the last two equations. Continue in this manner until Euclid's algorithm on the left stops. On the right, there will be the linear combination we are after. Let check this with an example: let a = 2322, b = 654. I adopt the usual convention of solving linear equations and omit all the terms in a linear combination but the left-hand side and the two coefficients on the right. The results are placed into a table with the fourth column being equal to p (from a = bp + r, which changes on each step. Multiply three numbers to the left of p by p and subtract them from the numbers directly above them. Record the results on the next line.)

left side  *a   *b   p  
2322 1 0  
654 0 1 3 
360 1 -3 1 
294 -1 4 1 
66 2 -7 4 
30 -9 32 2 
6 20 -71 5 
0    

Therefore, 20·2322 - 71·654 = 6. Note that 20 and 71 are coprime. This is the case for any s ant t such that as + bt = gcd(a,b) because, otherwise, we would be able to divide the whole equation by their common factor. The right side, gcd(a,b), would also be divided by that number which would give a positive linear combination of a and b smaller than gcd(a,b). But we know that this is impossible. Division by gcd(a,b), in our case, leads to 20·387 - 71·109 = 1. Wherefrom, 71/387 and 20/109 are consecutive fractions in the Farey series of order 387.

The algorithm, as described above, is a real extension of Euclid's algorithm in the sense that without removing any of the operations needed for the latter it only adds 2 multiplications and 2 subtractions on every step. Furthermore, these operations in no way affect the progress of Euclid's algorithm proper. Which proves that the extended algorithm terminates together with the common algorithm.

Indeed, assume the extended algorithm has furnished s,t, and g such that as + bt = g. We can easily check whether or not g|a and g|b. Unless there was an error, this would imply g|gcd(a,b). Moreover, once g is expressed as a linear combination of a and b we know that gcd(a,b)|g. Therefore, indeed g = gcd(a,b). It thus appears that by finding s and t the algorithm actually proves its own correctness.

References
A.Engel, Exploring Mathematics with Your Computer, MAA, 1993 
H.Davenport, The Higher Arithmetic, Harper&amp;Brothers, NY 
R.Graham, D.Knuth, O.Potashnik, Concrete Mathematics, 2nd edition, Addison-Wesley, 1994. 
D.Knuth, The Art of Computer Programming, v1,2. 
 
Instances are extended Euclid algorithms. Given a, b two integers, they compute the GCD of them and another two integers, s, t, such that: (a gcd: b) = (s * a) + (t * b).

Instance Variables:
	a	&lt;Integer&gt; input
	b	&lt;Integer&gt; input
	u	&lt;Integer&gt; quotient
	v	&lt;Integer&gt; quotient
	gcd	&lt;Integer&gt; result
</body>
</comment>

<class>
<name>BlockCipherPadding</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>blockSize cipher </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.BlockCipherPadding</class-id>
<body>BlockCipherPadding is again a wrapper for either BlockCiphers or those BlockCipherModes that need padding (i.e ECB or any of the CBC modes). Concrete subclasses are BlockPadding that implements standard PKCS#5/RFC#1423 padding style (used by openssl) and CiphertextStealing that was taken from "Applied Cryptography" by Bruce Schneier.

Subclasses must implement the following messages:
	services
		decrypt:
		decryptInPlace:
		decryptInPlace:from:to:
		encrypt:
		encryptInPlace:
		encryptInPlace:from:to:

Instance Variables:
	blockSize	&lt;SmallInteger&gt;	caches the value of the cipher block size
	cipher	&lt;BlockCipher&gt;	the cipher/cipher mode to be used with this padding

</body>
</comment>

<class>
<name>ECBCiphertextStealing</name>
<environment>Security</environment>
<super>Security.BlockCipherPadding</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>block </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.ECBCiphertextStealing</class-id>
<body>This padding style was taken from "Applied Cryptography" by Bruce Schneier. The neat feature of this one is that it doesn't require extra room for the cipher text, i.e. the cipher text is the same length as the plain text regardless of the block cipher used. Note that this particular class can be used only for ECB mode. Different modes require slightly different implementation of this padding style.

Instance Variables:
	block	&lt;ByteArray&gt;

</body>
</comment>

<class>
<name>CBCCiphertextStealing</name>
<environment>Security</environment>
<super>Security.ECBCiphertextStealing</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>ivCopy </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.CBCCiphertextStealing</class-id>
<body>This padding style was taken from "Applied Cryptography" by Bruce Schneier. The neat feature of this one is that it doesn't require extra room for the cipher text, i.e. the ciphertext is the same length as the plaintext regardless of the block cipher used. Note that this particular class can be used only for CBC mode, because different modes require slightly different implementation of this padding style.

Instance Variables:
	ivCopy	&lt;ByteArray&gt;
</body>
</comment>

<class>
<name>MillerRabin</name>
<environment>Security</environment>
<super>Security.PrimalityTest</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>t random </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CiphersBase</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.MillerRabin</class-id>
<body>This PrimalityTest implements the Miller-Rabin algorithm as described in Handbook Of Applied Cryptography, section 4.24. Note that this is a probabilistic primality test which exploits a random number generator. The probability of a false prime slipping through is less then (1/4)^t, where t is a configurable parameter of the algorithm. Usual value for t is 50.

Instance Variables:
	t	&lt;Integer&gt; the security parameter; probability of a false prime is less then (1/4)^t; t &gt; 0
	random	&lt;Random&gt; must generate positive integers up to the largest integer to be tested for primality

Shared Class Variables:
	DefaultT	&lt;Object&gt; default security parameter

</body>
</comment>

<class>
<name>EncryptionKey</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.EncryptionKey</class-id>
<body>Abstract superclass for encryption keys that are more complex than just a large integer or a byte array.

</body>
</comment>

<class>
<name>TripleEDE</name>
<environment>Security</environment>
<super>Security.BlockCipherMode</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cipher2 cipher3 </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.TripleEDE</class-id>
<body>This class implements the 3-key triple EDE encryption mode. EDE stands for encrypt-decrypt-encrypt, i.e. the plain text block is first encrypted with the first key, then decrypted with the second key and finally encrypted with the third key. This mode is a type of ECB mode, i.e. no feedback or chaining between the blocks of data is involved. This has some fairly severe security implications, therefore it is usually better to use one of the CBC subclasses. This mode has to be initialized with 3 equal size blocks of key data (which have to satisfy the requirements of the 3 sub-ciphers). Note that using the same first and third key effectively turns the mode into a 2-key tripple EDE.

Instance Variables:
	cipher2	&lt;BlockCipher&gt;	an instance of cipher to be used for the second "decrypt" step
	cipher3	&lt;BlockCipher&gt;	an instance of cipher to be used for the third "encrypt" step

</body>
</comment>

<class>
<name>TripleEDEInnerCBC</name>
<environment>Security</environment>
<super>Security.TripleEDE</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.TripleEDEInnerCBC</class-id>
<body>This class implements the 3-key triple EDE encryption mode with "inner" block chaining. Inner means that each of the 3 sub-ciphers run in their own CBC mode. However this inner mode is aparently only slightly stronger than single encryption against certain types of attack, therefore it is usually better to use the "outer" mode instead.
This mode has to be initialized with an "initialization vector", i.e. 3 blocks of data used to intialize the 3 sub-ciphers. This implementation follows the description in "Applied Cryptography" by Bruce Schneier.</body>
</comment>

<class>
<name>TripleEDEOuterCBC</name>
<environment>Security</environment>
<super>Security.TripleEDEInnerCBC</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>iv ivBackup block </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.TripleEDEOuterCBC</class-id>
<body>This class implements the 3-key triple EDE encryption mode with "outer" block chaining. Outer means that the output of the third sub-cipher is combined with the input of the next round of encryption. This is usually the mode used for the triple CBC ciphers as is for example the 3DES_EDE_CBC of SSL. This mode has to be initialized with an "initialization vector", i.e. one block of data used to intialize the first sub-cipher. This implementation follows the description in "Applied Cryptography" by Bruce Schneier.

Instance Variables:
	iv	&lt;ByteArray&gt;
	ivBackup	&lt;ByteArray&gt;
	block	&lt;ByteArray&gt;

</body>
</comment>

<class>
<name>CipherBlockChaining</name>
<environment>Security</environment>
<super>Security.BlockCipherMode</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>iv ivBackup </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.CipherBlockChaining</class-id>
<body>This class implements Cipher Block Chaining Mode (CBC). The implemenation is based on "Applied Cryptography" by Bruce Schneier. This is probably the most commonly used encryption mode for its increased security compared to plain ECB mode. The mode requires an initialization vector, i.e. a block of data used to initialize the mode with.

Instance Variables:
	iv	&lt;ByteArray&gt;
	ivBackup	&lt;ByteArray&gt;
</body>
</comment>

<class>
<name>CrpRandom</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>q xkey bitLength </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.CrpRandom</class-id>
<body>DEPRECATED! Use DSSRandom instead.
A cryptographical-grade random number generator as described in FIPS

PUB 186-1 ("Digital Signature Standard (DSS)").

Instance Variables:
	q	&lt;Integer&gt; The value of Q from the DSA (see the standard).
	xkey	&lt;Integer&gt; The running random value initially set to the
	bitLength	&lt;Integer&gt; Bit length of the keys to generate

</body>
</comment>

<class>
<name>AsymmetricCipher</name>
<environment>Security</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.AsymmetricCipher</class-id>
<body>This is an abstract superclass for all asymmetric (public key) ciphers, defining the basic API that the ciphers are expected to conform to. Four basic public key operations are encryption, decryption, signing and verification.

Public key encryption is usually utilized in the following way. The party wishing to send encrypted message to another party first obtains the recipient's public key. Public key doesn't need to be kept secret so it's generally easier to distribute such key than it is with keys that have to remain secret, although there are still many serious threats to consider, for example key forgery. The sender then encrypts the message using the recipients public key. An encrypted message can only be decrypted using the corresponding private key, which is supposedly only known to the recipient.
Note that the size of the message is usually severely limited by the size of the keys, the bit size of the message usually cannot exceed the bit size of the keys. This limitation is similar to the block size of block ciphers and could possibly be dealt with similarly, however public key encryption is also several orders of magnitude slower than symmetric encryption. Therefore the most common use of public key encryption is to encrypt a secret key for symmetric encryption and then data of unlimited size is encrypted using the symmetric encryption.

Encryption is performed using the #encrypt: message sent to an instance of algorithm initialized with a public key.

	encryptedBytes :=
		RSA new
			publicKey: anRSAPublicKey;
			encrypt: plainBytes
			
Decryption is preformed using the #decrypt: message sent to an instance of algorithm initialized with a corresponding private key.

	plainMessageBytes :=
		RSA new
			privateKey: anRSAPrivateKey;
			decrypt: encryptedMessageBytes

Public key signing takes a message and signer's private key and generates a "signature" object. Authenticity of a signature can be verified using singer's public key and the original message. The public key algorithm ensures that it is impractical to forge a valid signature (one that passes the verification test) without having the private key. Assuming that only the signer has access to the private key, one can assume that the message was indeed signed by the signer.
To sign some data one has to initialize an instance of the algorithm with a private key, then use #sign: to generate the signature.

	aDSASignature :=
		DSA new
			privateKey: aDSAPrivateKey;
			sign: byteData

Signatures are verified by sending message #verify:of: to an instance of the algorithm initialized with the singer's public key.

	isAuthenticBoolean :=
		DSA new
			publicKey: aDSAPublicKey;
			verify: aDSASignature of: byteData

Subclasses must implement the following messages, if given capability is supported:
	accessing
		publicKey
		publicKey:
		privateKey
		privateKey:
	services (encryption)
		encrypt:
		decrypt:
	services (signing)
		sign:
		verify:of:
</body>
</comment>

<class>
<name>StreamCipher</name>
<environment>Security</environment>
<super>Security.SymmetricCipher</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.StreamCipher</class-id>
<body>This is the abstract superclass for stream ciphers. StreamCiphers encrypt/decrypt data byte by byte.

Subclasses must implement the following messages:
	services
		decryptByte:
		encryptByte:

</body>
</comment>

<class>
<name>BlockPadding</name>
<environment>Security</environment>
<super>Security.BlockCipherPadding</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.BlockPadding</class-id>
<body>This is what's allegedly sometimes called the "standard block padding". It is defined in PKCS#5 and RFC#1423.
It simply adds anywhere from 1 to blockSize bytes of padding, filling it with the actual padding length.</body>
</comment>

<class>
<name>AutogeneratedSeeding</name>
<environment>Security</environment>
<super>Core.Warning</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CiphersBase</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.AutogeneratedSeeding</class-id>
<body>This warning is to alert the users that a random generator they are about to use will be seeded from an autogenerated seed. The generation process may not be able to provide suitable amount of randomness to satisfy the security requirements of their application. If that is a concern the generator should be seeded explicitly with required amount of trully random bytes using the #seed: message. More information about proper seeding of the generator can be found in the comments on the generator class (e.g. DSSRandom).

</body>
</comment>

<class>
<name>CipherFeedback</name>
<environment>Security</environment>
<super>Security.BlockCipherMode</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>iv </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Security-Ciphers</category>
<attributes>
<package>CiphersBase</package>
</attributes>
</class>

<comment>
<class-id>Security.CipherFeedback</class-id>
<body>This class implements Cipher Feedback Mode (CFB). The implemenation is based on "Applied Cryptography" by Bruce Schneier. Interesting features of this mode are that the ciphertext has the same size as the plaintext and the fault-tolerance properties. The mode requires an initialization vector, i.e. a block of data used to initialize the mode with.

Instance Variables:
	iv	&lt;ByteArray&gt;

</body>
</comment>

<shared-variable>
<name>Primes</name>
<environment>Security.PrimeSieve</environment>
<private>false</private>
<constant>false</constant>
<category>constants</category>
<initializer>PrimeSieve primesUpTo: 100</initializer>
<attributes>
<package>CiphersBase</package>
</attributes>
</shared-variable>

<shared-variable>
<name>DefaultT</name>
<environment>Security.MillerRabin</environment>
<private>false</private>
<constant>false</constant>
<category>defaults</category>
<initializer>50</initializer>
<attributes>
<package>CiphersBase</package>
</attributes>
</shared-variable>

<methods>
<class-id>Security.DSSRandom</class-id> <category>accessing</category>

<body package="CiphersBase" selector="auxInput">auxInput

	^auxInput</body>

<body package="CiphersBase" selector="auxInput:">auxInput: aBlock
"	auxInput	&lt;nil | Object | Block&gt; auxiliary provider of 'optional user input'; must produce a nil or an integer in the 0 to seedMask range when sent #value"

	auxInput := aBlock</body>

<body package="CiphersBase" selector="next">next
"Provides next random integer between 0 and q.
If q is nil the integer will be about 320 bits long (twice the size of SHA-1 digest)."

	^mutex critical: [
		(q notNil and: [ q basicSize &gt; self blockSize ]) 
			ifTrue: [ self privateNextExtended ]
			ifFalse: [ self privateNext ] ]</body>

<body package="CiphersBase" selector="q">q

	^q</body>

<body package="CiphersBase" selector="q:">q: aLargePrime

	q := aLargePrime</body>

<body package="CiphersBase" selector="sha">sha

	^sha ifNil: [ sha := SHA new ]</body>
</methods>

<methods>
<class-id>Security.DSSRandom</class-id> <category>initialization</category>

<body package="CiphersBase" selector="b:">b: seedBitSize
"	seedBitSize	&lt;SmallInteger&gt;	the bit-size of the secret seed, should be between 160 and 512 (DSS, Appendix 3.1)"

	self seed: (self autogeneratedSeed: seedBitSize).</body>

<body package="CiphersBase" selector="initializeMutex">initializeMutex

	mutex := Semaphore forMutualExclusion</body>

<body package="CiphersBase" selector="q:b:">q: upperBound b: seedBitSize
"	upperBound	&lt;LargePositiveInteger&gt; the upper bound, usually the parameter q in DSS or DH
	seedBitSize	&lt;SmallInteger&gt;	the bit-size of the secret seed, should be between 160 and 512 (DSS, Appendix 3.1)"

	q := upperBound.
	self b: seedBitSize</body>

<body package="CiphersBase" selector="q:seed:">q: upperBound seed: seeding
"	upperBound	&lt;LargePositiveInteger&gt; the upper bound, usually the parameter q in DSS or DH
	seeding	&lt;LargePositiveInteger | ByteArray&gt; the secret-seed, should be between 160 and 512 bits long (DSS, Appendix 3.1)"

	q := upperBound.
	self seed: seeding</body>

<body package="CiphersBase" selector="seed:">seed: seeding
"	seeding	&lt;LargePositiveInteger | ByteArray&gt; the secret-seed, should be between 160 and 512 bits long (DSS, Appendix 3.1)"

	seed := seeding isInteger
			ifTrue: [ seeding ]
			ifFalse: [ seeding changeClassTo: LargePositiveInteger ].	
	seed highBit &lt; 153 ifTrue: [
		self error: (#SeedLessThan160Bits &lt;&lt; #security &gt;&gt; 'The seed must be at least 160 bits long!') ].
	seedMask := (2 raisedTo: seed digitLength * 8) - 1.
	self initializeMutex</body>
</methods>

<methods>
<class-id>Security.DSSRandom</class-id> <category>private</category>

<body package="CiphersBase" selector="autogeneratedSeed:">autogeneratedSeed: seedBitSize

	| s size |
	s := self class autogeneratedSeed.
	s := self sha hash: s.
	[ (size := s size * 8) &lt; seedBitSize ] whileTrue: [
		s := s, (self sha hash: s) ].
	"make sure the top bit is set"
	s at: s size put: (s last bitOr: 16r80). 
	s changeClassTo: LargePositiveInteger.
	s := s bitShift: (seedBitSize - size).
	^s</body>

<body package="CiphersBase" selector="blockSize">blockSize

	^self sha digestSize * 2</body>

<body package="CiphersBase" selector="privateNext">privateNext
"Provides next random integer between 0 and q. Implements the algorithm defined in Appending 3.1 in DSS. The G function is constructed from SHA-1, see Apending 3.3 in DSS"

	| x xval w0 w1 |
	"XKEY is seed. XSEED is auxInput
	XVAL = (XKEY + XSEED) mod 2^b"
	xval := auxInput value
			ifNil: [ seed copy ]
			ifNotNil: [ :xseed | (seed + xseed) bitAnd: seedMask ].
	"w0 = G(t, XVAL)"
	xval changeClassTo: ByteArray.
	w0 := self sha hash: xval.
	"XKEY = ( 1 + XKEY + w0) mod 2^b"
	x := w0 copy.
	x changeClassTo: LargePositiveInteger.
	seed := (1 + seed + x) bitAnd: seedMask.
	"XVAL = (XKEY + XSEED) mod 2^b"
	xval := auxInput value
			ifNil: [ seed copy ]
			ifNotNil: [ :xseed | (seed + xseed) bitAnd: seedMask ].
	"w1 = G(t, XVAL)"
	xval changeClassTo: ByteArray.
	w1 := self sha hash: xval.
	"XKEY = ( 1 + XKEY + w0) mod 2^b"
	x := w1 copy.
	x changeClassTo: LargePositiveInteger.
	seed := (1 + seed + x) bitAnd: seedMask.
	
	"x = (w0 || w1) mod q"
	x := w0, w1.
	x changeClassTo: LargePositiveInteger.
	q ifNotNil: [ x := x \\ q ].
	^x</body>

<body package="CiphersBase" selector="privateNextExtended">privateNextExtended
"This is to allow upper bounds beyond the 320-bit limit."

	| target next |
	target := q basicSize.
	next := self privateNext.
	[	next basicSize &lt; target
	] whileTrue: [
		next := (next bitShift: self blockSize) bitOr: self privateNext ].
	^next \\ q</body>
</methods>

<methods>
<class-id>Security.DSSRandom class</class-id> <category>default generator</category>

<body package="CiphersBase" selector="default">default

	^default ifNil: [ self resetDefault ].</body>

<body package="CiphersBase" selector="flushDefault">flushDefault

	^default ifNotNil: [ default := nil ].</body>

<body package="CiphersBase" selector="resetDefault">resetDefault
"Reset the default random instance.
	^DSSRandom

	self resetDefault

Note that the seeding method used here expects that the image was up for a while and has been used heavily in an unpredictable manner in order to get the object memory parameters drift away from the initial startup state. It is highly recommended that you use a more reliable, external seeding instead (see #resetDefaultFrom:)."

	^default := self new</body>

<body package="CiphersBase" selector="resetDefaultFrom:">resetDefaultFrom: aByteStream
"Reset the default random instance.
	aByteStream &lt;ReadStream&gt; stream containing the random seed bits, at least 160 bits
	^DSSRandom

Resetting the default random from an external entropy gathering daemon (Unix)
	
	| file |
	file := '/dev/urandom' asFilename readStream binary.
	[	self resetDefaultFrom: (file next: 20) readStream
	] ensure: [ file close ]

Resetting the default random from a seed file

	| file |
	file := 'seed' asFilename readStream binary.
	[	self resetDefaultFrom: file
	] ensure: [ file close ]

A seed file can be created as follows.

	'seed' asFilename writeStream	binary; nextPutAll: (self default next changeClassTo: ByteArray); close

It is important that this is done before every image shut-down, otherwise the generator may get reverted to some previous state and repeat part of its sequence. Image startup/shutdown events can be used to manage the seed file. It's also good to update the seed file periodically, e.g. every 10 minutes, in case the image crashes. Note that the seed file should be kept secret and excluded from any backup mechanisms to make sure it's never reverted back to some previous value.

For heavy use of the generator it is also desirable to reseed it occassionally with a fresh seed, if there's a danger that the period of the generator may get depleted."

	| seed |
	seed := aByteStream nextAvailable: 64. "Don't read more than 512 bits"
	seed size &lt; 20 ifTrue: [
		self error: (#SeedLessThan160Bits &lt;&lt; #security &gt;&gt; 'The seed must be at least 160 bits long!') ].
	^default := self seed: seed</body>
</methods>

<methods>
<class-id>Security.DSSRandom class</class-id> <category>utilities</category>

<body package="CiphersBase" selector="autogeneratedSeed">autogeneratedSeed

	^[ self osGeneratedSeed
	] on: Error do: [ :ex |
		self seedWarning ifTrue: [ AutogeneratedSeeding raiseSignal ].
		self systemStateSeed ]</body>

<body package="CiphersBase" selector="osGeneratedSeed">osGeneratedSeed
"Attempts to obtain 160 random bits from the OS"
	(OSHandle currentOS = #unix) ifTrue: [ ^self unixGeneratedSeed ].
	(OSHandle currentOS = #win32) ifTrue: [ ^self win32GeneratedSeed ].
	self osRandomNotAccessible</body>

<body package="CiphersBase" selector="osRandomNotAccessible">osRandomNotAccessible

	self error: (#OSRandomNotAccessible &lt;&lt; #security &gt;&gt; 'OS random generation facilities are not accessible!')</body>

<body package="CiphersBase" selector="systemStateSeed">systemStateSeed
"Returns a 160 bit seed compiled from the sub-second part of microsecond clock and some more volatile paramaters of ObjectMemory"

	| om |
	om := ObjectMemory current.
	^(OrderedCollection new
		add: (Time microsecondClock bitAnd: 16rFFFF);
		add: ((om edenUsedBytes bitShift: -2) bitAnd: 16rFFFF);
		add: ((om survUsedBytes bitShift: -2) bitAnd: 16rFFFF);
		add: ((om threadedDataBytes bitShift: -2) bitAnd: 16rFFFF);
		add: ((om allocProbes bitShift: -2) bitAnd: 16rFFFF);
		add: ((om availableFreeBytes bitShift: -2) bitAnd: 16rFFFF);
		add: (om oopsLeft bitAnd: 16rFFFF);
		add: ((om incMarkedBytes bitShift: -2) bitAnd: 16rFFFF);
		add: ((om incNilledBytes bitShift: -2) bitAnd: 16rFFFF);
		add: (om incReclaimedBytes bitAnd: 16rFFFF);
		yourself
	)	inject: ByteArray new 
		into: [ :total :next |
			total, (ByteArray
					with: (next bitAnd: 255)
					with: ((next bitShift: -8) bitAnd: 255)) ]</body>

<body package="CiphersBase" selector="unixGeneratedSeed">unixGeneratedSeed

	| random |
	random := '/dev/urandom' asFilename.
	random exists ifFalse: [ self osRandomNotAccessible ].
	random := random readStream binary.
	^[	random next: 20
	] ensure: [ random close ]</body>

<body package="CiphersBase" selector="win32GeneratedSeed">win32GeneratedSeed

	| xif provider |
	xif := Win32SystemSupport new.
	provider := xif CryptAcquireNormalContext.
	^[	xif CryptGenRandomProvider: provider len: 20.
	] ensure: [ 
		xif CryptReleaseContext: provider.
		xif CryptDeleteNormalContext ].</body>
</methods>

<methods>
<class-id>Security.DSSRandom class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="b:">b: seedBitSize
"	seedBitSize	&lt;SmallInteger&gt;	the bit-size of the secret seed, should be between 160 and 512 (DSS, Appendix 3.1)"

	^self basicNew b: seedBitSize</body>

<body package="CiphersBase" selector="new">new

	^self b: 160</body>

<body package="CiphersBase" selector="q:b:">q: upperBound b: seedBitSize
"	upperBound	&lt;LargePositiveInteger&gt; the upper bound, usually the parameter q in DSS or DH
	seedBitSize	&lt;SmallInteger&gt;	the bit-size of the secret seed, should be between 160 and 512 (DSS, Appendix 3.1)"

	^self basicNew q: upperBound b: seedBitSize</body>

<body package="CiphersBase" selector="q:seed:">q: upperBound seed: seed
"	upperBound	&lt;LargePositiveInteger&gt; the upper bound, usually the parameter q in DSS or DH
	seed	&lt;LargePositiveInteger | ByteArray&gt; the secret-seed, should be between 160 and 512 bits long (DSS, Appendix 3.1)"

	^self basicNew q: upperBound seed: seed</body>

<body package="CiphersBase" selector="seed:">seed: seed
"	seed	&lt;LargePositiveInteger | ByteArray&gt; the secret-seed, should be between 160 and 512 bits long (DSS, Appendix 3.1)"

	^self basicNew seed: seed</body>
</methods>

<methods>
<class-id>Security.DSSRandom class</class-id> <category>accessing</category>

<body package="CiphersBase" selector="seedWarning">seedWarning

	^seedWarning ifNil: [ self seedWarningDefault ]</body>

<body package="CiphersBase" selector="seedWarning:">seedWarning: warn
"
	warn &lt;Boolean&gt; warn users about autogenerated seeding
"
	seedWarning := warn</body>

<body package="CiphersBase" selector="seedWarningDefault">seedWarningDefault
	
	^true	"warn by default"</body>
</methods>

<methods>
<class-id>Security.SymmetricCipher</class-id> <category>services</category>

<body package="CiphersBase" selector="decrypt:">decrypt: aByteArray
"Return a new ByteArray with decrypted contents of &lt;aByteArray&gt;."

	| copy |
	copy := aByteArray copy.
	self decryptInPlace: copy.
	^copy</body>

<body package="CiphersBase" selector="decryptInPlace:">decryptInPlace: aByteArray
"Decrypt the contents of &lt;aByteArray&gt; in place.
Return the index of the last data byte"

	^self decryptInPlace: aByteArray from: 1 to: aByteArray size</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
Return the index of the last data byte"

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encrypt:">encrypt: aByteArray
"Return a new ByteArray with encrypted contents of &lt;aByteArray&gt;."

	| copy |
	copy := aByteArray copy.
	self encryptInPlace: copy.
	^copy</body>

<body package="CiphersBase" selector="encryptInPlace:">encryptInPlace: aByteArray
"Encrypt the contents of &lt;aByteArray&gt; in place.
Return the index of the last cipher byte"

	^self encryptInPlace: aByteArray from: 1 to: aByteArray size</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
Return the index of the last cipher byte"

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.SymmetricCipher</class-id> <category>initialization</category>

<body package="CiphersBase" selector="setKey:">setKey: aByteArray
"Initialize the cipher with the given key. Note that different encryption algorithms have different requirements for the key."

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.SymmetricCipher class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="key:">key: aByteArray

	^self new setKey: aByteArray; yourself</body>
</methods>

<methods>
<class-id>Security.BlockCipher</class-id> <category>accessing</category>

<body package="CiphersBase" selector="blockSize">blockSize

	^blockSize</body>
</methods>

<methods>
<class-id>Security.BlockCipher</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:at:">decryptInPlace: aByteArray at: start
"Decrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) is expected to be a multiple of the cipher block size.
Return the index of the last data byte"

	start to: end by: blockSize do: [ :p |
		self decryptInPlace: aByteArray at: p ].
	^end</body>

<body package="CiphersBase" selector="encryptInPlace:at:">encryptInPlace: aByteArray at: start
"Encrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) is expected to be a multiple of the cipher block size.
Return the index of the last cipher byte"

	start to: end by: blockSize do: [ :p |
		self encryptInPlace: aByteArray at: p ].
	^end</body>
</methods>

<methods>
<class-id>Security.BlockCipher</class-id> <category>initialization</category>

<body package="CiphersBase" selector="initialize">initialize

	blockSize := self class blockSize</body>
</methods>

<methods>
<class-id>Security.BlockCipher class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="new">new

	^super new initialize</body>

<body package="CiphersBase" selector="new3EDE_CBC">new3EDE_CBC
"Create an instance in 3EDE_CBC mode with no padding"

	^TripleEDEOuterCBC
		first: self new
		second: self new
		third: self new</body>

<body package="CiphersBase" selector="newBP_3EDE_CBC">newBP_3EDE_CBC
"Create an instance in 3EDE_CBC mode with block padding"

	^BlockPadding on: self new3EDE_CBC</body>

<body package="CiphersBase" selector="newBP_CBC">newBP_CBC
"Create an instance in CBC mode with block padding"

	^BlockPadding on: self newCBC</body>

<body package="CiphersBase" selector="newBP_ECB">newBP_ECB
"Create an instance in ECB mode with block padding"

	^BlockPadding on: self newECB</body>

<body package="CiphersBase" selector="newCBC">newCBC
"Create an instance in CBC mode with no padding"

	^CipherBlockChaining on: self new</body>

<body package="CiphersBase" selector="newCFB">newCFB
"Create an instance in CFB mode with no padding"

	^CipherFeedback on: self new</body>

<body package="CiphersBase" selector="newCS_3EDE_CBC">newCS_3EDE_CBC
"Create an instance in 3EDE_CBC mode with ciphertext stealing"

	^CBCCiphertextStealing on: self new3EDE_CBC</body>

<body package="CiphersBase" selector="newCS_CBC">newCS_CBC
"Create an instance in CBC mode with ciphertext stealing"

	^CBCCiphertextStealing on: self newCBC</body>

<body package="CiphersBase" selector="newCS_ECB">newCS_ECB
"Create an instance in ECB mode with ciphertext stealing"

	^ECBCiphertextStealing on: self newECB</body>

<body package="CiphersBase" selector="newECB">newECB
"Create an instance in ECB mode with no padding"

	^self new</body>

<body package="CiphersBase" selector="newOFB">newOFB
"Create an instance in OFB mode with no padding"

	^OutputFeedback on: self new</body>
</methods>

<methods>
<class-id>Security.BlockCipher class</class-id> <category>accessing</category>

<body package="CiphersBase" selector="blockSize">blockSize

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.BlockCipherMode</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:at:">decryptInPlace: aByteArray at: start
"Decrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	self decryptInPlace: aByteArray from: start to: start + blockSize - 1</body>

<body package="CiphersBase" selector="encryptInPlace:at:">encryptInPlace: aByteArray at: start
"Encrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."
	
	self encryptInPlace: aByteArray from: start to: start + blockSize - 1</body>
</methods>

<methods>
<class-id>Security.BlockCipherMode</class-id> <category>initialization</category>

<body package="CiphersBase" selector="initialize">initialize</body>

<body package="CiphersBase" selector="on:">on: aCipher

	cipher := aCipher.
	blockSize := aCipher blockSize</body>
</methods>

<methods>
<class-id>Security.BlockCipherMode</class-id> <category>accessing</category>

<body package="CiphersBase" selector="blockSize">blockSize

	^blockSize</body>

<body package="CiphersBase" selector="setKey:">setKey: aByteArray

	cipher setKey: aByteArray</body>
</methods>

<methods>
<class-id>Security.BlockCipherMode class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="key:">key: aByteArray

	"A mode can only be created on a cipher. Use #on: to create instances of block cipher mode."
	^self shouldNotImplement</body>

<body package="CiphersBase" selector="on:">on: aCipher

	^self new on: aCipher</body>
</methods>

<methods>
<class-id>Security.BlockCipherMode class</class-id> <category>accessing</category>

<body package="CiphersBase" selector="blockSize">blockSize
"Modes delegate blockSize to the underlying cipher."
	^self shouldNotImplement</body>
</methods>

<methods>
<class-id>Security.OutputFeedback</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt in place the contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) does not have to be a multiple of the encryption block size."

	self encryptInPlace: aByteArray from: start to: end</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt in place the contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) does not have to be a multiple of the encryption block size."

	| s0 s1 s2 |
	s2 := end + 1.
	s0 := start.
	s1 := s0 + blockSize min: s2.
	[ s0 &gt; end ] whileFalse: [
		cipher encryptInPlace: iv.
		(1 to: s1 - s0) with: (s0 to: s1 - 1) do: [ :i :j |
			aByteArray at: j put: (
				(aByteArray at: j) bitXor: (iv at: i)) ].
		s0 := s1.
		s1 := s1 + blockSize min: s2 ]</body>
</methods>

<methods>
<class-id>Security.OutputFeedback</class-id> <category>accessing</category>

<body package="CiphersBase" selector="setIV:">setIV: aByteArray

	aByteArray size ~= blockSize ifTrue: [
		self error: (#IVSizeMismatch &lt;&lt; #security &gt;&gt; 'Initialization Vector does not match the encryption block size !') ].
	iv := aByteArray.</body>
</methods>

<methods>
<class-id>Security.PrimalityTest</class-id> <category>services</category>

<body package="CiphersBase" selector="value:">value: n
"	n &lt;Integer&gt; a positive integer to be tested
	^&lt;Boolean&gt; is n a prime ?"

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.PrimeSieve</class-id> <category>initialization</category>

<body package="CiphersBase" selector="on:">on: nextTest
"	nextTest &lt;PrimalityTest&gt; next test in the chain"

	next := nextTest.
	primes := Primes</body>

<body package="CiphersBase" selector="on:boundedBy:">on: nextTest boundedBy: bound
"	nextTest &lt;PrimalityTest&gt; next test in the chain
	bound &lt;Integer&gt; upper bound on primes to sieve with"

	next := nextTest.
	primes := self class primesUpTo: bound</body>
</methods>

<methods>
<class-id>Security.PrimeSieve</class-id> <category>services</category>

<body package="CiphersBase" selector="value:">value: n
"	n &lt;Integer&gt; a positive integer to be tested
	^&lt;Boolean&gt; is n a prime ?"

	| witness |
	^n even
		ifTrue: [ n = 2 ]
		ifFalse: [ (witness := primes detect: [ :p | (n \\ p) isZero ] ifNone: [ nil ]) notNil
				ifTrue: [ witness = n ]
				ifFalse: [ next value: n ] ]</body>
</methods>

<methods>
<class-id>Security.PrimeSieve class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="on:">on: nextTest
"	nextTest &lt;PrimalityTest&gt; next test in the chain"

	^self new on: nextTest</body>

<body package="CiphersBase" selector="on:boundedBy:">on: nextTest boundedBy: bound
"	nextTest &lt;PrimalityTest&gt; next test in the chain
	bound &lt;Integer&gt; upper bound on primes to sieve with"

	^self new on: nextTest boundedBy: bound</body>
</methods>

<methods>
<class-id>Security.PrimeSieve class</class-id> <category>utility</category>

<body package="CiphersBase" selector="primesUpTo:">primesUpTo: anInteger
"self primesUpTo: 100"

	| primes |
	primes := Primes
			ifNil: [OrderedCollection with: 3]
			ifNotNil: [ :ps |
				(ps detect: [ :p | anInteger &lt;= p ] ifNone: [ nil ])
					ifNotNil: [ :up | ^ps copyUpTo: up ].
				ps copy ].
	primes last + 2 to: anInteger by: 2 do: [ :i |
		(i even or: [
			primes anySatisfy: [ :p | (i \\ p) isZero ] ]
		) ifFalse: [
			primes add: i ] ]	.
	^primes</body>
</methods>

<methods>
<class-id>Security.KeyGenerator</class-id> <category>initialization</category>

<body package="CiphersBase" selector="keySize:">keySize: bitLength
"	bitLength	&lt;SmallInteger&gt; desired bit-length of the generated keys"

	self keySize: bitLength random: self defaultRandom</body>

<body package="CiphersBase" selector="keySize:random:">keySize: bitLength random: aRandom
"	bitLength	&lt;SmallInteger&gt; desired bit-length of the generated keys
	aRandom	&lt;Random&gt; a random seed generator producing large intergers of size 160 bits"

	self keySize: bitLength random: aRandom primalityTest: (self defaultPrimalityTestUsing: aRandom)</body>

<body package="CiphersBase" selector="keySize:random:primalityTest:">keySize: bitLength random: aRandom primalityTest: pTest
"	bitLength	&lt;SmallInteger&gt; desired bit-length of the generated keys
	aRandom	&lt;Random&gt; a random seed generator producing large intergers
	pTest	&lt;PrimalityTest&gt; a probabilistic primality test, with very low error probability"

	keySize := bitLength.
	random := aRandom.
	primalityTest := pTest.</body>
</methods>

<methods>
<class-id>Security.KeyGenerator</class-id> <category>services</category>

<body package="CiphersBase" selector="flush">flush
"Flush all the parameters to make sure next generation creates new ones"

	self subclassResponsibility</body>

<body package="CiphersBase" selector="privateKey">privateKey

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="publicKey">publicKey

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.KeyGenerator</class-id> <category>accessing</category>

<body package="CiphersBase" selector="keySize">keySize
	^keySize</body>

<body package="CiphersBase" selector="primalityTest">primalityTest
	^primalityTest</body>

<body package="CiphersBase" selector="random">random
	^random</body>
</methods>

<methods>
<class-id>Security.KeyGenerator</class-id> <category>private</category>

<body package="CiphersBase" selector="defaultPrimalityTestUsing:">defaultPrimalityTestUsing: aRandom

	^PrimeSieve on: (MillerRabin random: aRandom)</body>

<body package="CiphersBase" selector="defaultRandom">defaultRandom

	^self class random</body>
</methods>

<methods>
<class-id>Security.KeyGenerator class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="keySize:">keySize: bitLength
"	bitLength	&lt;SmallInteger&gt; desired bit-length of the generated keys"

	^self new keySize: bitLength</body>

<body package="CiphersBase" selector="keySize:random:">keySize: bitLength random: aRandom
"	bitLength	&lt;SmallInteger&gt; desired bit-length of the generated keys
	aRandom	&lt;Random&gt; a random seed generator producing large intergers"

	^self new keySize: bitLength random: aRandom</body>

<body package="CiphersBase" selector="keySize:random:primalityTest:">keySize: bitLength random: aRandom primalityTest: pTest
"	bitLength	&lt;SmallInteger&gt; desired bit-length of the generated keys
	aRandom	&lt;Random&gt; a random seed generator producing large intergers
	pTest	&lt;PrimalityTest&gt; a probabilistic primality test, with very low error probability"

	^self new keySize: bitLength random: aRandom primalityTest: pTest</body>
</methods>

<methods>
<class-id>Security.KeyGenerator class</class-id> <category>accessing</category>

<body package="CiphersBase" selector="defaultRandom">defaultRandom

	^DSSRandom default</body>

<body package="CiphersBase" selector="random">random

	^random ifNil: [ self defaultRandom ]</body>

<body package="CiphersBase" selector="random:">random: aRandom
"Set the default random generator for key generators.
	aRandom &lt;Random&gt; secure random generator
"
	random := aRandom</body>
</methods>

<methods>
<class-id>Security.EuclidAlgorithm</class-id> <category>accessing</category>

<body package="CiphersBase" selector="firstCoefficient">firstCoefficient
	^u</body>

<body package="CiphersBase" selector="gcd">gcd
	^gcd</body>

<body package="CiphersBase" selector="secondCoefficient">secondCoefficient
	^ v</body>

<body package="CiphersBase" selector="with:with:">with: numberA with: numberB
	a := numberA.
	b := numberB</body>
</methods>

<methods>
<class-id>Security.EuclidAlgorithm</class-id> <category>services</category>

<body package="CiphersBase" selector="lehmer">lehmer
	"For a desciption of the algorithm below for large integers See 'A Course in Computational Algebraic 
	Number Theory' by Henri Cohen"

	"do Preprocessing"
	| a0 b0 a1 b1 aHat bHat higher aa bb cc dd q t r v1 bcc bdd quoRem e k |
	b1 := b abs.
	a1 := a abs max: b1.
	b1 := a abs min: b1.
	a0 := a1.
	b0 := b1.	"Initialize elements"
	u := 1.
	v1 := 0.
	aa := 1.
	bb := 0.
	cc := 0.
	dd := 1.
	higher := 30. "Core.SmallInteger maxVal highBit."
	["Are we done yet"
	b1 class == SmallInteger]
		whileFalse: 
			[aHat := a1.
			k := higher - a1 highBit.
			(aHat bitShift: k) class == SmallInteger
				ifFalse: 
					[k := k - 1.
					aHat := aHat bitShift: -1].
			bHat := b1 bitShift: k.
			
			["Test the quotient"
			bcc := bHat + cc.
			bcc ~= 0
				and: 
					[bdd := bHat + dd.
					bdd ~= 0
						and: 
							[q := aHat + a1 // bcc.
							q = (aHat + bb // bdd)]]]
				whileTrue: 
					["Euclidean step"
					aa := cc.
					cc := aa - (q * aa).
					bb := dd.
					dd := bb - (q * bb).
					aHat := bHat.
					bHat := aHat - (q * aHat)].
			bb = 0
				ifTrue: 
					["Multi-precision step"
					quoRem := a1 digitDiv: b1 neg: false.
					a1 := b1.
					b1 := quoRem at: 2.
					u := v1.
					v1 := u - ((quoRem at: 1)
									* u)]
				ifFalse: 
					[t := aa * a1 + (bb * b1).
					r := cc * a1 + (dd * b1).
					a1 := t.
					b1 := r.
					t := aa * u + (bb * v1).
					r := cc * u + (dd * v1).
					u := t.
					v1 := r]].
	e := self class with: a1 with: b1.
	e doBasicAlgorithm.
	gcd := e gcd.
	u := u * e firstCoefficient + (v1 * e secondCoefficient).
	v := b0 = 0
				ifTrue: [b0]
				ifFalse: [gcd - (u * a0) // b0].
	a abs &gt;= b abs
		ifFalse: 
			["Postprocess"
			t := u.
			u := v.
			v := t].
	a &lt; 0 ifTrue: [u := u negated].
	b &lt; 0 ifTrue: [v := v negated]</body>

<body package="CiphersBase" selector="run">run
	((a isKindOf: LargePositiveInteger)
		and: [b isKindOf: LargePositiveInteger])
		ifTrue: [self lehmer]
		ifFalse: [self doBasicAlgorithm]</body>
</methods>

<methods>
<class-id>Security.EuclidAlgorithm</class-id> <category>private</category>

<body package="CiphersBase" selector="doBasicAlgorithm">doBasicAlgorithm
	| u1 a1 b1 q r |
	u := 1. u1 := 0. a1 := a. b1 := b.
	[b1 = 0]
		whileFalse: 
			[q := a1 // b1.
			r := a1 - (b1 * q).
			u1 := u - (q * (u := u1)).
			a1 := b1.
			b1 := r].
	gcd := a1.
	v := b = 0
			ifTrue: [b]
			ifFalse: [gcd - (u * a) // b]</body>
</methods>

<methods>
<class-id>Security.EuclidAlgorithm class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="with:with:">with: a with: b
	^ self new with: a with: b</body>
</methods>

<methods>
<class-id>Security.BlockCipherPadding</class-id> <category>initialization</category>

<body package="CiphersBase" selector="on:">on: aCipher

	cipher := aCipher.
	blockSize := aCipher blockSize</body>
</methods>

<methods>
<class-id>Security.BlockCipherPadding</class-id> <category>services</category>

<body package="CiphersBase" selector="decrypt:">decrypt: aByteArray
"Return a new ByteArray decrypted and with padding removed."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="decryptInPlace:">decryptInPlace: aByteArray
"Decrypt aByteArray in place, return the index of the last data byte"

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt aByteArray from start to end, return the index of the last data byte."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encrypt:">encrypt: aByteArray
"Return a new ByteArray padded and encrypted"

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encryptInPlace:">encryptInPlace: aByteArray
"Encrypt aByteArray in place. Return the index of the last byte of cipher text."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt aByteArray from start to end. Return the index of the last byte of cipher text."

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.BlockCipherPadding</class-id> <category>accessing</category>

<body package="CiphersBase" selector="blockSize">blockSize

	^blockSize</body>

<body package="CiphersBase" selector="setIV:">setIV: aByteArray

	cipher setIV: aByteArray</body>

<body package="CiphersBase" selector="setKey:">setKey: aByteArray

	cipher setKey: aByteArray</body>
</methods>

<methods>
<class-id>Security.BlockCipherPadding class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="on:">on: aCipher

	^self new on: aCipher</body>
</methods>

<methods>
<class-id>Security.ECBCiphertextStealing</class-id> <category>services</category>

<body package="CiphersBase" selector="decrypt:">decrypt: aByteArray
"Return a new ByteArray with decrypted contents of &lt;aByteArray&gt; and with padding removed."

	| copy |
	copy := aByteArray copy.
	self decryptInPlace: copy from: 1 to: aByteArray size.
	^copy</body>

<body package="CiphersBase" selector="decryptInPlace:">decryptInPlace: aByteArray
"Decrypt aByteArray in place, return the index of the last data byte."

	^self decryptInPlace: aByteArray from: 1 to: aByteArray size</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;, return the index of the last data byte."

	| blocks lastBlockEnd |
	blocks := end - start // blockSize.
	lastBlockEnd := blocks * blockSize + start - 1.
	lastBlockEnd &lt; start ifTrue: [
		self error: (#NeedAtLeastABlock &lt;&lt; #security &gt;&gt; 'Must get more than one block size of data !') ].
	cipher decryptInPlace: aByteArray from: start to: lastBlockEnd.
	block replaceFrom: 1 to: end - lastBlockEnd with: aByteArray startingAt: lastBlockEnd + 1.
	block replaceFrom: end - lastBlockEnd + 1 to: blockSize with: aByteArray startingAt: end - blockSize + 1.
	cipher decryptInPlace: block.
	aByteArray replaceFrom: lastBlockEnd + 1 to: end with: aByteArray startingAt: lastBlockEnd - blockSize + 1.
	aByteArray replaceFrom: lastBlockEnd - blockSize + 1 to: lastBlockEnd with: block.
	^end</body>

<body package="CiphersBase" selector="encrypt:">encrypt: aByteArray
"Return a new ByteArray with contents of &lt;aByteArray&gt; padded and encrypted"

	| copy |
	copy := aByteArray copy.
	self encryptInPlace: copy from: 1 to: aByteArray size.
	^copy</body>

<body package="CiphersBase" selector="encryptInPlace:">encryptInPlace: aByteArray
"Encrypt aByteArray in place. Return the index of the last byte of cipher text."

	^self encryptInPlace: aByteArray from: 1 to: aByteArray size.</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;  in place.
Returns the index of the last byte of cipher text."

	| blocks lastBlockEnd |
	blocks := end - start // blockSize.
	lastBlockEnd := blocks * blockSize + start - 1.
	lastBlockEnd &lt; start ifTrue: [
		self error: (#NeedAtLeastABlock &lt;&lt; #security &gt;&gt; 'Must get more than one block size of data !') ].
	cipher encryptInPlace: aByteArray from: start to: lastBlockEnd.
	block replaceFrom: 1 to: end - lastBlockEnd with: aByteArray startingAt: lastBlockEnd + 1.
	block replaceFrom: end - lastBlockEnd + 1 to: blockSize with: aByteArray startingAt: end - blockSize + 1.
	cipher encryptInPlace: block.
	aByteArray replaceFrom: lastBlockEnd + 1 to: end with: aByteArray startingAt: lastBlockEnd - blockSize + 1.
	aByteArray replaceFrom: lastBlockEnd - blockSize + 1 to: lastBlockEnd with: block.
	^end</body>
</methods>

<methods>
<class-id>Security.ECBCiphertextStealing</class-id> <category>initialization</category>

<body package="CiphersBase" selector="on:">on: aCipher

	super on: aCipher.
	block := ByteArray new: blockSize</body>
</methods>

<methods>
<class-id>Security.CBCCiphertextStealing</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;, return the index of the last data byte."

	| blocks lastBlockEnd ivBackup |
	blocks := end - start // blockSize.
	lastBlockEnd := blocks * blockSize + start - 1.
	lastBlockEnd &lt; start ifTrue: [
		self error: (#NeedAtLeastABlock &lt;&lt; #security &gt;&gt; 'Must get more than one block size of data !') ].
	blocks &gt; 1 ifTrue: [ cipher decryptInPlace: aByteArray from: start to: lastBlockEnd - blockSize ].
	ivCopy replaceFrom: 1 to: end - lastBlockEnd with: aByteArray startingAt: lastBlockEnd + 1.
	ivCopy replaceFrom: end - lastBlockEnd + 1 to: blockSize with: (RunArray new: blockSize withAll: 0) startingAt: 1.
	ivBackup := cipher getIV.
	cipher setIV: ivCopy.
	cipher decryptInPlace: aByteArray from: lastBlockEnd - blockSize + 1 to: lastBlockEnd.
	cipher setIV: ivBackup.
	block replaceFrom: 1 to: end - lastBlockEnd with: aByteArray startingAt: lastBlockEnd + 1.
	block replaceFrom: end - lastBlockEnd + 1 to: blockSize with: aByteArray startingAt: end - blockSize + 1.
	cipher decryptInPlace: block.
	aByteArray replaceFrom: lastBlockEnd + 1 to: end with: aByteArray startingAt: lastBlockEnd - blockSize + 1.
	aByteArray replaceFrom: lastBlockEnd - blockSize + 1 to: lastBlockEnd with: block.
	ivBackup := cipher getIV.
	cipher setIV: ivCopy.
	ivCopy := ivBackup.
	^end</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;  in place.
Returns the index of the last byte of cipher text."

	| blocks lastBlockEnd |
	blocks := end - start // blockSize.
	lastBlockEnd := blocks * blockSize + start - 1.
	lastBlockEnd &lt; start ifTrue: [
		self error: (#NeedAtLeastABlock &lt;&lt; #security &gt;&gt; 'Must get more than one block size of data !') ].
	cipher encryptInPlace: aByteArray from: start to: lastBlockEnd.
	block replaceFrom: 1 to: end - lastBlockEnd with: aByteArray startingAt: lastBlockEnd + 1.
	block replaceFrom: end - lastBlockEnd + 1 to: blockSize with: (RunArray new: blockSize withAll: 0) startingAt: 1.
	cipher encryptInPlace: block.
	aByteArray replaceFrom: lastBlockEnd + 1 to: end with: aByteArray startingAt: lastBlockEnd - blockSize + 1.
	aByteArray replaceFrom: lastBlockEnd - blockSize + 1 to: lastBlockEnd with: block.
	^end</body>
</methods>

<methods>
<class-id>Security.CBCCiphertextStealing</class-id> <category>initialization</category>

<body package="CiphersBase" selector="on:">on: aCipher

	super on: aCipher.
	ivCopy := ByteArray new: blockSize</body>
</methods>

<methods>
<class-id>Security.MillerRabin</class-id> <category>initialization</category>

<body package="CiphersBase" selector="t:max:">t: securityParameter max: upperBound
"	securityParameter	&lt;Integer&gt; the security parameter t; probability of a false prime is less then (1/4)^t; t &gt; 0
	upperBound	&lt;Integer&gt; any integer that is to be tested for primality will not be greater than this"

	self
		t: securityParameter
		random: (self defaultRandomBoundedBy: upperBound)</body>

<body package="CiphersBase" selector="t:random:">t: securityParameter random: aRandom
"	securityParameter	&lt;Integer&gt; the security parameter t; probability of a false prime is less then (1/4)^t; t &gt; 0
	aRandom	&lt;Random&gt; must generate positive integers up to the largest integer to be tested for primality"

	t := securityParameter.
	random := aRandom</body>
</methods>

<methods>
<class-id>Security.MillerRabin</class-id> <category>services</category>

<body package="CiphersBase" selector="value:">value: n
"Implements the Miller-Rabin algorithm as described in [HAC] 4.24
	n &lt;Integer&gt; a positive integer to be tested
	^&lt;Boolean&gt; is n a prime ?"

	| n1 ps s r n4 |
	n even ifTrue: [^n = 2].
	"Find s, r such that n - 1 = 2^s * r; r is odd"
	n1 := n - 1.
	ps := 1 "2^0".
	s := 0.
	[ (ps bitAnd: n1) isZero ] whileTrue: [
		ps := ps bitShift: 1. s := s + 1 ].
	r := n1 bitShift: s negated.
	n4 := n - 4.
	t timesRepeat: [ | a y |
		a := random next \\ n4 + 2. "random a; 2 &lt;= a &lt;= n - 2"
		y := a raisedTo: r modulo: n.
		(y = 1 or: [ y = n1 ]) ifFalse: [ | j |
			j := 1.
			[j &lt; s and: [ y ~= n1 ]] whileTrue: [
				y := y * y \\ n.
				y = 1 ifTrue: [^false].
				j := j + 1 ].
			y = n1 ifFalse: [^false] ] ].
	^true</body>
</methods>

<methods>
<class-id>Security.MillerRabin</class-id> <category>private</category>

<body package="CiphersBase" selector="defaultRandomBoundedBy:">defaultRandomBoundedBy: aPositiveInteger
	
	^DSSRandom
		q: aPositiveInteger
		seed: DSSRandom default next</body>
</methods>

<methods>
<class-id>Security.MillerRabin class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="max:">max: upperBound
"	upperBound	&lt;Integer&gt; any integer that is to be tested for primality will not be greater than this"

	^self new t: DefaultT max: upperBound</body>

<body package="CiphersBase" selector="random:">random: aRandom
"	aRandom	&lt;Random&gt; must generate positive integers up to the largest integer to be tested for primality"

	^self new t: DefaultT random: aRandom</body>

<body package="CiphersBase" selector="t:max:">t: securityParameter max: upperBound
"	securityParameter	&lt;Integer&gt; the security parameter t; probability of a false prime is less then (1/4)^t; t &gt; 0
	upperBound	&lt;Integer&gt; any integer that is to be tested for primality will not be greater than this"

	^self new t: securityParameter max: upperBound</body>

<body package="CiphersBase" selector="t:random:">t: securityParameter random: aRandom
"	securityParameter	&lt;Integer&gt; the security parameter t; probability of a false prime is less then (1/4)^t; t &gt; 0
	aRandom	&lt;Random&gt; must generate positive integers up to the largest integer to be tested for primality"

	^self new t: securityParameter random: aRandom</body>
</methods>

<methods>
<class-id>Security.TripleEDE</class-id> <category>initialization</category>

<body package="CiphersBase" selector="first:second:third:">first: aCipher second: aCipher2 third: aCipher3

	blockSize := aCipher blockSize.
	cipher := aCipher.
	cipher2 := aCipher2.
	cipher3 := aCipher3.</body>

<body package="CiphersBase" selector="on:">on: aCipher

	self error: (#OnNotAppropriate &lt;&lt; #security &gt;&gt; 'Need three instances of cipher, so this method is not apropriate for this mode !')</body>
</methods>

<methods>
<class-id>Security.TripleEDE</class-id> <category>accessing</category>

<body package="CiphersBase" selector="first">first

	^cipher</body>

<body package="CiphersBase" selector="second">second

	^cipher2</body>

<body package="CiphersBase" selector="setKey:">setKey: aByteArray

	| keySize |
	keySize := aByteArray size // 3.
	cipher setKey: (aByteArray copyFrom: 1 to: keySize).
	cipher2 setKey: (aByteArray copyFrom: keySize + 1 to: 2 * keySize).
	cipher3 setKey: (aByteArray copyFrom: 2 * keySize + 1 to: 3 * keySize).</body>

<body package="CiphersBase" selector="third">third

	^cipher3</body>
</methods>

<methods>
<class-id>Security.TripleEDE</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:at:">decryptInPlace: aByteArray at: start
"Decrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	cipher3 decryptInPlace: aByteArray at: start.
	cipher2 encryptInPlace: aByteArray at: start.
	cipher decryptInPlace: aByteArray at: start.</body>

<body package="CiphersBase" selector="encryptInPlace:at:">encryptInPlace: aByteArray at: start
"Encrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	cipher encryptInPlace: aByteArray at: start.
	cipher2 decryptInPlace: aByteArray at: start.
	cipher3 encryptInPlace: aByteArray at: start.</body>
</methods>

<methods>
<class-id>Security.TripleEDE class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="first:second:third:">first: aCipher second: aCipher2 third: aCipher3

	^self new first: aCipher second: aCipher2 third: aCipher3</body>
</methods>

<methods>
<class-id>Security.TripleEDEInnerCBC</class-id> <category>accessing</category>

<body package="CiphersBase" selector="setIV:">setIV: aByteArray

	aByteArray size ~= (3 * blockSize) ifTrue: [
		self error: (#IVSizeMismatch &lt;&lt; #security &gt;&gt; 'Initialization Vector does not match the encryption block size !') ].
	cipher setIV: (aByteArray copyFrom: 1 to: blockSize).
	cipher2 setIV: (aByteArray copyFrom: blockSize + 1 to: 2 * blockSize).
	cipher3 setIV: (aByteArray copyFrom: 2 * blockSize + 1 to: aByteArray size).</body>
</methods>

<methods>
<class-id>Security.TripleEDEInnerCBC</class-id> <category>initialization</category>

<body package="CiphersBase" selector="first:second:third:">first: aCipher second: aCipher2 third: aCipher3

	blockSize := aCipher blockSize.
	cipher := CipherBlockChaining on: aCipher.
	cipher2 := CipherBlockChaining on: aCipher2.
	cipher3 := CipherBlockChaining on: aCipher3.</body>
</methods>

<methods>
<class-id>Security.TripleEDEOuterCBC</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:at:">decryptInPlace: aByteArray at: start
"Decrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	block replaceFrom: 1 to: blockSize with: aByteArray startingAt: start.
	cipher3 decryptInPlace: aByteArray at: start.
	cipher2 encryptInPlace: aByteArray at: start.
	cipher decryptInPlace: aByteArray at: start.
	iv replaceFrom: 1 to: blockSize with: block.
	ivBackup replaceFrom: 1 to: blockSize with: block.</body>

<body package="CiphersBase" selector="encryptInPlace:at:">encryptInPlace: aByteArray at: start
"Encrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	cipher encryptInPlace: aByteArray at: start.
	cipher2 decryptInPlace: aByteArray at: start.
	cipher3 encryptInPlace: aByteArray at: start.
	iv replaceFrom: 1 to: blockSize with: aByteArray startingAt: start.</body>
</methods>

<methods>
<class-id>Security.TripleEDEOuterCBC</class-id> <category>accessing</category>

<body package="CiphersBase" selector="setIV:">setIV: aByteArray

	aByteArray size ~= blockSize ifTrue: [
		self error: (#IVSizeMismatch &lt;&lt; #security &gt;&gt; 'Initialization Vector does not match the encryption block size !') ].
	iv := aByteArray.
	cipher setIV: aByteArray.
	ivBackup := cipher getIVBackup.</body>
</methods>

<methods>
<class-id>Security.TripleEDEOuterCBC</class-id> <category>private</category>

<body package="CiphersBase" selector="getIV">getIV

	^iv</body>
</methods>

<methods>
<class-id>Security.TripleEDEOuterCBC</class-id> <category>initialization</category>

<body package="CiphersBase" selector="first:second:third:">first: aCipher second: aCipher2 third: aCipher3

	blockSize := aCipher blockSize.
	cipher := CipherBlockChaining on: aCipher.
	cipher2 := aCipher2.
	cipher3 := aCipher3.
	block := ByteArray new: blockSize</body>
</methods>

<methods>
<class-id>Security.CipherBlockChaining</class-id> <category>private</category>

<body package="CiphersBase" selector="getIV">getIV

	^iv</body>

<body package="CiphersBase" selector="getIVBackup">getIVBackup

	^ivBackup</body>
</methods>

<methods>
<class-id>Security.CipherBlockChaining</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:at:">decryptInPlace: aByteArray at: start
"Decrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	iv replaceFrom: 1 to: blockSize with: aByteArray startingAt: start.
	cipher decryptInPlace: aByteArray at: start.
	ivBackup with: (start to: start + blockSize - 1) do: [ :b :p |
		aByteArray at: p put: ((aByteArray at: p) bitXor: b) ].
	ivBackup replaceFrom: 1 to: blockSize with: iv.</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) is expected to be a multiple of the encryption block size."

	| s0 s1 s2 |
	s1 := (end - start // blockSize) * blockSize + start.
	iv replaceFrom: 1 to: blockSize with: aByteArray startingAt: s1.
	cipher decryptInPlace: aByteArray at: s1.
	s0 := s1 - blockSize.
	s2 := s1 + blockSize.
	[ s1 &gt; start ] whileTrue: [
		(s0 to: s1 - 1) with: (s1 to: s2 - 1) do: [ :f :t |
			aByteArray at: t put: ((aByteArray at: t) bitXor: (aByteArray at: f)) ].
		cipher decryptInPlace: aByteArray at: s0.
		s2 := s1. s1 := s0. s0 := s0 - blockSize ].
	ivBackup with: (s1 to: s2 - 1) do: [ :b :p |
		aByteArray at: p put: ((aByteArray at: p) bitXor: b) ].
	ivBackup replaceFrom: 1 to: blockSize with: iv.</body>

<body package="CiphersBase" selector="encryptInPlace:at:">encryptInPlace: aByteArray at: start
"Encrypt in place one block of &lt;aByteArray&gt; at postion &lt;start&gt;.
Block size is defined by the encryption algorithm."

	
	iv with: (start to: start + blockSize - 1) do: [ :b :p |
		aByteArray at: p put: ((aByteArray at: p) bitXor: b) ].
	cipher encryptInPlace: aByteArray at: start.
	iv replaceFrom: 1 to: blockSize with: aByteArray startingAt: start.</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) is expected to be a multiple of the encryption block size."

	| s0 s1 s2 |
	s0 := start.
	s1 := s0 + blockSize.
	iv with: (s0 to: s1 - 1) do: [ :b :p |
		aByteArray at: p put: ((aByteArray at: p) bitXor: b) ].
	cipher encryptInPlace: aByteArray at: start.
	s2 := s1 + blockSize.
	[ s1 &lt; end ] whileTrue: [
		(s0 to: s1 - 1) with: (s1 to: s2 - 1) do: [ :f :t |
			aByteArray at: t put: ((aByteArray at: t) bitXor: (aByteArray at: f)) ].
		cipher encryptInPlace: aByteArray at: s1.
		s0 := s1. s1 := s2. s2 := s2 + blockSize ].
	iv replaceFrom: 1 to: blockSize with: aByteArray startingAt: s0.</body>
</methods>

<methods>
<class-id>Security.CipherBlockChaining</class-id> <category>initialization</category>

<body package="CiphersBase" selector="on:">on: aCipher

	super on: aCipher.
	ivBackup := ByteArray new: blockSize</body>
</methods>

<methods>
<class-id>Security.CipherBlockChaining</class-id> <category>accessing</category>

<body package="CiphersBase" selector="setIV:">setIV: aByteArray

	aByteArray size ~= blockSize ifTrue: [
		self error: (#IVSizeMismatch &lt;&lt; #security &gt;&gt; 'Initialization Vector does not match the encryption block size !') ].
	iv := aByteArray.
	ivBackup replaceFrom: 1 to: blockSize with: iv.</body>
</methods>

<methods>
<class-id>Security.CipherBlockChaining class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="on:iv:">on: aCipher iv: aByteArray

	^(self on: aCipher)
		setIV: aByteArray;
		yourself</body>
</methods>

<methods>
<class-id>Security.CrpRandom</class-id> <category>initialize-release</category>

<body package="CiphersBase" selector="initializeQ:">initializeQ: qInteger

	self
		initializeQ: qInteger
		seed: self class systemStateSeed</body>

<body package="CiphersBase" selector="initializeQ:seed:">initializeQ: qInteger seed: seedInteger

	self
		initializeQ: qInteger
		seed: seedInteger
		bits: 160</body>

<body package="CiphersBase" selector="initializeQ:seed:bits:">initializeQ: qInteger seed: seedInteger bits: bInteger

	q := qInteger.
	xkey := seedInteger.
	bitLength := bInteger</body>
</methods>

<methods>
<class-id>Security.CrpRandom</class-id> <category>accessing</category>

<body package="CiphersBase" selector="nextUsing:">nextUsing: stepSeedInteger
	"Answer the next random value using the supplied argument as an
'auxiliary one-time seed'.
	See Section 3.1 of the standard for details."

	| xval result twoToB |
	twoToB := 1 bitShift: bitLength.
	xval := (xkey + stepSeedInteger) \\ twoToB.
	result := (SHA hashInteger: xval) \\ q.
	xkey := (1 + xkey + result) \\ twoToB.
	^result</body>
</methods>

<methods>
<class-id>Security.CrpRandom class</class-id> <category>instance creation</category>

<body package="CiphersBase" selector="newSeededGenerator">newSeededGenerator
	| inst |
	inst := self new  initializeQ: self systemStateSeed.
	^inst</body>

<body package="CiphersBase" selector="newSeededGeneratorReturnBits:">newSeededGeneratorReturnBits: bitLength
	| inst |
	inst := self new  initializeQ: self systemStateSeed seed: self  systemStateSeed bits: bitLength.
	^inst</body>
</methods>

<methods>
<class-id>Security.CrpRandom class</class-id> <category>testing</category>

<body package="CiphersBase" selector="test1">test1
"self test1"
	^self new initializeQ: self systemStateSeed.</body>
</methods>

<methods>
<class-id>Security.CrpRandom class</class-id> <category>utilities</category>

<body package="CiphersBase" selector="systemStateSeed">systemStateSeed
	"An integer seed built of a bunch of system-supplied values.
	The result should be at least 160 bits long."
	"self systemStateSeed"

	| value om |
	om := ObjectMemory current.
	value := (Random new next * 65536) floor. "16 bits"
	value := (value bitShift: 16) bitXor: om edenUsedBytes.
	value := (value bitShift: 16) bitXor: om survUsedBytes.
	value := (value bitShift: 24) bitXor: om threadedDataBytes.
	value := (value bitShift: 16) bitXor: om allocProbes.
	value := (value bitShift: 24) bitXor: om availableFreeBytes.
	value := (value bitShift: 16) bitXor: om oopsLeft.
	value := (value bitShift: 20) bitXor: om incMarkedBytes.
	value := (value bitShift: 16) bitXor: om incNilledBytes.
	^value asBigEndianByteArray shaValue</body>
</methods>

<methods>
<class-id>Security.AsymmetricCipher</class-id> <category>accessing</category>

<body package="CiphersBase" selector="privateKey">privateKey

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="privateKey:">privateKey: aPrivateKey

	self subclassResponsibility</body>

<body package="CiphersBase" selector="publicKey">publicKey

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="publicKey:">publicKey: aPublicKey

	self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.AsymmetricCipher</class-id> <category>services</category>

<body package="CiphersBase" selector="decrypt:">decrypt: aByteArray
"Decrypt aByteArray using the previously assigned private key."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encrypt:">encrypt: aByteArray
"Encrypts aByteArray using the previously assigned public key"

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="sign:">sign: aMessageArray
"Compute a signature of aMessageArray."

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="verify:of:">verify: aSignatureArray of: aMessageArray
"Denies or confirms that aSignatureArray is a signature of aMessageArray."

	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>Security.StreamCipher</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptByte:">decryptByte: aByte

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
Return the index of the last data byte"

	start to: end do: [ :p |
		aByteArray
			at: p
			put: (self decryptByte: (
					aByteArray at: p)) ].
	^end</body>

<body package="CiphersBase" selector="encryptByte:">encryptByte: aByte

	^self subclassResponsibility</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt in place contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
Return the index of the last cipher byte."

	start to: end do: [ :p |
		aByteArray
			at: p
			put: (self encryptByte: (
					aByteArray at: p)) ].
	^end</body>
</methods>

<methods>
<class-id>Security.BlockPadding</class-id> <category>services</category>

<body package="CiphersBase" selector="decrypt:">decrypt: aByteArray
"Return a new ByteArray with decrypted contents of &lt;aByteArray&gt; and with padding removed.
&lt;aByteArary&gt; must be a multiple of the encryption block size."

	| copy lastByte |
	copy := aByteArray copy.
	lastByte := self decryptInPlace: copy.
	^lastByte = copy size
		ifTrue: [ copy ]
		ifFalse: [ copy copyFrom: 1 to: lastByte ]</body>

<body package="CiphersBase" selector="decryptInPlace:">decryptInPlace: aByteArray
"Decrypt aByteArray in place, return the index of the last data byte.
&lt;aByteArary&gt; must be a multiple of the encryption block size."

	^self decryptInPlace: aByteArray from: 1 to: aByteArray size</body>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;, return the index of the last data byte.
(start to: end) must be a multiple of the encryption block size."

	cipher decryptInPlace: aByteArray from: start to: end.
	^self detectPaddingIn: aByteArray from: start to: end</body>

<body package="CiphersBase" selector="encrypt:">encrypt: aByteArray
"Return a new ByteArray with contents of &lt;aByteArray&gt; padded and encrypted"

	| size newSize copy |
	size := aByteArray size.
	newSize := (size // blockSize + 1) * blockSize.
	copy := ByteArray new: newSize.
	copy replaceFrom: 1 to: size with: aByteArray startingAt: 1.
	self encryptInPlace: copy from: 1 to: size.
	^copy</body>

<body package="CiphersBase" selector="encryptInPlace:">encryptInPlace: aByteArray
"Encrypt aByteArray in place. Return the index of the last byte of cipher text."

	^self error: (#InvalidOperation &lt;&lt; #security &gt;&gt; 'This operation does not make sense with this style of padding !')</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;  in place.
There must be room after &lt;end&gt; to the next multiple of encryption block size.
The contents of this additional space will be destroyed.
Returns the index of the last byte of cipher text."

	| blocks newEnd |
	blocks := end - start + 1 // blockSize + 1.
	newEnd := blocks * blockSize + start - 1.
	self fillPaddingIn: aByteArray from: end + 1 to: newEnd.
	cipher encryptInPlace: aByteArray from: start to: newEnd.
	^newEnd</body>
</methods>

<methods>
<class-id>Security.BlockPadding</class-id> <category>private</category>

<body package="CiphersBase" selector="detectPaddingIn:from:to:">detectPaddingIn: aByteArray from: start to: end

	^end - (aByteArray at: end)</body>

<body package="CiphersBase" selector="fillPaddingIn:from:to:">fillPaddingIn: aByteArray from: start to: end

	| padByte |
	padByte := end - start + 1.
	start to: end do: [ :i |
		aByteArray at: i put: padByte ]</body>
</methods>

<methods>
<class-id>Security.AutogeneratedSeeding</class-id> <category>private - actions</category>

<body package="CiphersBase" selector="defaultAction">defaultAction

	^Dialog warn: self description</body>
</methods>

<methods>
<class-id>Security.AutogeneratedSeeding class</class-id> <category>class initialization</category>

<body package="CiphersBase" selector="initialize">initialize

	notifierString :=
		#AutogeneratedSeeding &lt;&lt; #security &gt;&gt;
		'Random generator is about to be seeded from an auto-generated seed.\This may not satisfy your security requirements!' withCRs</body>
</methods>

<methods>
<class-id>Security.CipherFeedback</class-id> <category>services</category>

<body package="CiphersBase" selector="decryptInPlace:from:to:">decryptInPlace: aByteArray from: start to: end
"Decrypt in place the contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) does not have to be a multiple of the encryption block size."

	| s0 s1 s2 |
	s2 := end + 1.
	s0 := start.
	s1 := s0 + blockSize min: s2.
	[ s0 &gt; end ] whileFalse: [
		cipher encryptInPlace: iv.
		(1 to: s1 - s0) with: (s0 to: s1 - 1) do: [ :i :j |
			aByteArray at: j put: (
				(iv"Backup" at: i) bitXor: (iv at: i put: (aByteArray at: j))) ].
		"ivBackup replaceFrom: 1 to: blockSize with: iv."
		s0 := s1.
		s1 := s1 + blockSize min: s2 ]</body>

<body package="CiphersBase" selector="encryptInPlace:from:to:">encryptInPlace: aByteArray from: start to: end
"Encrypt in place the contents of &lt;aByteArray&gt; from &lt;start&gt; to &lt;end&gt;.
(start to: end) does not have to be a multiple of the encryption block size."

	| s0 s1 s2 |
	s2 := end + 1.
	s0 := start.
	s1 := s0 + blockSize min: s2.
	[ s0 &gt; end ] whileFalse: [
		cipher encryptInPlace: iv.
		(1 to: s1 - s0) with: (s0 to: s1 - 1) do: [ :i :j |
			aByteArray at: j put: (
				iv at: i put: (
					(aByteArray at: j) bitXor: (iv at: i))) ].
		s0 := s1.
		s1 := s1 + blockSize min: s2 ]</body>
</methods>

<methods>
<class-id>Security.CipherFeedback</class-id> <category>accessing</category>

<body package="CiphersBase" selector="setIV:">setIV: aByteArray

	aByteArray size ~= blockSize ifTrue: [
		self error: (#IVSizeMismatch &lt;&lt; #security &gt;&gt; 'Initialization Vector does not match the encryption block size !') ].
	iv := aByteArray.</body>
</methods>

<methods>
<class-id>OS.Win32SystemSupport class</class-id> <category>documentation</category>

<body package="CiphersBase" selector="documentation_CryptGenRandom">documentation_CryptGenRandom
"Here is how to use the CryptGenRandom extension

	exInt := Win32SystemSupport new.
	provider := exInt CryptAcquireNormalContext.
	randomBytes := exInt CryptGenRandomProvider: provider len: 32.
	exInt CryptReleaseContext: provider.
	exInt CryptDeleteNormalContext

randomBytes now contains 32 random bytes.
"</body>
</methods>

<methods>
<class-id>OS.Win32SystemSupport</class-id> <category>procedures</category>

<body package="CiphersBase" selector="CryptAcquireContextContainerName:providerName:providerType:flags:">CryptAcquireContextContainerName:  pszContainer providerName: pszProvider providerType: dwProvType flags: dwFlags

"providerNames listed in the documentation, or nil for default:
'Microsoft DH Schannel Cryptographic Provider' 
 'Microsoft Base DSS and Diffie-Hellman Cryptographic Provider' 
'Microsoft Base DSS Cryptographic Provider' 
'Microsoft Base Cryptographic Provider v1.0' 
'Microsoft RSA Schannel Cryptographic Provider' 
'Microsoft RSA Signature Cryptographic Provider' 
'Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider' 
'Microsoft Enhanced RSA and AES Cryptographic Provider' 
'Microsoft Enhanced Cryptographic Provider v1.0' 
'Microsoft Base Smart Card Crypto Provider' 
'Microsoft Strong Cryptographic Provider' 
provider types listed in the docs:
#define PROV_RSA_FULL           1
#define PROV_RSA_SIG            2
#define PROV_DSS                3
#define PROV_FORTEZZA           4
#define PROV_MS_EXCHANGE        5
#define PROV_SSL                6
#define PROV_RSA_SCHANNEL       12
#define PROV_DSS_DH             13
#define PROV_EC_ECDSA_SIG       14
#define PROV_EC_ECNRA_SIG       15
#define PROV_EC_ECDSA_FULL      16
#define PROV_EC_ECNRA_FULL      17
#define PROV_SPYRUS_LYNKS       20"
	| phProv |
	phProv := self HCRYPTPROV malloc.
	self CryptAcquireContext: phProv containerName:  pszContainer providerName: pszProvider providerType: dwProvType flags: dwFlags.
	^phProv at: 0</body>

<body package="CiphersBase" selector="CryptAcquireNormalContext">CryptAcquireNormalContext
	^self CryptAcquireContextContainerName: 'VisualWorks' providerName: nil providerType: 1 flags: self CRYPT_NEWKEYSET</body>

<body package="CiphersBase" selector="CryptDeleteNormalContext">CryptDeleteNormalContext
	^self CryptAcquireContextContainerName: 'VisualWorks' providerName: nil providerType: 1 flags: self CRYPT_DELETEKEYSET</body>

<body package="CiphersBase" selector="CryptGenRandomProvider:len:">CryptGenRandomProvider: hProv len: dwLen

	| pbBuffer result |
	pbBuffer := self BYTE malloc: dwLen.
	self CryptGenRandomProvider: hProv len: dwLen buffer: pbBuffer.
	result := ByteArray new: dwLen.
	pbBuffer copyAt: 0 to: result size: dwLen startingAt: 1.
	pbBuffer free.
	^result</body>

<body package="CiphersBase" selector="CryptReleaseContext:">CryptReleaseContext: hProv
	^self CryptReleaseContext: hProv flags: 0 "Reserved for future use and must be zero."</body>
</methods>

<methods>
<class-id>OS.Win32SystemSupport</class-id> <category>defines</category>

<body package="CiphersBase" selector="CRYPT_DELETEKEYSET"> CRYPT_DELETEKEYSET
	&lt;C:#define CRYPT_DELETEKEYSET      0x00000010
&gt;</body>

<body package="CiphersBase" selector="CRYPT_NEWKEYSET">CRYPT_NEWKEYSET
	&lt;C:#define CRYPT_NEWKEYSET         0x00000008
&gt;</body>
</methods>

<methods>
<class-id>OS.Win32SystemSupport</class-id> <category>types</category>

<body package="CiphersBase" selector="HCRYPTPROV">HCRYPTPROV
	&lt;C:typedef unsigned long HCRYPTPROV&gt;</body>
</methods>

<methods>
<class-id>Core.Integer class</class-id> <category>deprecated</category>

<body package="CiphersBase" selector="generate160BitPrime">generate160BitPrime
"DEPRECATED.
	self generate160BitPrime
"
	^self generatePrimeBits: 160</body>

<body package="CiphersBase" selector="generatePrimeBits:">generatePrimeBits: numberOfBits
"DEPRECATED.
	self generatePrimeBits: 1024
"
	^self randomPrimeBits: numberOfBits</body>

<body package="CiphersBase" selector="generateRandomBits:">generateRandomBits: total
"DEPRECATED"

	^self randomBits: total</body>

<body package="CiphersBase" selector="primesUpTo:">primesUpTo: max
"DEPRECATED: Return a list of prime integers up to the given integer.
"
	^Security.PrimeSieve primesUpTo: max</body>

<body package="CiphersBase" selector="random160BitPrime">random160BitPrime
"DEPRECATED.
	self random160BitPrime
"
	^self randomPrimeBits: 160</body>

<body package="CiphersBase" selector="randomBits:">randomBits: size
"Generate a random integer of bit size.
	(1 to: 1024) reject: [ :i | i = (self randomBits: i) highBit ]
	(1 to: 1024) inject: true into: [ :success :i | (i = (self randomBits: i) highBit) &amp; success ]
"
	| random bits |
	random := Security.DSSRandom default.
	bits := random next.
	[	bits highBit &lt; size
	] whileTrue: [
		bits := (bits bitShift: random blockSize) bitOr: random next ].
	^bits bitShift: (size - bits highBit)</body>

<body package="CiphersBase" selector="randomNumber">randomNumber
"Note that this method depends on current configuration of the default DSSRandom generator. Usually that would mean that the returned number will be 40-bits long, but if the generator was reconfigured with for example lower upper bound parameter (q) then it will return smaller number. You may want to prefer method #randomBits: instead.
"
	^Security.DSSRandom default next</body>

<body package="CiphersBase" selector="randomPrimeBits:">randomPrimeBits: numberOfBits
"
	self randomPrimeBits: 1024
"
	| trials |
	trials := numberOfBits * 100.
	[ trials &gt; 0 ] whileTrue: [ | candidate |
		candidate := self randomBits: numberOfBits.
		candidate isProbablyPrime ifTrue: [ ^candidate ].
		trials := trials - 1 ].
	"Schneier/Fergusson estimated probability of this to 2**-128,
	so if this happened you really should go gambling today."
	self error: (
		#FailedToGenerateRandomPrime1p &lt;&lt; #security &gt;&gt;
		'Failed to generate &lt;1p&gt;-bit random prime. Try again!'
			expandMacrosWith: numberOfBits )</body>
</methods>

<methods>
<class-id>Core.Integer</class-id> <category>security</category>

<body package="CiphersBase" selector="&lt;&lt;">&lt;&lt; integer
	^self bitShift: integer</body>

<body package="CiphersBase" selector="&gt;&gt;">&gt;&gt; integer
	^self bitShift: integer negated</body>
</methods>

<methods>
<class-id>Core.Integer</class-id> <category>deprecated</category>

<body package="CiphersBase" selector="asBitMask">asBitMask
"DEPRECATED! return a bit mask as all 1's with the bitlength equal to my value"

	^(1 to: self - 1)
		inject: 1
		into: 
			[:mask :index | 
			| shift |
			shift := 1 bitShift: index.
			mask + shift]</body>
</methods>

<methods>
<class-id>Core.Integer</class-id> <category>security</category>

<body package="CiphersBase" selector="isProbablyPrime">isProbablyPrime
"Use probablilistic primality test on the receiver."

	^(Security.PrimeSieve on: (Security.MillerRabin max: self)) value: self</body>

<body package="CiphersBase" selector="raisedTo:modulo:">raisedTo: anExponent modulo: aModulus 
"This will perform following computation (a raisedTo: b) \\ n. We're using a binary square and multiply method to avoid excessively large intermediate results."

	^anExponent asBigEndianByteArray "bit-endian"
		inject: 1
		into: [ :total :byte |
			#(128 64 32 16 8 4 2 1)
				inject: total
				into: [ :subtotal :mask || square |
					square := subtotal * subtotal \\ aModulus.
					(byte bitAnd: mask) == 0
						ifTrue: [ square ]
						ifFalse: [ square * self \\ aModulus ] ] ]</body>
</methods>

<methods>
<class-id>Core.SystemEventInterest class</class-id> <category>dependencies-pragma</category>

<body package="CiphersBase" selector="flushDefaultDSSRandom">flushDefaultDSSRandom
"If the default random instance gets saved with the image, the generator will start from the same state on every subsequent run of that image, which of course means that it will generate the exact same sequence on each subsequent run. If that happens in a production system the security impact would be catastrophic. 
Flushing the default will get the generator seeded from our ad-hoc seeding method, which may have its issues as well, but is far better than the catastrophic scenario. Applications that take security seriously should maintain their own generator and a seed file tailored to its specific circumstances. See the documentation for more advice."

	&lt;triggerAtSystemEvent: #returnFromSnapshot&gt;

	Security.DSSRandom flushDefault</body>
</methods>

<methods>
<class-id>OS.Win32SystemSupport</class-id> <category>procedures</category>

<body package="CiphersBase" selector="CryptAcquireContext:containerName:providerName:providerType:flags:">CryptAcquireContext:  phProv containerName:  pszContainer providerName: pszProvider providerType: dwProvType flags: dwFlags
	&lt;C:BOOL _wincall CryptAcquireContextA(
	  HCRYPTPROV* phProv,
	  LPCTSTR pszContainer,
	  LPCTSTR pszProvider,
	  DWORD dwProvType,
	  DWORD dwFlags
	)&gt;
	^self externalAccessFailedWith: _errorCode</body>

<body package="CiphersBase" selector="CryptGenRandomProvider:len:buffer:">CryptGenRandomProvider: hProv len: dwLen buffer: pbBuffer

	&lt;C:BOOL _wincall CryptGenRandom( 
	  HCRYPTPROV hProv,
	  DWORD dwLen, 
	  BYTE* pbBuffer
	)&gt;
	^self externalAccessFailedWith: _errorCode</body>

<body package="CiphersBase" selector="CryptReleaseContext:flags:">CryptReleaseContext: hProv flags: dwFlags

&lt;C: BOOL _wincall CryptReleaseContext(
  HCRYPTPROV hProv,
  DWORD dwFlags
)&gt;
	^self externalAccessFailedWith: _errorCode</body>
</methods>

<initialize>
<class-id>Security.AutogeneratedSeeding</class-id>
</initialize>

<do-it>"Imported Classes:"</do-it>

<do-it>self error: 'Attempting to file-in parcel imports.  Choose terminate or close'</do-it>

<class>
<name>Object</name>
<environment>Core</environment>
<super></super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Kernel-Objects</category>
<attributes>
<package>Kernel-Objects</package>
</attributes>
</class>

<class>
<name>Integer</name>
<environment>Core</environment>
<super>Core.Number</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Magnitude-Numbers</category>
<attributes>
<package>Magnitude-Numbers</package>
</attributes>
</class>

<class>
<name>Win32SystemSupport</name>
<environment>OS</environment>
<super>OS.OSSystemSupport</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports>
			OS.Win32SystemSupportDictionary.*
			</imports>
<category>OS-Support</category>
<attributes>
<includeFiles></includeFiles>
<includeDirectories></includeDirectories>
<libraryFiles><item>kernel32.dll</item> <item>gdi32.dll</item> <item>advapi32.dll</item> <item>user32.dll</item></libraryFiles>
<libraryDirectories></libraryDirectories>
<beVirtual type="eval">false</beVirtual>
<optimizationLevel type="sym">full</optimizationLevel>
<package>OS-Support</package>
</attributes>
</class>

<class>
<name>Warning</name>
<environment>Core</environment>
<super>Core.Exception</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Kernel-Exception Handling</category>
<attributes>
<package>Kernel-Exception Handling</package>
</attributes>
</class>

<class>
<name>EventManager</name>
<environment>Core</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>handlers </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>System-Dependency Events</category>
<attributes>
<package>System-Dependency Events</package>
</attributes>
</class>

<class>
<name>Random</name>
<environment>Core</environment>
<super>Core.Stream</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>seed </inst-vars>
<class-inst-vars>defaultGeneratorClass </class-inst-vars>
<imports></imports>
<category>Magnitude-Numbers</category>
<attributes>
<package>Magnitude-Numbers</package>
</attributes>
</class>

</st-source>
