[jsword-svn] common/java/core/org/crosswire/common/crypt s
jswordcvs at crosswire.org
jswordcvs at crosswire.org
Sun Mar 6 13:22:01 MST 2005
Update of /cvs/jsword/common/java/core/org/crosswire/common/crypt
In directory www.crosswire.org:/tmp/cvs-serv26740/java/core/org/crosswire/common/crypt
Modified Files:
Sapphire.java
Log Message:
Changes to satisfy CheckStyle
Index: Sapphire.java
===================================================================
RCS file: /cvs/jsword/common/java/core/org/crosswire/common/crypt/Sapphire.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Sapphire.java 4 Mar 2005 04:04:38 -0000 1.1
--- Sapphire.java 6 Mar 2005 20:21:59 -0000 1.2
***************
*** 6,10 ****
* originally provided for it. It has been converted to JavaDoc and the
* C++ fragment has been removed.
! *
* <h1>THE SAPPHIRE II STREAM CIPHER</h1>
*
--- 6,10 ----
* originally provided for it. It has been converted to JavaDoc and the
* C++ fragment has been removed.
! *
* <h1>THE SAPPHIRE II STREAM CIPHER</h1>
*
***************
*** 42,46 ****
*
* <h2>HISTORY AND RELATED CIPHERS</h2>
! *
* <p>The Sapphire Stream Cipher is very similar to a cipher I started work on in
* November 1993. It is also similar in some respects to the alledged RC-4 that
--- 42,46 ----
*
* <h2>HISTORY AND RELATED CIPHERS</h2>
! *
* <p>The Sapphire Stream Cipher is very similar to a cipher I started work on in
* November 1993. It is also similar in some respects to the alledged RC-4 that
***************
*** 58,70 ****
* key of 128 bits). A variant of the Sapphire Stream Cipher is also used in
* the shareware program Atbash, which has no weakened exportable version.</p>
! *
* <p>The Sapphire II Stream Cipher is a modification of the Sapphire Stream Cipher
* designed to be much more resistant to adaptive chosen plaintext attacks (with
* reorigination of the cipher allowed). The Sapphire II Stream Cipher is used
* in an encryption utility called ATBASH2.</p>
! *
! *
* <h2>OVERVIEW</h2>
! *
* <p>The Sapphire Stream Cipher is based on a state machine. The state consists
* of 5 index values and a permutation vector. The permutation vector is simply
--- 58,70 ----
* key of 128 bits). A variant of the Sapphire Stream Cipher is also used in
* the shareware program Atbash, which has no weakened exportable version.</p>
! *
* <p>The Sapphire II Stream Cipher is a modification of the Sapphire Stream Cipher
* designed to be much more resistant to adaptive chosen plaintext attacks (with
* reorigination of the cipher allowed). The Sapphire II Stream Cipher is used
* in an encryption utility called ATBASH2.</p>
! *
! *
* <h2>OVERVIEW</h2>
! *
* <p>The Sapphire Stream Cipher is based on a state machine. The state consists
* of 5 index values and a permutation vector. The permutation vector is simply
***************
*** 85,95 ****
* locations 1, 3, 5, 7, and a key dependent value (rsum) left over from the
* shuffling of the permutation vector (cards array).</p>
! *
! *
* <h2>KEY SETUP</h2>
! *
* <p>Key setup (illustrated by the function initialize(), below) consists of three
* parts:</p>
! * <ol>
* <li>Initialize the index variables.</li>
* <li>Set the permutation vector to a known state (a simple counting
--- 85,95 ----
* locations 1, 3, 5, 7, and a key dependent value (rsum) left over from the
* shuffling of the permutation vector (cards array).</p>
! *
! *
* <h2>KEY SETUP</h2>
! *
* <p>Key setup (illustrated by the function initialize(), below) consists of three
* parts:</p>
! * <ol>
* <li>Initialize the index variables.</li>
* <li>Set the permutation vector to a known state (a simple counting
***************
*** 98,102 ****
* permutation vector with an element indexed somewhere from 0
* to the current index (chosen by the function keyrand()).</li>
! * </ol>
* <p>The keyrand() function returns a value between 0 and some maximum number
* based on the user's key, the current state of the permutation vector, and an
--- 98,102 ----
* permutation vector with an element indexed somewhere from 0
* to the current index (chosen by the function keyrand()).</li>
! * </ol>
* <p>The keyrand() function returns a value between 0 and some maximum number
* based on the user's key, the current state of the permutation vector, and an
***************
*** 104,111 ****
* keyrand(), too, so that a key like "abcd" will not result in the same
* permutation as a key like "abcdabcd".</p>
! *
! *
* <h2>ENCRYPTION</h2>
! *
* <p>Each encryption involves updating the index values, moving (up to) 4 bytes
* around in the permutation vector, selecting an output byte, and adding the
--- 104,111 ----
* keyrand(), too, so that a key like "abcd" will not result in the same
* permutation as a key like "abcdabcd".</p>
! *
! *
* <h2>ENCRYPTION</h2>
! *
* <p>Each encryption involves updating the index values, moving (up to) 4 bytes
* around in the permutation vector, selecting an output byte, and adding the
***************
*** 118,162 ****
* byte. The last plain text and the last cipher text bytes are also kept as
* index variables. See the function called encrypt(), below for details.</p>
! *
! *
* <h2>PSUEDORANDOM BYTE GENERATION</h2>
! *
* <p>If you want to generate random numbers without encrypting any particular
* ciphertext, simply encrypt 0. There is still plenty of complexity left in
* the system to ensure unpredictability (if the key is not known) of the output
* stream when this simplification is made.</p>
! *
! *
* <h2>DECRYPTION</h2>
! *
* <p>Decryption is the same as encryption, except for the obvious swapping of the
* assignments to last_plain and last_cipher and the return value. See the
* function decrypt(), below.</p>
! *
! *
* <h2>C++ SOURCE CODE FRAGMENT</h2>
! *
* <p>The original implimentation of this cipher was in Object Oriented Pascal, but
* C++ is available for more platforms.</p>
! *
* <h2>GENERATION OF CRYPTOGRAPHIC CHECK VALUES (HASH VALUES)</h2>
! *
* <p>For a fast way to generate a cryptographic check value (also called a hash or
* message integrity check value) of a message of arbitrary length:</p>
! * <ol>
* <li>Initialize either with a key (for a keyed hash value) or call hash_init
* with no key (for a public hash value).</li>
! *
* <li>Encrypt all of the bytes of the message or file to be hashed. The
* results of the encryption need not be kept for the hash generation
* process. (Optionally decrypt encrypted text, here).</li>
! *
* <li>Call hash_final, which will further "stir" the permutation vector by
* encrypting the values from 255 down to 0, then report the results of
* encrypting 20 zeroes.</li>
! * </ol>
! *
* <h2>SECURITY ANALYSIS</h2>
! *
* <p>There are several security issues to be considered. Some are easier to
* analyze than others. The following includes more "hand waving" than
--- 118,162 ----
* byte. The last plain text and the last cipher text bytes are also kept as
* index variables. See the function called encrypt(), below for details.</p>
! *
! *
* <h2>PSUEDORANDOM BYTE GENERATION</h2>
! *
* <p>If you want to generate random numbers without encrypting any particular
* ciphertext, simply encrypt 0. There is still plenty of complexity left in
* the system to ensure unpredictability (if the key is not known) of the output
* stream when this simplification is made.</p>
! *
! *
* <h2>DECRYPTION</h2>
! *
* <p>Decryption is the same as encryption, except for the obvious swapping of the
* assignments to last_plain and last_cipher and the return value. See the
* function decrypt(), below.</p>
! *
! *
* <h2>C++ SOURCE CODE FRAGMENT</h2>
! *
* <p>The original implimentation of this cipher was in Object Oriented Pascal, but
* C++ is available for more platforms.</p>
! *
* <h2>GENERATION OF CRYPTOGRAPHIC CHECK VALUES (HASH VALUES)</h2>
! *
* <p>For a fast way to generate a cryptographic check value (also called a hash or
* message integrity check value) of a message of arbitrary length:</p>
! * <ol>
* <li>Initialize either with a key (for a keyed hash value) or call hash_init
* with no key (for a public hash value).</li>
! *
* <li>Encrypt all of the bytes of the message or file to be hashed. The
* results of the encryption need not be kept for the hash generation
* process. (Optionally decrypt encrypted text, here).</li>
! *
* <li>Call hash_final, which will further "stir" the permutation vector by
* encrypting the values from 255 down to 0, then report the results of
* encrypting 20 zeroes.</li>
! * </ol>
! *
* <h2>SECURITY ANALYSIS</h2>
! *
* <p>There are several security issues to be considered. Some are easier to
* analyze than others. The following includes more "hand waving" than
***************
*** 164,171 ****
* mathematician. The reader is invited to improve upon or refute the
* following, as appropriate.</p>
! *
! *
* <h2>KEY LENGTH</h2>
! *
* <p>There are really two kinds of user keys to consider: (1) random binary keys,
* and (2) pass phrases. Analysis of random binary keys is fairly straight
--- 164,171 ----
* mathematician. The reader is invited to improve upon or refute the
* following, as appropriate.</p>
! *
! *
* <h2>KEY LENGTH</h2>
! *
* <p>There are really two kinds of user keys to consider: (1) random binary keys,
* and (2) pass phrases. Analysis of random binary keys is fairly straight
***************
*** 174,178 ****
* phrase. The length limit of the key (255 bytes) is adequate to allow a pass
* phrase with enough entropy to be considered strong.</p>
! *
* <p>To be real generous to a cryptanalyst, assume dedicated Sapphire Stream
* Cipher cracking hardware. The constant portion of the key scheduling can be
--- 174,178 ----
* phrase. The length limit of the key (255 bytes) is adequate to allow a pass
* phrase with enough entropy to be considered strong.</p>
! *
* <p>To be real generous to a cryptanalyst, assume dedicated Sapphire Stream
* Cipher cracking hardware. The constant portion of the key scheduling can be
***************
*** 186,190 ****
* rounding to two significant digits, the following key length versus cracking
* time estimates result:</p>
! *
* <pre>
* Key length, bits Time to crack
--- 186,190 ----
* rounding to two significant digits, the following key length versus cracking
* time estimates result:</p>
! *
* <pre>
* Key length, bits Time to crack
***************
*** 197,219 ****
* 80 19 billion years (kind of like Skipjack's key)
* 128 5.4E24 years (good enough for the clinically paranoid)
! * </pre>
*
* <p>Naturally, the above estimates can vary by several orders of magnitude based
* on what you assume for attacker's hardware, budget, and motivation.</p>
! *
* <p>In the range listed above, the probability of spare keys (two keys resulting
* in the same initial permutation vector) is small enough to ignore. The proof
* is left to the reader.</p>
! *
! *
* <h2>INTERNAL STATE SPACE</h2>
! *
* <p>For a stream cipher, internal state space should be at least as big as the
* number of possible keys to be considered strong. The state associated with
* the permutation vector alone (256!) constitutes overkill.</p>
! *
! *
* <h2>PREDICTABILITY OF THE STATE</h2>
! *
* <p>If you have a history of stream output from initialization (or equivalently,
* previous known plaintext and ciphertext), then rotor, last_plain, and
--- 197,219 ----
* 80 19 billion years (kind of like Skipjack's key)
* 128 5.4E24 years (good enough for the clinically paranoid)
! * </pre>
*
* <p>Naturally, the above estimates can vary by several orders of magnitude based
* on what you assume for attacker's hardware, budget, and motivation.</p>
! *
* <p>In the range listed above, the probability of spare keys (two keys resulting
* in the same initial permutation vector) is small enough to ignore. The proof
* is left to the reader.</p>
! *
! *
* <h2>INTERNAL STATE SPACE</h2>
! *
* <p>For a stream cipher, internal state space should be at least as big as the
* number of possible keys to be considered strong. The state associated with
* the permutation vector alone (256!) constitutes overkill.</p>
! *
! *
* <h2>PREDICTABILITY OF THE STATE</h2>
! *
* <p>If you have a history of stream output from initialization (or equivalently,
* previous known plaintext and ciphertext), then rotor, last_plain, and
***************
*** 227,234 ****
* could be used to achieve security, here, if it were not for the hash
* requirements.</p>
! *
! *
* <h2>CRYPTOGRAPHIC CHECK VALUE</h2>
! *
* <p>The change in state altered with each byte encrypted contributes to an
* avalanche of generated check values that is radically different after a
--- 227,234 ----
* could be used to achieve security, here, if it were not for the hash
* requirements.</p>
! *
! *
* <h2>CRYPTOGRAPHIC CHECK VALUE</h2>
! *
* <p>The change in state altered with each byte encrypted contributes to an
* avalanche of generated check values that is radically different after a
***************
*** 239,243 ****
* generated (about half of the bits change). This is an essential feature of a
* cryptographic check value.</p>
! *
* <p>Another good property of a cryptographic check value is that it is too hard
* to compute a message that results in a certain check value. In this case, we
--- 239,243 ----
* generated (about half of the bits change). This is an essential feature of a
* cryptographic check value.</p>
! *
* <p>Another good property of a cryptographic check value is that it is too hard
* to compute a message that results in a certain check value. In this case, we
***************
*** 249,253 ****
* so-called "birthday" attack that is to cryptographic hash functions what
* brute force is to key search.</p>
! *
* <p>To generate a sequence that restores the state of the cipher to what it was
* before the alteration probably requires at least 256 bytes, since the index
--- 249,253 ----
* so-called "birthday" attack that is to cryptographic hash functions what
* brute force is to key search.</p>
! *
* <p>To generate a sequence that restores the state of the cipher to what it was
* before the alteration probably requires at least 256 bytes, since the index
***************
*** 262,266 ****
* <m.p.johnson@ieee.org> if you
* find one.</p>
! *
* <p>The "birthday" attack just uses the birthday paradox to find a message that
* has the same check value. With a 20 byte check value, you would have to find
--- 262,266 ----
* <m.p.johnson@ieee.org> if you
* find one.</p>
! *
* <p>The "birthday" attack just uses the birthday paradox to find a message that
* has the same check value. With a 20 byte check value, you would have to find
***************
*** 271,278 ****
* algorithm. Someone who likes 16 byte keys might prefer 32 byte check values
* for similar stringth.</p>
! *
! *
* <h2>ADAPTIVE CHOSEN PLAIN TEXT ATTACKS</h2>
! *
* <p>Let us give the attacker a keyed black box that accepts any input and
* provides the corresponding output. Let us also provide a signal to the black
--- 271,278 ----
* algorithm. Someone who likes 16 byte keys might prefer 32 byte check values
* for similar stringth.</p>
! *
! *
* <h2>ADAPTIVE CHOSEN PLAIN TEXT ATTACKS</h2>
! *
* <p>Let us give the attacker a keyed black box that accepts any input and
* provides the corresponding output. Let us also provide a signal to the black
***************
*** 281,285 ****
* the black box, identical in all respects except that the key is not provided
* and it is not locked, so the array can be manipulated directly.</p>
! *
* <p>Since each byte encrypted only modifies at most 5 of the 256 bytes in the
* permutation vector, and it is possible to find different sequences of two
--- 281,285 ----
* the black box, identical in all respects except that the key is not provided
* and it is not locked, so the array can be manipulated directly.</p>
! *
* <p>Since each byte encrypted only modifies at most 5 of the 256 bytes in the
* permutation vector, and it is possible to find different sequences of two
***************
*** 300,307 ****
* Stream Cipher, I have come up with the Sapphire II Stream Cipher. Thanks
* again to Bryan for his valuable help.</p>
! *
* <p>Bryan Olson's "differential" attack of the original Sapphire Stream Cipher
* relies on both of these facts:</p>
! *
* <ol>
* <li>By continual reorigination of a black box containing a keyed version of
--- 300,307 ----
* Stream Cipher, I have come up with the Sapphire II Stream Cipher. Thanks
* again to Bryan for his valuable help.</p>
! *
* <p>Bryan Olson's "differential" attack of the original Sapphire Stream Cipher
* relies on both of these facts:</p>
! *
* <ol>
* <li>By continual reorigination of a black box containing a keyed version of
***************
*** 311,315 ****
* suffixes so obtained will not contain the values of the permutation vector
* bytes that <i>differ</i> because of the different initial bytes encrypted.</li>
! *
* <li>Because the five index values are initialized to constants that are
* known by the attacker, most of the locations of the "missing" bytes noted in
--- 311,315 ----
* suffixes so obtained will not contain the values of the permutation vector
* bytes that <i>differ</i> because of the different initial bytes encrypted.</li>
! *
* <li>Because the five index values are initialized to constants that are
* known by the attacker, most of the locations of the "missing" bytes noted in
***************
*** 317,321 ****
* the ratchet index variable for encryptions after the first byte).</li>
* </ol>
! *
* <p>I have not yet figured out if Bryan's attack on the original Sapphire Stream
* Cipher had complexity of more or less than the design strength goal of 2^64
--- 317,321 ----
* the ratchet index variable for encryptions after the first byte).</li>
* </ol>
! *
* <p>I have not yet figured out if Bryan's attack on the original Sapphire Stream
* Cipher had complexity of more or less than the design strength goal of 2^64
***************
*** 325,329 ****
* accurately, and I have limited time for that). Fortunately, there is a way
* to frustrate this type of attack without fully developing it.</p>
! *
* <p>Denial of condition 1 above by increased alteration of the state variables is
* too costly, at least using the methods I tried. For example, doubling the
--- 325,329 ----
* accurately, and I have limited time for that). Fortunately, there is a way
* to frustrate this type of attack without fully developing it.</p>
! *
* <p>Denial of condition 1 above by increased alteration of the state variables is
* too costly, at least using the methods I tried. For example, doubling the
***************
*** 335,339 ****
* That means that all possible output values can occur in the differential
* sequences of item 1, above.</p>
! *
* <p>Denial of condition 2 above, is simpler. By making the initial values of the
* five index variables dependent on the key, Bryan's differential attack is
--- 335,339 ----
* That means that all possible output values can occur in the differential
* sequences of item 1, above.</p>
! *
* <p>Denial of condition 2 above, is simpler. By making the initial values of the
* five index variables dependent on the key, Bryan's differential attack is
***************
*** 341,355 ****
* vector were different between data sets, and exhaustive search is too
* expensive.</p>
! *
! *
* <h2>OTHER HOLES</h2>
! *
* <p>Are there any? Take you best shot and let me know if you see any. I offer
* no challenge text with this algorithm, but you are free to use it without
* royalties to me if it is any good.</p>
! *
! *
* <h2>CURRENT STATUS</h2>
! *
* <p>This is a new (to the public) cipher, and an even newer approach to
* cryptographic hash generation. Take your best shot at it, and please let me
--- 341,355 ----
* vector were different between data sets, and exhaustive search is too
* expensive.</p>
! *
! *
* <h2>OTHER HOLES</h2>
! *
* <p>Are there any? Take you best shot and let me know if you see any. I offer
* no challenge text with this algorithm, but you are free to use it without
* royalties to me if it is any good.</p>
! *
! *
* <h2>CURRENT STATUS</h2>
! *
* <p>This is a new (to the public) cipher, and an even newer approach to
* cryptographic hash generation. Take your best shot at it, and please let me
***************
*** 357,364 ****
* caution, but it still looks like it fills a need for reasonably strong
* cryptography with limited resources.</p>
! *
! *
* <h2>LEGAL STUFF</h2>
! *
* <p>The intention of this document is to share some research results on an
* informal basis. You may freely use the algorithm and code listed above as
--- 357,364 ----
* caution, but it still looks like it fills a need for reasonably strong
* cryptography with limited resources.</p>
! *
! *
* <h2>LEGAL STUFF</h2>
! *
* <p>The intention of this document is to share some research results on an
* informal basis. You may freely use the algorithm and code listed above as
***************
*** 369,373 ****
* Constitutionally protected publication, and not a munition, but don't blame
* me if it explodes or has toxic side effects.</p>
! *
* <pre>
* ___________________________________________________________
--- 369,373 ----
* Constitutionally protected publication, and not a munition, but don't blame
* me if it explodes or has toxic side effects.</p>
! *
* <pre>
* ___________________________________________________________
***************
*** 384,388 ****
* Regarding this port to Java and not the original code, the following license
* applies:
! *
* <p><table border='1' cellPadding='3' cellSpacing='0'>
* <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
--- 384,388 ----
* Regarding this port to Java and not the original code, the following license
* applies:
! *
* <p><table border='1' cellPadding='3' cellSpacing='0'>
* <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
***************
*** 427,434 ****
else
{
! hash_init();
}
}
!
/**
* Decipher a single byte, presumably the next.
--- 427,434 ----
else
{
! hashInit();
}
}
!
/**
* Decipher a single byte, presumably the next.
***************
*** 447,451 ****
// Convert from a byte to an int, but prevent sign extension.
// So -16 becomes 240
! int bVal = (b & 0xFF);
ratchet += cards[rotor++];
// Keep ratchet and rotor in the range of 0-255
--- 447,451 ----
// Convert from a byte to an int, but prevent sign extension.
// So -16 becomes 240
! int bVal = b & 0xFF;
ratchet += cards[rotor++];
// Keep ratchet and rotor in the range of 0-255
***************
*** 464,469 ****
// Output one byte from the state in such a way as to make it
// very hard to figure out which one you are looking at.
! lastPlain = (bVal ^ cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
! cards[cards[(cards[lastPlain] + cards[lastCipher] + cards[avalanche]) & 0xFF]]);
lastCipher = bVal;
--- 464,469 ----
// Output one byte from the state in such a way as to make it
// very hard to figure out which one you are looking at.
! lastPlain = bVal ^ cards[(cards[ratchet] + cards[rotor]) & 0xFF]
! ^ cards[cards[(cards[lastPlain] + cards[lastCipher] + cards[avalanche]) & 0xFF]];
lastCipher = bVal;
***************
*** 491,503 ****
* @param hash
*/
! public void hash_final(byte[] hash) // Destination
{
for (int i = 255; i >= 0; i--)
{
! cipher((byte)i);
}
for (int i = 0; i < hash.length; i++)
{
! hash[i] = cipher((byte)0);
}
}
--- 491,503 ----
* @param hash
*/
! public void hashFinal(byte[] hash) // Destination
{
for (int i = 255; i >= 0; i--)
{
! cipher((byte) i);
}
for (int i = 0; i < hash.length; i++)
{
! hash[i] = cipher((byte) 0);
}
}
***************
*** 519,528 ****
{
! // Start with cards all in order, one of each.
for (int i = 0; i < 256; i++)
{
cards[i] = i;
}
!
// Swap the card at each position with some other card.
int swaptemp;
--- 519,528 ----
{
! // Start with cards all in order, one of each.
for (int i = 0; i < 256; i++)
{
cards[i] = i;
}
!
// Swap the card at each position with some other card.
int swaptemp;
***************
*** 537,541 ****
cards[toswap] = swaptemp;
}
!
// Initialize the indices and data dependencies.
// Indices are set to different values instead of all 0
--- 537,541 ----
cards[toswap] = swaptemp;
}
!
// Initialize the indices and data dependencies.
// Indices are set to different values instead of all 0
***************
*** 557,561 ****
* Initialize non-keyed hash computation.
*/
! private void hash_init()
{
--- 557,561 ----
* Initialize non-keyed hash computation.
*/
! private void hashInit()
{
***************
*** 579,583 ****
{
int u; // Value from 0 to limit to return.
!
if (limit == 0)
{
--- 579,583 ----
{
int u; // Value from 0 to limit to return.
!
if (limit == 0)
{
***************
*** 586,597 ****
int retry_limiter = 0; // No infinite loops allowed.
!
! // Fill mask with enough bits to cover the desired range.
! int mask = 1;
while (mask < limit)
{
mask = (mask << 1) + 1;
}
!
do
{
--- 586,597 ----
int retry_limiter = 0; // No infinite loops allowed.
!
! // Fill mask with enough bits to cover the desired range.
! int mask = 1;
while (mask < limit)
{
mask = (mask << 1) + 1;
}
!
do
{
***************
*** 608,612 ****
}
! u = (mask & rsum);
if (++retry_limiter > 11)
--- 608,612 ----
}
! u = mask & rsum;
if (++retry_limiter > 11)
More information about the jsword-svn
mailing list