| Payment ]
[ Logi Ragnarsson
| Send Mail ]
[ General info
| Status & Plans
| Commercial License
| Class docs ]
logi.crypto Status and Plans
This is the read.me file for the java package org.logi.crypto, version
1.0.7, dated 2000.07.07.
- A java 1.1 compatible virtual machine. Most implementation dependant
behaviour is in the user interface code, which logi.crypto doesn't use
at all, so there is no reason why it shouldn't work on all platforms.
- A good feel for how cryptography works. I'm sorry, but no matter
how easy to use the package becomes, you need a fair understanding
of cryptography to be able to use it securely. The system will, for
example, lose all security if you publish the wrong keys or trust
keys from an unknown party. Badly used cryptography is worse than
none at all. Read a book.
- The RSA algorithm with the RSAKey class.
- The ElGamal algorithm with the DHKey class.
- The DES algorithm with the DESKey class.
- Triple DES with the TriDESKey class. (EDE with three sub-keys).
- The Blowfish algorithm with the BlowfishKey class.
- Encrypting/decrypting arbitrary byte arrays in ECB, CBC, CFB or OFB
mode with any of the above ciphers using the EncryptXXX and
- Encryption/decryption of streams with optional non-interactive
key-exchange with the EncryptStream and DecryptStream classes.
- Encryption/decryption of streams with optional interactive
key-exchange with the CipherStreamClient and CipherStreamServer
- Key 'exchange' by sending a hash of the key to use when decrypting
with the SendHashKeyExClient and SendHashKeyExServer classes.
- Key exchange by sending encrypted keys (including RSA key-exchange)
with the EncryptedKeyExClient and EncryptedKeyExServer classes.
- Diffie-Hellman key exchange with the DHKeyExClient and DHKeyExServer
- Diffie-Hellman key pre-distribution with the DHKeyExNoninter and
- Key exchange and verification with DHEKEKeyExchangeClient and
- MD5 Fingerprinting with the MD5State and Fingerprint classes.
- SHA-1 Fingerprinting with the SHA1State and Fingerprint classes.
- Signatures with those keys that support them.
- Key certificates. (as signatures of KeyRecord objects.)
- Strong continually re-seeding random-number generation with the
- Storing and retrieveing keys, fingerprints and key-rings with the
toString() and Crypto.fromString() methods.
Plans for future versions
- More encryption/signature algorithms, such as IDEA, DSA, etc.
- More protocols, such as Schnorr, proof of knowledge of discrete
logarithm, proof that two discreete logarithms are equal, etc.
- Better key authentication similar to the PGP web-of-trust.
- Key-server class for automatic key exchange.
- General authentication server classes/application.
- More demonstration programs.
- A class to pre-calculate random numbers and store them in a buffer.
- Secret sharing.
- Blind signatures.
- Anything else people are interested in.
These won't be added in any particular order. If there is something you
would like to see in logi.crypto, send me mail and I'll move it forward
in the queue.
Also note that this is the "stable" version and new features are more
likely to appear in the "development" versions. See the web page for details.
Version 1.0.7 (2000.07.07)
- The changes below were made in response to the findings of Jeffrey
Horton and Jennifer Seberry at the University of Wollongong examining
the library on behalf of GET Systems also of Sydney, Australia.
- Made the TestKey class test decryption against the test vectors as
well as encryption.
- Fixed DecryptCBC, DecryptCFB and DecryptOFB so they can receive the
IV in more than one call to decrypt().
- Fixed bug in DecryptCBC which incorrectly handled decryption of less
than a whole multiple of blocks at a time.
- Various bugs and buglets, especially in the stream classes.
- Rewrote TestKey and TestMode and added TestIterate to iterate calls
to those two with all possible key/mode combinations. This unearthed
most of the bugs mentioned above.
- Rewrote the OFB threading code again. It now subclasses the new
Producer thread. It is simpler, safer and much faster.
- Made RandomMD5 more conservative. It now collects 256 bytes of noise
from the spinner when initializing.
- Fixed silly bugs and buglets in RNG's. In particular, they returned
too many random bits from the next() calls.
- Fixed a horrible bug in the RandomFromStream class. It could return
the same bits repeatedly if a read() on the stream didn't read the
full number of bytes. Luckily this is never a problem when used to
read infinite-sized files like "/dev/random" in linux, which is the
only thing it was used for.
Version 1.0.6 (2000.02.08)
- I have been working to apply my library to a large on-line casino
software system in Australia (www.getsystems.com). Most of the
changes below were made in conjunction with that.
- Bugfix: VerifyStream.read() would sometimes return the int -1 when
it should be returning the integer 255
- Bugfix: EncryptOFB and DecryptOFB were not properly destroying their
helper-threads when they were no longer used. The fix included adding
close methods to EncryptStream and DecryptStream and calling them from
appropriate finalizers. Thanks to Jani Raty for pointing this out.
- Added the RSAKey.createKeys(username, password, size) method to create
an RSA key-pair from a username/password pair.
- Added support for signing session keys sent with the EncryptedKeyEx
- Improved the handling of malformed messages in the various protocols.
- Changed the default size of a randomly generated Blowfish key from 128
bits to 448 bits
- Started putting version numbers on the classes I modify. Each class
will have the version number of the last version for which it was
- Renamed RandomSpinner to RandomMD5 and allow it to be seeded from any
Random object. This was an almost complete re-write.
- Overrode the nextBytes() methods in the Random classes to reduce
- Added the is.logi.crypto.random.Seedable interface and made
RandomMD5 implement it. Seedable objects can be fed entropy
from various sources.
- Made the EncryptedKeyExServer constructor take an optional Seedable
parameter of an RNG which should be fed the random padding following
an encrypted session key (and various other data). This is useful if
the "client" has a much better source of entropy than the "server".
(Such as the "client" actually being a server with an HRNG board)
- Removed the obsolete OldRandomSpinner.
- Replaced RandomFromReader with RandomFromStream. It is a low-level,
non-character based thing and should not be using a Reader.
- Added the Crypto.init(...) methods. One of these must be called
before the library is used. It allows you to specify the RNG to use
to avoid instantiating and seeding the RandomMD5 class if you don't
use it. The random number generator is initialized to one that simply
throws an error if it is ever used.
- Updated documentation all over the place.
- Added the plainBlockSize to the EncryptMode and DecryptMode interfaces
and all classes implementing them.
- Added the DecryptMode.drain() method using the above to get rid of
random garbage inserted to fill a plaintext block.
- Various small fixes to low-level threading and io code for strange and
- Made the default hash function changeable. See the
is.logi.crypto.hash.HashState.setDefaultHashFunction method. The default
default is SHA1 as before.
Version 1.0.5 (1999.06.09)
- Bugfix: Fixed a horrendous bug in the Diffie-Hellman/ElGamal code.
The precalculated 1024-bit modulus was not a prime! A typo crept in,
so that the modulus used was two higher than the correct modulus.
This means that the ElGamal code didn't work at all for 1024 bit
moduli, but even worse, the Diffie-Hellman code seemed to work, but
with reduced strength! This is inexcusable on my part.
- Merged the DHKey and ElGamal class. The new class is called DHKey,
while the deprecated ElGamal extends DHKey and does no work on
Version 1.0.4 (1999.04.01)
- Switched to jdk1.2, mostly for the greatly improved javadoc. The
package will still be tested with jdk1.1.x.
- Cleaned up a lot of @see javadoc mismatches thanks to the new
- Fixed bug in how EncryptStream and DecryptStream execute
non-interactive protocols. Thanks for Frank Fowler for leading me
in the right direction.
- Added the ElGamalKey class for encryption and signatures.
- Changed the way fingerprints are calculated for Diffie-Hellman keys.
They now use SHA1 and also hash in the group modulus. I can't see
that the old fingerprint should be weak, but just switching to SHA1
makes it even stronger.
- Fixed DHKey.matches(key).
- Enforce that signatures can only be created with private/secret keys
and verified with public keys in public key algorithms. This meant
adding a "throws KeyException" to SignatureKey.verify(...). Changed
RSAKey accordingly. This may slightly break existing code!
Version 1.0.3 (1999.02.24)
- Cleaned up the protocol interfaces. The KeyExchangeClient and
KeyExchangeServer interfaces are gone as they added no abstraction
over the KeyExClient and KeyExServer interfaces.
- Added the protocol.InterAuthClient and
protocol.InterAuthServer interfaces to define authentication
interactive protocols. Made the DHEKE classes implement these
interfaces (i.e. added to the implements list).
- Added the QRAuthClient and QRAuthServer classes to implement a
simple query-response protocol for simultaneously authenticating
both the client and the server.
Version 1.0.2 (1999.02.13)
- Added the BlowfishKey class for the blowfish cipher. It is about 15
times faster than triple-DES.
- Renamed the packages from is.logi.crypto.* to is.logi.crypto.*
- Change Cryptonite to Crypto wherever it appeared in a class name.
- Bugfix: Crypto.fromHexNibble and Crypto.fromHexString would not work
correctly for upper-case hexadecimal strings.
- Bugfix: The various equals() methods would throw an exception when
called with a null argument. Thanks to Erwin Bolwidt for pointing this
- test.TestKey now checks the code against test-vectors stored in
vector.name where name is tha name of the algorithm. Test-vectors are
included for DES and Blowfish. Needless to say, the package passes the
Version 1.0.1 (1999.01.08)
- Changed the inner workings of Cryptonite.fromString to use static
methods in the classes it generates rather than constructors. This
is more flexible and allows things like:
- Created protected RSAKeyChin subclass of RSAKey. This class stores the
factorization of the modulus and can do faster modular exponentation.
The speed increase is close to twofold. Instances are created for
private keys whenever possible and should be transparent to the user.
- Added support for Signature objects to Cryptonite.fromString().
- Bugfix: RSAKey.equals() always returned true. (This was not a security
risk, but still important)
Version 1.0.0 (1999.01.01)
- Bugfix: Added random padding in RSA signatures. This was a potential
weakness, especially for hash functions with small output sets.
- Gave access to some settings in the RandomSpinner.
- Changed the RandomSpinner to launch a separate thread to do
initialization. This reduces the load-time especially with a large
initial entropy pool.
Version 0.90 (1998.12.20)
- (Version 0.90 was in some places called 0.95. Oops!)
- Created the is.logi.crypto.sign and
is.logi.crypto.random packages and
moved the appropriate classes to them.
- Cleaned up the MD5 code a bit.
- Renamed hash.FingerprintState to hash.HashState
- Rewrote RandomSpinner so it initially generates an entropy pool
from the Spinner class and then hashes it repeatedly to generate
pseudo-random numbers. Each time it is re-hashed additional entropy
is injected into the pool. This is about 8 times faster than the old
RandomSpinner, but still slower than SecureRandom.
- Created random.PureSpinner which is similar to the old RandomSpinner
- Wrote test.TestRandom to test the various random number generators,
including java.util.Random and java.security.SacureRandom.
Version 0.54 (1998.11.25)
- Created several super-interfaces of the KeyEx interfaces, to
define various generic protocols.
- Added the CipherStreamClient.execute(InterProtocolClient) and
CipherStreamServer.execute(InterProtocolServer) methods to execute
arbitrary interactive cryptographic protocols.
- Added the EncryptStream.execute(NoninterProtocolClient) and
DecryptStream.execute(InterProtocolClient) methods to execute
arbitrary interactive cryptographic protocols.
- Split the is.logi.crypto into sever packages:
I hope it is obvious what goes in the sub-packages. The rest stays
- Folded the is.logi.crypto.util package into
- The various CDS methods now search through Cryptonite.cdsPath for
Version 0.53 (1998.11.16)
- Improved the packaging. There is now a jar file in the distribution
and spearate archives for source and documentation.
- I took the time to learn some simple unix shell programming. The
packaging scripts now check that the links and dates in the doc
directory are correct.
- Reviewed all the javadocs.
- Deleted the redundant method
Fingerprint.create(byte buf, String algorithm)
- Changed the default random number generator to use /dev/urandom in
stead of /dev/random. This is a SHA1 based generator (like
java.security.SecureRandom) but injects environment noise as it
- Bugfix: TriDES.equals() always returned false.
- Bugfix: Rewrote SignStream and VerifyStream so that flush() now
Version 0.52 (1998.11.06)
- Bugfix: Renamed the CBF classes to CFB. Ooops...
- Moved all test code for key classes to
- Moved all test code for mode classes to
- Added methods to the CipherStreamClient and CipherStreamServer classes to
return the agreed-upon key. This allows you to agree upon a key and
then use it for multiple connections thereafter.
- Moved all test code for stream and key-exchange classes to
is.hi.logir.cryponite.test.TestCliSer, which also tests multithreaded
- Bugfix: DecryptOFB would thrown a NullPointerException if getKey() was
called before the first decrypt operation.
- Bugfix: CipherStreamClient did not work with non-interactive
- Moved the CDS test to is.hi.logir.cryponite.test.TestCDS
- Moved the SignStram and VerifyStream tests to
Version 0.51 (1998.11.03)
- Bugfix: catch SecurityException when applets try to initialize the
default random-number generator to use /dev/random. Thak you
- Bugfix: Various ClassName(String) constructors were protected which
makes it invisible to the introspector on some jvm's. Thanks again to
- Added the EncryptOFB and DecryptOFB classes for Output Feedback Mode,
with the xor-stream pre-calculated in a separate thread.
- Made the appropriate methods in the EncryptXXX, DecryptXXX and
Stream classes synchronized. (Key classes need no synchronized
methods, for their internal state is immutable!). Thanks to Bartek
Teodorczyk for allerting me to the problem.
Version 0.50 (1998.11.02)
- I now have all the features I want before version 1.0. Thus the jump
in version number. I have written DH-EKE classes, but have not talked
to the patent holders about licensing issues and don't dare distribute
- Renamed the Key class to K and added the Key interface which is now
implemented by all key classes and is the ancestor of SignatureKey
and CipherKey. This is probably the 'correct' way to do this in java.
- Added the DHEKEKeyEx, DHEKEKeyExClient and DHEKEKeyExServer classes
for Encrypted Key Exchenge with the Diffie-Hellman algorithms (DH-EKE).
- Fixed a bug in EncryptCBC which caused garbled output if the first block
to be encrypted was not at index 0 in its array.
- Added the EncryptMode.flush(byte,int,int) method.
- Added the SHA1State object and made it the default hash function
- Rewrote the FingerprintState.create() method, so each sub-class doesn't
need a create method.
- Changed the RSA code to use the public exponent 65537 in stead of 17.
This makes some protocol failures less damaging.
- Added the EncryptCBF and DecryptCBF classes.
- Added the SignStream and VerifyStream classes to sign/verify streams or
to insert/verify fingerprints.
- Rewrote the license without actually changing it.
Version 0.11 (1998.09.29)
- Added the CipherStreamClient and CipherStreamServer classes to apply
interactive key-exchange and subsequent encryption to a pair of
- Added pre-calculated Difie-Hellman (m,g) pairs for 1024 and 2048 bit
- Converted the CipherKey class to an interface and created the
SymmetricKey class which implements some of the abstract methods from
Key. The Key classes are now neater and all the default behaviour in
Key which was not appropriate for asymmetric keys is gone.
- Made all the constructors used by Cryptonite.fromString() protected.
- Renamed some classes. DiffieHellman becomes DH. KeyExchange becomes
KeyEx and Interactive become Inter. The new DHKeyExNoninter class
used to be called DiffieHellmanKeyExchangeNoninteractive which was
- Added the DHKey class.
- Added a constructor to the DHKeyExClient and DHKeyExServer to
initialize with a given DHKey object.
- Added the DHKeyExNoninter class for Diffie-Hellman key
Version 0.10 (1998.09.21)
- Added the Diffie-Hellman key-echange classes (but no classes currently
use the interactive key-exchange interfaces, so they can't be used
- Implemented RSA signatures.
- Renamed the KeyCertificate class to KeyRecord.
- Added methods to allow signing of KeyRecords. This would be a key
certificate, but I'm still thinkng about just how to implement this
- Added the EncryptedKeyExchange classes, which can be used for RSA
- Enabled EncryptStream/DecryptStream to work without any key-exchange.
- Optimized the f function in the DESKey class. It is now 2.5 times
faster (on the non-jit blackdown jdk1.1.6-2 jvm for linux).
- Added the TriDESKey class. It is actually much faster than the old DESKey
- Split the SendHashKeyExchange class into SendHashKeyExchangeClient and
SendHashKeyExchangeServer classes, which makes a much cleaner design
and catches more programmer errors (mine too).
- Removed the EncryptMode.empty() and EncryptMode.bytesEncrypted() methods.
Yell at me if you think this is a bad idea, but I just can't see how they
- Added the EncryptCBC and DecryptCBC classes.
- Added the RandomFromReader class. Cryptonite will by default try to
use the /dev/random device for random numbers, but falls back to the
Version 0.09 (1998.09.16)
- Major re-write. I've simplified most of the code and made it more
general. This version is a few months later than I expected, since
I inadvertently aquired a life. This should no longer be a problem.
- The name of the package changed from IS.hi.logir.cryptonite to
is.hi.logir.cryptonite, which is contrary to the guidelines set down
by Sun, but doesn't cause as many problems on Windows 95 machines
(and probably Windows 98, although I wouldn't know).
- Renamed the RsaKey class to RSAKey.
- Got rid of the damned kludge of a Data class. Let's hope the generation
scavenging garbage collection that Sun is going to use is as good as
they say. (My programing languages professor liked it...)
- Rewrote most of the fingerprint code. To quickly create an MD5
fignerprint use FingerprintState.createFingerprint(..., "MD5")
- Added the EncryptMode/DecryptMode classs to support various block
cipher modes, such as ECB and CBC.
- Added the EncryptECB and DecryptECB classes.
- Moved all encryption/decryption methods from the Key class to a new
sub-class, CipherKey, and made it the superclass of all keys that are
used for encryption/decryption (and not only key-exchange or
- Simplified the CipherKey class (which used to be the Key class) so
that it only encrypts and decrypts single blocks of data. The logic
to manage larger buffers has been moved to the EncryptMode classes.
- Added the SignatureKey interface for keys that can be used to
create and check signatures.
- Relaxed the license a little. You can now use old versions of
Cryptonite indefinately. (But must pay for pre-release versions
once the final version is out, unless you are using the GPL)
- Created the Cryptonite class and made it the superclass of all the
other classes. It includes various utility functions and the default
random number generator.
- Changed all toString() methods so the strings they return completely
define the object.
- Added the Cryptonite.fromString() method to recreate objects from the
strings returned by toString(). Try fromString("DESKey(?)")
to create random DES keys.
- Added the KeySource interace.
- Threw out the overly complicated KeyRing class and added a nice and
simple KeyRing class which implements the KeySource interface.
- Added various key-exchange interfaces with long and complicated
- Added the SendHashKeyExchange class which exchanges keys by sending
the hash of the key and expecting the other side to look up the key
in its default KeySource.
- Totally re-wrote the EncryptStream and DecryptStream objects. They
now use the non-interactive key-exchange classes and the
encrypt/decrypt-mode classes to do all the work. This is much cleaner
and more versatile. (The EncryptStream code is very elegant now,
especially compared to the earlier mess.)
- Probably other things that I've long since forgotten.
Version 0.08 (97.12.21)
- Added the TeaKey class, which implements the TEA cipher. It was
written by a third party who would not be known, but heavily modified
- Changed the Streams and Key classes so the stream doesn't have to
keep track of the size of plain-text blocks, but only of the
cipher-text blocks. This made the Key.getEncryptedSize() method
- Added the Data class to handle byte buffers. It can resize the buffer
at the users request and return fingerprints.
- Changed DecryptStream so it re-uses buffer arrays when possible and
gives the garbage-collector less to do. This is done by using the Data
- Added the Key.blockSize() and changed EncryptStream so it uses a buffer
size that is a multiple of Key.blockSize(), which is more space
- Modified EncryptStream so that it always writes a key-identifier block.
- Added support for session keys to EncryptStream and DecryptStream.
I tested it using a 32-iteration Tea session key with a 512-bit RSA
key to encrypt and decrypt a 200KB text file. Encryption actually
slowed down by 25%, but decryption speed increased by some small 2438%.
- Converted the readme file to HTML.
Version 0.07 (97.11.07)
- Fixed a bug in RsaKey that added garbage after the data when encrypting
- Fixed a bug in DecryptStream that would return negative integers when
reading a byte larger than 127 in read()
- Created a new package, IS.logi.crypto.util, to hold various
utility programs that use Cryptonite.
- Added a simple MD5 hash generation utility to the utility package.
Version 0.06 (97.11.06)
- Moved the creation of FingerprintState objects by name from the
Fingerprint class to the FingerprintState class.
- Got MD5State to work (by stealing time away from my studies)
Version 0.05 (97.10.12)
- Restructured the class hierarchy to allow support for other fingerprint
algorithms by subclassing Fingerprint.
- Added methods to the Key class so that its subclasses can register
themselves whereafter instances can be created by using the algorithm
- Cleaned up the DecryptStream.getBlock() method. I even understand it
- Moved the test programs into their own package called
IS.logi.crypto.test. This uncovered a horrendous bug: All
the constructors in EncryptStream were invisible from outside the
class! No wonder no-one was using the damned thing :-)
Version 0.04 (97.09.07)
- Restructured the class hierarchy to allow support for other encryption
algorithms. This included moving key-generation back into the key
class, renaming Key to RsaKey and creating an abstract Key class.
- Re-created the KeyPair class, but only as a holder for a
- Defined the Fingerprint method for MD5 fingerprints, but used a weak
- Implemented the Signature class and the KeyRing.isValid(Key) method.
Version 0.03 (97.08.26)
- Added the EncryptStream, DescryptStream and KeyRing classes.
- Removed the KeyPair class and moved key-generation into the
Version 0.02 (97.08.20)
- Got encryption and decryption of large blocks of data working.
- Moved key generation into a new KeyPair class.
Version 0.01 (97.08.17)
- Created the is.hi.logir.cryptonite package.
- Created the Key class (only for RSA).
- Got key generation and encrption/decryption of data blocks
with fewer bits than the key working.
Version 0.00 (97.04.??)
- Passed the Abstract Algebra I test and started thinking about
implementing the RSA algorithm.
- I am considering creating a "weak" version of logi.crypto that can only
create and use small key sizes. This would probably only involve
changing the Key classes and would make the export of software using
logi.crypto legal from countries which disallow the export of strong
This weak version would be built so that it could be replaced by the
user with the strong version. If you are interested in such a version
of logi.crypto, contact me.
If you are interested in a weak version of logi.crypto that can't be
replaced with a stronger version, then I don't want to know.
| Payment ]
[ Logi Ragnarsson
| Send Mail ]
[ General info
| Status & Plans
| Commercial License
| Class docs ]